#define должно добавить пробелы вокруг макросов?
Я смотрел программу на http://www0.us.ioccc.org/1988/westley.c, упомянутый в другой ответ SO - он должен печатать значение pi, около 3,142, но когда я его компилирую и запускаю, я получаю 0.250
. Похоже, что когда препроцессор GCC (как проверен 4.1.2, так и 3.4.6) работает над кодом, он преобразует
#define _ -F<00||--F-OO--;
_-_-_
к
-F<00||--F-OO--;- -F<00||--F-OO--;- -F<00||--F-OO--;
но я думаю, что для работы программы это должно быть
-F<00||--F-OO--;--F<00||--F-OO--;--F<00||--F-OO--;
то есть. GCC добавляет дополнительное пространство перед расширением "macro". Предполагается, что путь #define
должен работать? (Сменилось ли это с 1988 года?)
EDIT: Также будет оценена любая информация о том, как предотвратить появление этих пробелов.
Ответы
Ответ 1
Препроцессор работает с токенами, а не строго по тексту. Так что технически это не "помещает пробел" между ними, но если вы явно не скажете ему вставить два токена вместе с оператором ##
, он этого не сделает. В этом случае две -
через макрострочные линии считаются двумя разными токенами - оба значения означают унарный минус, а не декремент.
см. также: http://en.wikipedia.org/wiki/C_preprocessor#Token_concatenation
Ответ 2
Только более старые препроцессоры не вставляли лишнее пространство - обратите внимание, что оригинальная запись была отправлена более 20 лет назад в 1988 году до того, как была стандартизирована стандартная версия стандарта 1989 года. Вы можете передать флаг -traditional-cpp
в препроцессор GCC, что заставляет его имитировать поведение старомодных препроцессоров C, в отличие от препроцессоров ISO C.
Ответ 3
Из стандарта C99:
Директива предварительной обработки формы
# определить идентификатор замены-списка new-line
определяет объект-подобный макрос, который заменяет каждый последующий экземпляр имени макроса заменяющим списком токенов предварительной обработки, которые составляют оставшуюся часть директивы.
Таким образом, макросы работают с токенами, и ожидается, что это будет пустое пространство.
И вы можете получить вывод, который хотите использовать с помощью оператора склеивания токенов, ##
, но для этого вам нужно использовать некоторые дополнительные уродства:
#define PASTE2( x, y) x##y
#define PASTE( x, y) PASTE2(x, y)
#define _ -F<00||--F-OO--;
PASTE(PASTE(PASTE(PASTE(_,-),_),-),_)
Поэтому я не уверен, что это реальный ответ для вас.
Вы можете использовать менее уродливый набор макросов для получения желаемых выражений - все равно будут пробелы, но пробелы не будут мешать созданию операторов --
:
_ PASTE(-,_) PASTE(-,_)
Я все еще сомневаюсь, что вы хотите.
Ответ 4
Да, gcc вставляет лишние пробелы (проверьте, проверяя вывод stdout gcc -E westley.c
(. Насколько я знаю, это поведение соответствует стандарту.