Как этот код C может оцениваться как 0, а не 0 одновременно?
Я пробовал несколько конкурсов на запутывание кода (я знаю, что это не очень хорошая практика программирования, но это была проблема, с которой я и мой друг соревнуемся, поэтому нет необходимости указывать на очевидное), и, в одном из них, Я обнаружил следующее странное поведение (код был уменьшен до кода, который все еще воспроизводит поведение) для выражения t-scanf("%d",t--?&N:&t)
:
int main(int t, int N){
printf("%d\n",t-scanf("%d",t--?&N:&t));
}
int main(int t, int N){
printf("%d\n",t-scanf("%d",t--?&N:&t)==0);
}
int main(int t, int N){
printf("%d\n",t-scanf("%d",t--?&N:&t)!=0);
}
Если я выполню первую часть, будет напечатано 0, то есть выражение оценивается как 0.
На втором будет напечатано 0, то есть выражение не оценивает 0.
На третьем будет напечатано 1, означающее, что выражение не оценивается как 0.
Итак, вопрос: что не так с этими частями кода?
1 ответ
Эти примеры кода вызывают неопределенное поведение, потому что t--
не секвенирован по отношению к t
в начале выражения.
Соотношения последовательности здесь:
t--
чередуется перед другими выражениями в троичном операторе- Аргументы
scanf
каждый секвенируется перед использованием возвращаемого значенияscanf
тем не мение !=
а также -
не имеют отношения последовательности, поэтому эти отношения не ограничивают t
подлежит оценке до t--
или наоборот, поэтому поведение не определено.
В качестве обходного пути вы могли бы написать:
int temp = t;
printf("%d\n", temp - scanf("%d",t--?&N:&t));
t--
последовательность перед выполнением scanf
тело, так что приращение будет благополучно завершено до scanf
потенциально перезаписывает t
,