Задачи по языку С

       

в системах программирования Borland не


При выполнении этого примера в системах программирования Borland не забудьте о том, что мы определили файл defs.h не так, как это сделал м-р Фьюэр. В этом и следующих примерах мы рекомендуем непосредственно обращаться к функции printf для вывода символов и строк.




При переносе этого примера в среду системы программирования Borland может возникать замечательная ошибка: для п. "Записи 2.4" получаются совсем другие результаты, если мы вместо макроса PRINT3 используем:
printf("%s %s %s\n",++(p->s),a[(++p)->i].s,a[--(p->s1p->i)].s);
Почему? Дело в том, что в макросе PRINT3 есть три раздельных обращения к функции printf, таким образом, гарантированно вычисляется сначала первый параметр псевдофункции PRINT3, затем второй и наконец третий. Для функции же правилами языка не определено, в каком порядке вычисляются ее параметры. "Здравый смысл" подсказывает нам, что параметры вычисляются в прямом порядке, но на самом деле в большинстве систем программирования это не так. А если параметры вычисляются в обратном порядке, то при вычислении третьего параметра: a[--(p->s1p->i)].s указатель p еще не увеличен на 1 (это произойдет только при вычислении второго параметра) и т.д.
"Запланированные" результаты получатся при раздельных обращениях к printf:
printf("%s ", ++(p->s)); printf("%s", a[(++p)->i].s,); printf("%s\n", a[--(p->s1p->i)].s);
Является ли эта ошибка "абсолютной" или зависимой от реализации? Мы считаем, что это ошибка в любом случае. Вспомните примеры, рассмотренные в 3.3: "избегайте выражений, вычисление которых зависит от вашего знания того, что происходит при побочных эффектах".



Содержание раздела