В какой момент проблематично неопределенное поведение?
Все UB проблематично.
Определение эффектов UB конкретной версии компилятора имеет некоторыезаслуга в решении проблем.Тем не менее, никогда не следует полагаться на этот эффект UB для сохранения.
Мой ответ основан на C в целом, а не на gcc 4.7.
Учтите, что объекты не обязательно передаются с использованиемодин и тот же механизм для разных типов. Соответствующий истинный пример : float/double
передается в стек FP и других типов через обычный стек.printf("%llx\n", 1.234);
может плохо провалиться, даже если переданный размер равен 8 и ожидается 8, но они находятся в разных местах.Аналогичная разница может возникнуть между типами указателей и целыми числами (хотя это звучит как платформа единорога).
Оставить UB в коде неэффективным в разработке.
Подумайте, нашел ли кто-то UB, который работалотлично в выбранном случае, следующая компиляция или версия может привести к другим результатам.Исправляя, вы экономите время, не пытаясь объяснить, как «этот UB в порядке, я знаю, что проверил его» во время проверки кода.Также сэкономьте время, не нуждаясь в том, чтобы найти способ успокоить предупреждение об этом "хорошем" UB.Команда разработчиков, которая должна поддерживать ваш код UB, будет бормотать злые слова о предыдущем кодере.
UB Отсутствует соответствующий аргумент.
custom_printf("HI THERE%d");
<source>:26:5: warning: format '%d' expects a matching 'int' argument [-Wformat]
Не UB.С дополнительными аргументами все в порядке, но, скорее всего, это неверный шаг кодирования - отсюда и предупреждение. @ melpomene
custom_printf("HI THERE", 1);
<source>:27:5: warning: too many arguments for format [-Wformat-extra-args]
UB.int
и void *
могут отличаться по размеру, допустимым значениям и механизмам передачи функций,
custom_printf("val: %d", (void*)0);
<source>:28:5: warning: format '%d' expects argument of type 'int', but argument 2 has type 'void *' [-Wformat]
UB.так же, как строка 28
custom_printf("val: %p", 0);
<source>:29:5: warning: format '%p' expects argument of type 'void *', but argument 2 has type 'int' [-Wformat]
UB.int
и long long
могут отличаться размерами и функциями передающих механизмов,
custom_printf("val: %lld", 1);
<source>:30:5: warning: format '%lld' expects argument of type 'long long int', but argument 2 has type 'int' [-Wformat]
UB.Типы могут отличаться по размеру, допустимым значениям и механизмам передачи функций,
custom_printf("val: %s", (THING){"A", "AA", "CCCC"});
<source>:31:5: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'THING' [-Wformat]
UB: Неверный стандартный спецификатор %0.30s
, может произойти что угодно.Хорошо ведет себя в некоторых системах, которые определяют поведение для этого нестандартного спецификатора.
custom_printf("val: %0.30s","HI");
<source>:32:5: warning: '0' flag used with '%s' gnu_printf format [-Wformat]
UB, как строка 30
custom_printf("val: %d",LLONG_MAX);
<source>:33:5: warning: format '%d' expects argument of type 'int', but argument 2 has type 'long long int' [-Wformat]
Не UB с main()
.Только проблема UB с функциями в целом, если вызывающий код использует возвращаемое значение.Тем не менее, main()
особенный в том, что код действует, как если бы return 0;
был в конце - если эта функция не заканчивается return
.
<source>:34:1: warning: control reaches end of non-void function [-Wreturn-type]