Ответ 1
По-моему, стандарт неясен в этом вопросе.
Авторы gcc явно придерживались мнения, что повторяющиеся флаги недействительны, поскольку gcc выдает предупреждение по умолчанию для чего-то вроде:
printf("%++d\n", 42);
но это не обязательно говорит нам о том, что предназначались авторам стандарта.
Стандарт позволяет:
Ноль или более флагов (в любом порядке), которые изменяют смысл преобразования спецификация.
Флаги -
, +
, пробел, #
и 0
. Фраза "Нуль или больше флагов", я думаю, специально предназначена для того, чтобы разрешить объединение разных флагов. Например, это:
#include <stdio.h>
int main(void) {
printf("|%6x|\n", 0x123);
printf("|%-6x|\n", 0x123);
printf("|%#6x|\n", 0x123);
printf("|%-#6x|\n", 0x123);
printf("|%#-6x|\n", 0x123);
}
действителен и производит этот вывод:
| 123|
|123 |
| 0x123|
|0x123 |
|0x123 |
В других контекстах стандарт явно указывает, может ли конструкция повторяться или не повторяться. Например, long long int
отличается от long int
, а long int int
является синтаксической ошибкой. С другой стороны, стандарт явно говорит (N1570 6.7.3p5), что:
Если один и тот же определитель появляется более одного раза в одном и том же спецификатор-классификатор-список, либо напрямую, либо через один или несколько
typedefs
, поведение такое же, как если бы оно появилось только один раз.
Отсутствие такого заявления здесь заставляет меня подозревать, что авторы стандарта не рассматривали случай повторения одного и того же флага.
Если я ошибаюсь в этом вопросе, и комитет решил, что повторяющийся флаг будет эквивалентен одному флагу, тогда ваш синтаксический анализатор формата должен рассматривать их как эквивалентные. Если я прав, то поведение повторения одного и того же флага будет undefined, и ваша реализация может делать все, что вам нравится, включая обращение к ним как эквиваленту одного флага.
В любом случае вы можете отправить предупреждение, если хотите. Даже если стандарт определяет поведение повторяющегося флага, он все еще может быть плохого стиля и заслуживает внимания.