Мне было интересно, почему мы не можем использовать конкатенацию маркера вне define
s.
Это происходит, когда я хочу их в одно и то же время:
- конфликтующее именование в библиотеке (или для "generics" )
- debugability; при использовании
define
для этого весь код объединяется в строку, и отладчик будет показывать только строку, в которой был использованdefine
Некоторым людям может понадобиться пример (актуальный вопрос ниже):
lib.inc:
#ifndef NAME
#error includer should first define NAME
#endif
void NAME() { // works
}
// void NAME##Init() { // doesn't work
// }
main.c:
#define NAME conflictfree
#include "lib.inc"
int main(void) {
conflictfree();
// conflictfreeInit();
return 0;
}
Ошибка:
In file included from main.c:2:0:
lib.h:6:10: error: stray '##' in program
void NAME##Init();
^
Эмпирическое правило "concat only in define". И если я правильно помню: причина - из-за фаз препроцессора.
Вопрос: Почему он не работает. Аргумент фаз звучит так, как будто это было ограничение реализации (а не логическая причина), а затем нашло свое отражение в стандарте. Что может быть так сложно в принятии NAME##Init()
, если NAME()
отлично работает?