Проблема с макросом функции - PullRequest
4 голосов
/ 01 ноября 2011

Практика программирования Книга гласит:

Одна из самых серьезных проблем с функциональными макросами состоит в том, что параметр, который появляется более одного раза в определении, может быть оценен большечем один раз;если аргумент в вызове включает выражение с побочными эффектами, результатом будет небольшая ошибка.Этот код пытается реализовать один из тестов символов из:

#define isupper(c) ((c) >= 'A' && (c) <= 'Z')

Обратите внимание, что параметр c встречается дважды в теле макроса.Если я вызываю ужин в контексте, подобном этому,

while (isupper(c = getchar()))

, то каждый раз, когда входной символ больше или равен A, он отбрасывается, а другой символ читается какпроверено на Z.

Я не понимаю, как можно отбросить символ больше> = A.

1 Ответ

6 голосов
/ 01 ноября 2011

Поскольку определения макросов развертываются в тексте до самой компиляции,

isupper(c = getchar())

расширится до

((c = getchar()) >= 'A' && (c = getchar()) <= 'Z')

, который по правилу короткого замыкания для && вызывает getchar дважды, если он возвращает >= 'A' в первый раз и присваивает c значение, возвращаемое при втором вызове.

...