отменить и переопределить макрос __cplusplus - PullRequest
0 голосов
/ 10 декабря 2018

Я хочу отменить и переопределить макрос __cplusplus, однако получаю ошибку компиляции: __cplusplus was not declared in this scope

#define TEMP_VERSION __cplusplus // temporary macro to hold the __cplusplus  containt
#undef __cplusplus
#define __cplusplus TEMP_VERSION  // redefine __cplusplus

#define AA 111
#undef AA
#define AA 111

int main()
{
    cout << "__cplusplus = "<<__cplusplus<<endl; // It doesn't work
    cout << "AA = "<<AA<<endl; // It works

    return 0;
}
  • Вопрос 1: Почему он не работает с __cplusplus, но работает с AA

Я знаю, что это действительно ужасно, но причина, по которой я не определил макрос, заключается в том, что я использую Программное обеспечение сторонних производителей, где они не используют #ifdef __cplusplus, я имею в виду содержание#ifdef __cplusplus ... #endif неправильно.Поэтому вместо того, чтобы менять их программное обеспечение, я решил сделать следующее:

#define TEMP_VERSION __cplusplus
#undef __cplusplus
#include <third_party_sw.h>
#define __cplusplus TEMP_VERSION
  • Вопрос 2: Как вы думаете, это хороший подход?

Ответы [ 3 ]

0 голосов
/ 10 декабря 2018

Из стандарта C ++ ([cpp.predefined, 3-4]):

Значения предопределенных макросов (кроме __FILE__ и __LINE__) остаются постоянными на протяжении всего переводаБлок.Если какое-либо из предварительно определенных имен макросов в этом подпункте или определенный идентификатор являются предметом директивы предварительной обработки #define или #undef, поведение не определено.

Другими словами,макрос __cplusplus - это не просто то, что компилятор начинает с определения перед передачей управления вам;это неизменяемая константа, которая не может быть изменена и является ошибкой при попытке ее изменить.

Что касается того, будет ли это хорошим подходом, если бы это было возможно: Зависит от контекста, но, вероятно, нет.Подобные хаки типа «обмануть заголовок» (#define private public, кто-нибудь?) Редко бывают эффективными и никогда не безопасными.

РЕДАКТИРОВАТЬ: Да, кстати, также, даже если у вас был макрос, законно было сохранять /восстановить, это не будет правильным способом сделать это.См. Можно ли переопределить макрос C ++ и определить его обратно? .

0 голосов
/ 10 декабря 2018

Вопрос 1: Почему он не работает с __cplusplus, но работает с AA

Поскольку __cplusplus является предопределенным макросом, и поведение (не) определяет егоне определено:

стандартный черновик [cpp.predefined]

Если любое из предопределенных имен макросов в этом подпункте или определенный идентификатор является предметом #defineили директива предварительной обработки #undef, поведение не определено....

AA не является предопределенным макросом, и идентификатор не зарезервирован.Можно (пере) определить его.


Вопрос 2: Как вы думаете, это хороший подход?

(Пере) определениезарезервированные идентификаторы никогда не являются хорошим подходом.Даже переопределение пользовательских макросов является сомнительным предложением.

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

0 голосов
/ 10 декабря 2018

Это потому, что __cplusplus предопределено компилятором.

Технически, это предварительный процессор, который определяет их, но в зависимости от того, какой компилятор вызывает препроцессор,выход может отличаться.Попробуйте выполнить это:

$ g++ -dM -E - </dev/null

Выходные данные - все, что определяет препроцессор, который (в данном случае) производит препроцессор, выполняемый этой командой.не появиться там.Он встроен в каждый модуль компиляции C ++.

(То же самое работает при замене clang++ на g++.)

...