Инвертированные аргументы в scanf ()

Я (быстро) писал некоторый код и случайно перевернул аргументы вscanf():

char i[] = "ABC1\t";
scanf(i, "%s");

Компилирование сgcc -Werror -Wall -Wextra ни на что не жалуется. Очевидно, этот код не работает, но почему gcc не сообщил мне, что я перевернул аргументы? Разве это не может обнаружить этоi не является форматной строкой, или что второй аргумент не был типом для хранения?

РЕДАКТИРОВАТЬ
Спасибо за понимание всем, похоже, я нашел ответ, был поворот на-Wformat флаг, который делает это "ловимым" (опубликовал его ниже для справки)

Ответы на вопрос(3)

поэтому первый аргумент удовлетворяется. Вторичные аргументы оцениваются во время выполнения (если я помню), поэтому они даже не рассматриваются здесь компилятором. С точки зрения компилятора, это прекрасный вызов функции с учетом ее прототипа.

int scanf(const char *format, ...);

Кроме того, компилятор никогда не проверяет, пытаетесь ли вы записать в недопустимые места. Самое замечательное (или ужасное) свойство C заключается в том, что он позволяет вам делать более или менее то, что вы хотите, даже если то, что вы хотите, является плохой идеей.

Правда, что

 Shahbaz25 окт. 2012 г., 15:30
 сам по себе принимает их, но в glibc, скомпилированном с gcc, scanf имеетscanf который сообщает компилятору, что параметры должны быть правильными, даже если это не применяется объявлением__attribute__((format(scanf, 1, 2)))Инвертированные аргументы в scanf ()scanf.

 обычно был преобразован в

int scanf ( const char * format, ... );

iвсе остальные параметры просто "многоточие" и не могут быть проверены во время компиляции.const char*Заголовки, используемые GCC, обычно имеют первый параметр, помеченный как строку формата, и затем он может гарантировать, что правильные типы передаются оставшимся параметрам при условии

 anishsane25 окт. 2012 г., 14:53
Дело в том, что glibc определяет
 Lyth25 окт. 2012 г., 14:43
 или буквальный.const char*Вероятно, он не проверяет между 'char * fmt' и 'const char * fmt'. Кто-нибудь может сказать, если второй аргумент ("ABC \ t") будет char * или const char *?
 anishsane25 окт. 2012 г., 14:47
РЕДАКТИРОВАТЬ: Вероятно, он не проверяет между 'char * fmt' и 'const char * fmt'. Кто-нибудь может сказать, если второй аргумент ("ABC \ t") будет char * или const char *? Кстати, 2-й аргумент будет полностью игнорироваться, потому что строка формата не содержит символов формата%.
 Shahbaz25 окт. 2012 г., 15:32
 с участиемscanf которая является опцией gcc, чтобы сказать ей проверить аргументы и выдать предупреждение. В противном случае очевидно, что в вопросе нет ошибки несоответствия типов.__attribute__((format(scanf, 1, 2)))Ручная запись для scanf (man scanf) дает прототип:
 Will25 окт. 2012 г., 14:39
 предоставлен. Я считаю, что это часть-Wformat@Will Но с другой стороны - неконстантный символ * был передан как строка формата (что само по себе допустимо), и поэтому компилятор не принудительно проверял параметры. Это могло бы быть сделано, если строка формата была-Wall.
Решение Вопроса

-Wformat=2 Флаг поймал это.

Размещение информации для справки других:

Вотсписок найденных мной флагов

-Wformat Check calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified...

Я предполагал-Wall было-Wformat в нем, что он делает, но действительно важная часть о том, что я только что нашел:

-Wformat is included in -Wall. For more control over some aspects of format checking, the options -Wformat-y2k, -Wno-format-extra-args, -Wno-format-zero-length, -Wformat-nonliteral, -Wformat-security, and -Wformat=2 are available, but are not included in -Wall.

 Omkant25 окт. 2012 г., 14:50
Да, +1 я тоже искал. \ Я полагаю, что это не должно.

Ваш ответ на вопрос