Целочисленные значения во время компиляции

Мне нужно написать некоторые константы в разных файлах с некоторым целочисленным идентификатором. Например:

#define MESSAGE_FIRST 0

В другом файле:

#define MESSAGE_ANOTHER 1

Любые способы получить этот идентификатор автоматически во время компиляции? Что-то типа:

#define MESSAGE_AUTO GetNextId()

Я не могу использовать перечисления здесь, потому что эти директивы будут в разных файлах.

Спасибо.

p.s. GCC, Линукс


person Max Frai    schedule 30.06.2012    source источник
comment
В стандарте нет чего-то вроде __COUNTER__ (аналогично __LINE__) AFAIK. p.s. В моем собственном препроцессоре у меня есть это.   -  person Kirill Kobelev    schedule 30.06.2012
comment
Я не могу придумать никакого способа сделать это за пределами генерации внешнего кода. Но, возможно, если вы дадите более подробное описание реальной проблемы, которую пытаетесь решить, мы сможем предложить вам лучшее решение.   -  person Benjamin Lindley    schedule 30.06.2012
comment
Они должны быть в разных файлах? Или все они могут включать один заголовочный файл с этими значениями?   -  person Matt    schedule 30.06.2012
comment
потребность в таком счетчике времени компиляции с пересечением файлов пахнет недостатком дизайна.   -  person Walter    schedule 30.06.2012


Ответы (2)


Вы можете сделать счетчик времени компиляции с наследованием и перегрузкой функций:

template<unsigned int n> struct Count { bool data[n]; };
template<int n> struct Counter : public Counter<n-1> {};
template<> struct Counter<0> {};
Count<1> GetCount(Counter<1>);

#define MAX_COUNTER_NUM 64
#define COUNTER_VALUE (sizeof(GetCount(Counter<MAX_COUNTER_NUM + 1>())) / sizeof(bool))
#define INC_COUNTER Count<COUNTER_VALUE + 1> GetCount(Counter<COUNTER_VALUE + 1>);

Вы можете увидеть его в действии здесь. Также работает с msvc.

person Synxis    schedule 30.06.2012

Вы говорите, что используете GCC. В GCC есть макрос (насколько мне известно, для каждого файла) с именем __COUNTER__, который увеличивается на единицу после каждого использования.

Обратите внимание, что это расширение, не включенное в стандартный C++.

Другой вариант - использовать перечисление:

enum {
    FIRST = 0,
    SECOND,
    THIRD
};

Или вы можете сделать это вручную, используя такие директивы препроцессора:

#define FIRST 0
#define SECOND (1 + FIRST)
#define THIRD (1 + SECOND)
person orlp    schedule 30.06.2012
comment
Как насчет последнего совета: это полезно, когда все в одном файле, мне нужно в разных, и несколько программистов будут редактировать этот код, поэтому возможны конфликты. - person Max Frai; 30.06.2012
comment
Пожалуйста, используйте круглые скобки при определении SECOND и THIRD. - person robert; 30.06.2012