Почему компилятор выбирает неправильную перегрузку в этом случае?

#c

Вопрос:

Рассмотрим этот довольно простой код (godbolt):

 #include <cstddef>
#include <string>

using namespace std;

string f(char const* fmt, ...);
size_t f(char* buf, size_t sz, char const* fmt, ...);

void bar()
{
    f("%c%s", 'A', "AAA");
}
 

Предполагается , что тип первого параметра должен быть char const[5] , а это означает, что вторая перегрузка даже не должна рассматриваться. И все же компилятор (хотя он немного жалуется) выбирает его (как вы могли видеть в сгенерированной сборке).

Кто-нибудь может точно объяснить, что здесь происходит?

Примечания:

  • MSVC не удается скомпилировать это
  • моя версия GCC 8.3.1-3 тоже не смогла ее скомпилировать

Комментарии:

1. @AdrianMole — VS изменил свой шаблон проекта по умолчанию в последние годы. /permissive- устанавливается по умолчанию. Однако в командной строке это не так.

2. компиляция clang; ошибка gcc; компиляция mcvc — live — godbolt.org/z/6M1axYza5

3. Ошибка GCC (эта, я полагаю gcc.gnu.org/bugzilla/show_bug.cgi?id=95596 ).

4. Вы можете получить временную работу по обходу f( "%c%s", 'A', "AAA");

5. Также стоит отметить, что gcc выбирает правильную перегрузку с -pedantic помощью флага