Переопределение макроса

312
26 января 2017, 02:56

Подскажите, можно ли определить макрос так, чтобы в зависимости от того, использовался он, или нет, он принимал разные значения ?

Пример:

#ifndef DISABLE_MANGLING
#   define DISABLE_MANGLING \
        extern "C" {
#else
#   undef  DISABLE_MANGLING
#   define DISABLE_MANGLING \
        }
#endif

Ожидания: используя макрос первый раз - он раскрывается в extern "C" {, второй раз - раскрывается в }.

Реальность: в обоих случаях раскрывается в extern "C" {.

Что подскажите ?

Answer 1

Как вы хотите не получится, т.к. препроцессор не будет выполнять ранее написанный #ifdef встречая в тексте макрос.

Теоретически можно написать что-то такое (я сократил DISABLE_MANGLING до DM)

#ifndef DM
#define DM extern "C" {
#define DME 1
#else
#undef DM
#if DME == 1
#undef DME
#define DME 2
#define DM }
#else
#undef DME
#define DME 1
#define DM extern "C" {
#endif
#endif

DM 1
#if DME == 1
#undef DME
#undef DM
#define DME 2
#define DM }
#else
#undef DME
#undef DM
#define DME 1
#define DM extern "C" {
#endif

DM 2
#if DME == 1
#undef DME
#undef DM
#define DME 2
#define DM }
#else
#undef DME
#undef DM
#define DME 1
#define DM extern "C" {
#endif
DM 3
#if DME == 1
#undef DME
#undef DM
#define DME 2
#define DM }
#else
#undef DME
#undef DM
#define DME 1
#define DM extern "C" {
#endif
DM 4

и получить в результате

avp@avp-ubu1:hashcode$ gcc -E dm.c
# 1 "dm.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "dm.c"
# 18 "dm.c"
extern "C" { 1
# 32 "dm.c"
} 2
# 45 "dm.c"
extern "C" { 3
# 58 "dm.c"
} 4
avp@avp-ubu1:hashcode$ 

но, не думаю, что это хоть как-то может пригодиться на практике.

Также, поскольку текст, получаемый в результате раскрытия макроса, повторно не анализируется препроцессором, такая попытка уменьшить объем кода

#define XX \
#if DME == 1 \
#undef DME \
#undef DM \
#define DME 2 \
#define DM } \
#else \
#undef DME \
#undef DM \
#define DME 1 \
#define DM extern "C" { \
#endif
DM 1
XX

не сработает.

В принципе (если уж очень хочется) сократить количество текста можно, записав #ifdef-ы в отдельный файл

// dm.h file
#ifndef DM
#define DM extern "C" {
#define DME 1
#else
#undef DM
#if DME == 1
#undef DME
#define DME 2
#define DM }
#else
#undef DME
#define DME 1
#define DM extern "C" {
#endif
#endif

и включая его в "основной код" вот таким образом

// dm.c
#include "dm.h"
DM 1
#include "dm.h"
DM 2
#include "dm.h"
DM 3
#include "dm.h"
DM 4
READ ALSO
Запустить .exe файлы c++

Запустить .exe файлы c++

Подскажите, пожалуйстаМне нужно создать 2 exe-файла: test1

325
Могут ли функции иметь один адрес?

Могут ли функции иметь один адрес?

В ответе говорится, что Open Watcom компилирует такой код

343
Как импортировать Sakila Database в phpMyAdmin?

Как импортировать Sakila Database в phpMyAdmin?

Когда импортирую через инструмент импорт, пишет что нет таблиц, либо они пустыеВозможно, кто-то сталкивался с такого рода импортом и сможет...

307