Что такое "неверная спецификация преобразования"?
Согласно C11
Глава §7.21.6.1, P9
Если спецификация преобразования недопустима, поведение не определено.282) Если какой-либо аргумент не является правильным типом для соответствующей спецификации преобразования, поведение не определено.
До того времени, как я понимаю,
char str [] = "Sourav";
- Заявление как
printf("%S", str);
принадлежат к первому предложению, не существует CS как%S
(ВЕРХНИЙ РЕГИСТР) - Заявление как
printf("%d", str);
принадлежит второму предложению (несоответствие между CS и типом аргумента, но%d
в любом случае, это не "недействительный" CS)
пока не рекомендовано иначе в недавней ветке комментариев.
Мое понимание неверно? Может ли второе утверждение также быть классифицировано как "неверный" (PS- не "неправильный") спецификатор преобразования?
Обновление: ответ и цепочка комментариев удалены, вот снимок для <10K пользователей.
3 ответа
"Действительность" спецификации конверсии определяется стандартными параграфами выше того, который вы цитировали:
Каждая спецификация преобразования представлена символом%. После% появляется следующее: ...
Знаки флага и их значения: ...
Спецификаторы преобразования и их значения: ...
Здесь это означает, что любая спецификация преобразования, составленная из элементов в приведенных выше списках, является действительной, все остальные не соответствуют стандарту. Вот почему параграф в вашем коде упоминает две причины UB. Одна - это спецификация, которая не соответствует грамматике, а другая - это несоответствие спецификации и типа.
Кажется, что комментарий, на который вы ссылаетесь, в разговорной речи использует "недействительный". Т.е. оба использования спецификаций преобразования являются "недействительными", так как они приводят к UB. Но только первый является "недействительным" с точки зрения языкового адвоката.
Чтобы поддержать моё понимание (и, возможно, для обоснования понимания в первую очередь), позвольте мне добавить два моих цента.
В течение минуты, давайте посмотрим на сноску 282, как упомянуто в цитате. Это говорит,
См. "Будущие направления библиотеки" (7.31.11).
и в §7.31.11
Строчные буквы могут быть добавлены в спецификаторы преобразования и модификаторы длины в
fprintf
а такжеfscanf
, Другие символы могут использоваться в расширениях.
Который ничего не упоминает об отношении между CS и его аргументом (если есть). Таким образом, "достоверность" CS не зависит от предоставленного аргумента.
Теперь, что сказал, еще пара указателей
Пункт 1:: Обратите внимание на упоминание фразы "спецификация конверсии", а не спецификатора конверсии, в цитате. Согласно главе §7.21.6.1/P4,
Каждая спецификация преобразования представлена символом
%
, После%
в последовательности появятся:Ноль или более флагов [...]
Необязательная минимальная ширина поля [...]
Дополнительная точность [...]
Дополнительный модификатор длины [...]
Символ спецификатора преобразования [...]
и у нас есть окончательные списки для всех элементов, упомянутых в
- P5, ширина поля и точность
- P6, флаги
- P7, модификатор длины
- P8, спецификатор преобразования
Таким образом, нет никакой связи с предоставленным аргументом (или она должна быть) для определения "достоверности" спецификации преобразования.
Чтобы дополнить это понимание, заимствуя слова из комментария Аджая Брахмакшатрия
"Я думаю, что рабочее слово здесь" соответствующее ". Первое предложение говорит, что если в строке существует спецификатор, который недопустим. Если нет, то каждый спецификатор сопоставляется со своим соответствующим аргументом. Тогда второе утверждение говорит о сопоставлении типов..... Я думаю, что второй пример не лежит в первой категории, потому что "соответствующий" не используется "
Точка 2:: С другой стороны, spec довольно четко и ясно говорит о "несоответствии" между CS и предоставленным соответствующим типом аргумента. Так что это совсем другой случай.
Например, в случае, когда оба случая объединены, трудно сказать, какое условие вызывает UB, но это UB, по нескольким причинам, наверняка.
Пример:
printf("%D", str);
после вопроса.
Сноска 282 указывает на будущие направления библиотеки C11 7.31.11p1:
Строчные буквы могут быть добавлены в спецификаторы преобразования и модификаторы длины в fprintf и fscanf. Другие символы могут использоваться в расширениях.
поэтому он также намекает на то, что недопустимые спецификаторы преобразования означают те спецификации преобразования, которых нет в списке, и эти строчные буквы могут использоваться в будущей версии C; и расширения могут свободно использовать другие буквы.
И хотя Нормативный, C11 Приложение J.2. содержит следующее:
- Недопустимая спецификация преобразования найдена в формате для одной из отформатированных функций ввода / вывода или
strftime
или жеwcsftime
функция (7.21.6.1, 7.21.6.2, 7.27.3.5, 7.29.2.1, 7.29.2.2, 7.29.5.1).
то есть недопустимая спецификация преобразования в *printf
здесь в паре с неверной спецификацией преобразования в strftime
- который не принимает переменные аргументы, и недействительность не может возникнуть из-за несоответствия между спецификацией преобразования и соответствующим аргументом;
Это может быть противопоставлено
- Недостаточно аргументов для формата в вызове одной из отформатированных функций ввода / вывода или аргумент не имеет подходящего типа (7.21.6.1, 7.21.6.2, 7.29.2.1, 7.29.2.2).
который обсуждает несоответствие между аргументами и спецификаторами преобразования, без упоминания слова "недействительный".