Порядок выполнения вызовов функций в строке - не определено?

0

стр.77 K & R C говорит, что выход следующей программы не определен, но текущая версия Xcode не дает никаких предупреждений. Все еще не определено в текущем стандарте? Как насчет C++? Бонусные очки для аналогичной программы на Java и С#.

#include <stdio.h>

int my_m()
{
    static int n = 0;
    static int m[] = { 42, 57 };
    return n++ % 2 == 0 ? m[0] : m[1];
}
int main()
{
    printf("%d" , my_m() - my_m());

    return 0;
}
  • 2
    Порядок оценки не уточняется.
Теги:

2 ответа

5
Лучший ответ

Результат на самом деле не определен, просто не указан.

Разница в том, что неопределенное поведение означает, что все может случиться, в том числе поведение, которое, по-видимому, полностью не связано ни с чем в программе. Классическая линия заключается в том, что она "заставляет демонов вылететь из вашего носа".

Произвольные означает, что вы не имеете никакого способа знать, какой вызов my_m будет оцениваться первым и который будет оцениваться вторым, но это будет 1 один вызовом, а затем другие. Один вызов начнется и запустится до завершения, тогда другой вызов начнется и запустится до завершения - два не будут чередоваться или что-то в этом роде. Единственное, что непредсказуемо, это порядок, в котором совершаются два вызова (и да, в соответствии со стандартами C и C++, заказ все еще на 100% непредсказуем).

Как в С#, так и в Java порядок оценки указан как слева направо.


1. Или, по крайней мере, он будет действовать так, как если бы это было так.И C, и C++ следуют тому, что обычно называется "как если бы", что позволяет компилятору делать что-то по-другому, если это так, что поддерживает указанное внешне видимое поведение.

  • 0
    Спасибо за разъяснение терминологии (K & R говорит, что порядок "не определен" - я знаю, что он действительно старый).
  • 0
    Технически, возможно, что оба вызова происходят одновременно, если компилятор гарантирует, что наблюдаемые побочные эффекты идентичны тем, которые вы увидели бы, если бы они происходили один за другим (в любом порядке).
2

Компилятор не будет предупреждать вас обо всех неопределенных программах. В следующей строке:

printf("%d" , my_m() - my_m());

порядок вызовов my_m() не my_m(). Компилятор может решить сначала вызвать либо первый, либо второй. Поскольку функция возвращает 42 при первом вызове, а 57 во втором вызове, результат равен 42 - 57 или 57 - 42.

Изменение: я пропустил разницу между неопределенным и неуказанным, см. Ответ Джерри Коффинса для получения подробностей об этом.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню