2016-01-30 4 views
11

Предположим, я забыл закрыть прямоугольную скобку ] сканера. Что будет тогда? Вызывает ли оно Непоследовательное поведение?Что произойдет, если я забуду закрыть сканирование?

Пример:

char str[] = "Hello! One Two Three"; 
char s1[50] = {0}, s2[50] = {0}; 
sscanf(str, "%s %[^h", s1, s2); /* UB? */ 
printf("s1='%s' s2='%s'\n", s1, s2); 

Я получаю предупреждение от GCC при компиляции:

source_file.c: In function ‘main’: 
source_file.c:11:5: warning: no closing ‘]’ for ‘%[’ format [-Wformat=] 
    sscanf(str, "%s %[^h", s1, s2); /* UB? */ 

и выход в

s1='Hello!' s2='' 

Я также заметил, что sscanf возвращает 1 Но что именно здесь происходит?

Я проверил стандарт C11, но не нашел никакой информации, связанной с этим.

ответ

5

Отлично! Вы должны подать отчет о дефектах для C11!

Вот соответствующая часть в С11 7.21.6.2

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

строгая интерпретацией символов между скобками является то, что при отсутствии закрывающей скобки нет таких символов, но в присутствии ^ в качестве первого символа после [, было бы несовместимым , gcc достаточно любезно указать вероятную ошибку в исходном коде. Фактическое поведение определяется реализацией библиотеки C, но, как представляется, не указано в стандарте C. Таким образом, это форма неопределенного поведения, которую ИМХО следует действительно документировать как таковое в Стандарте.

+0

Спасибо! Я предлагаю вам отправить отчет о дефектах, поскольку я не знаю, куда и как это сделать. –

+1

Я отправил электронное письмо на секретаря рабочей группы С Даниэля Плакоша, я буду держать вас в курсе дел. – chqrlie