#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
Можно ли объединить STR3 == "s1"? Вы можете сделать это, передав аргументы другой функции макроса. Но есть ли прямой путь?
c++
c
c-preprocessor
TVR
источник
источник
Ответы:
Если это обе строки, вы можете просто сделать:
Препроцессор автоматически объединяет соседние строки.
РЕДАКТИРОВАТЬ:
Как отмечено ниже, конкатенацию выполняет не препроцессор, а компилятор.
источник
L"a"
и"b"
получитьL"ab"
, но можете объединитьL"a"
иL"b"
получитьL"ab"
.Вам не нужно такое решение для строковых литералов, поскольку они объединяются на уровне языка, и это все равно не сработает, потому что «s» «1» не является допустимым токеном препроцессора.
[Изменить: в ответ на некорректный комментарий «Только для записи» ниже, который, к сожалению, получил несколько голосов, я повторю приведенное выше утверждение и замечу, что фрагмент программы
выдает это сообщение об ошибке на этапе предварительной обработки gcc: ошибка: вставка «s» и «1» не дает действительного токена предварительной обработки
]
Однако для общей вставки токенов попробуйте следующее:
Затем, например, оба
PPCAT_NX(s, 1)
иPPCAT(s, 1)
производят идентификаторs1
, еслиs
не определен как макрос, и в этом случаеPPCAT(s, 1)
производит<macro value of s>1
.Продолжая тему, эти макросы:
Затем,
Напротив,
источник
"s""1"
действительно для C (и C ++). Это два токена (строковые литералы), которые компилятор объединяет и представляет собой один токен."s""1" isn't a valid token
- это правильно; это, как вы говорите, два жетона. Но объединение их вместе с помощью ## сделало бы их одним токеном предварительной обработки, а не двумя токенами, и поэтому компилятор не будет выполнять конкатенацию, а лексер отклонит их (язык требует диагностики).STRINGIZE_NX(whatever occurs here)
расширяется до «все, что здесь происходит», независимо от любых макроопределений для того, что происходит или здесь.if A is defined as FRED then STRINGIZE_NX(A) still expands to "FRED"
- это ложь и не имеет ничего общего с вашим тестом. Вы изо всех сил пытаетесь не понять или не понять это правильно, и я не собираюсь вам больше отвечать.Подсказка:
STRINGIZE
приведенный выше макрос хорош, но если вы допустили ошибку и его аргумент не является макросом - у вас есть опечатка в имени или вы забыли#include
файл заголовка - тогда компилятор с радостью поместит предполагаемое имя макроса в строка без ошибок.Если вы хотите, чтобы аргумент
STRINGIZE
всегда был макросом с нормальным значением C, тогдарасширит его один раз и проверит его на предмет действительности, отбросит его, а затем снова расширит в строку.
Мне потребовалось некоторое время, чтобы понять, почему в
STRINGIZE(ENOENT)
итоге"ENOENT"
вместо"2"
... я не включилerrno.h
.источник
,
оператора. :)((1),"1") "." ((2),"2")
«1». «« 2 »)STRINGIZE
определением"The value of ENOENT is " STRINGIZE(ENOENT)
работает, тогда как"The value of ENOENT is" STRINGIZE_EXPR(X)
выдает ошибку.