取消定义和重新定义 __cplusplus 宏
undefine and redefine the __cplusplus macro
我想取消定义和重新定义 __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
,我的意思是 [=17= 的内容] 是错的。因此,我没有更改他们的软件,而是选择执行以下操作
#define TEMP_VERSION __cplusplus
#undef __cplusplus
#include <third_party_sw.h>
#define __cplusplus TEMP_VERSION
- 问题 2:您认为这是一个好的方法吗?
因为__cplusplus
是编译器预定义的
从技术上讲,定义它们的是预处理器,但根据调用预处理器的编译器,输出可能会有所不同。试试 运行宁这个:
$ g++ -dM -E - </dev/null
输出是所有预处理器定义的(在这种情况下)预处理器运行通过此命令产生。
请注意 __cplusplus
没有出现在那里。它内置于每个 C++ 编译单元。
(将 clang++
替换为 g++
时同样有效。)
来自 C++ 标准 ([cpp.predefined, 3-4]):
The values of the predefined macros (except for __FILE__
and __LINE__
)
remain constant throughout the translation unit. If any of the
pre-defined macro names in this subclause, or the identifier defined,
is the subject of a #define or a #undef preprocessing directive, the
behavior is undefined.
换句话说,__cplusplus
宏不仅仅是编译器在将控制权移交给您之前通过定义开始的东西;它是一个不可变常量,无法更改,尝试更改是错误的。
至于如果可能的话这是否是一个好方法:取决于上下文,但可能不是。这些 "fool the header" 黑客攻击(#define private public
,有人吗?)很少有效而且永远不安全。
编辑:哦,顺便说一下,即使您确实有一个宏,save/restore 也是合法的,但那不是正确的方法。参见 Can I redefine a C++ macro then define it back?。
Question 1: Why it is not working with the __cplusplus but works with AA
因为 __cplusplus
是一个 pre-defined 宏,并且(未)定义它的行为是未定义的:
stadard draft [cpp.predefined]
If any of the pre-defined macro names in this subclause, or the identifier defined, is the subject of a #define or a #undef preprocessing directive, the behavior is undefined. ...
AA
不是 pre-defined 宏,标识符也不是保留的。可以(重新)定义它。
Question 2: What do you think is it a good approach ?
(重新)定义保留标识符从来都不是一个好方法。甚至重新定义用户定义的宏也是一个可疑的提议。
如果可能,理想的方法可能是修复第三方软件。或者,您可以为没有问题的软件编写自定义 header。
我想取消定义和重新定义 __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
,我的意思是 [=17= 的内容] 是错的。因此,我没有更改他们的软件,而是选择执行以下操作
#define TEMP_VERSION __cplusplus
#undef __cplusplus
#include <third_party_sw.h>
#define __cplusplus TEMP_VERSION
- 问题 2:您认为这是一个好的方法吗?
因为__cplusplus
是编译器预定义的
从技术上讲,定义它们的是预处理器,但根据调用预处理器的编译器,输出可能会有所不同。试试 运行宁这个:
$ g++ -dM -E - </dev/null
输出是所有预处理器定义的(在这种情况下)预处理器运行通过此命令产生。
请注意 __cplusplus
没有出现在那里。它内置于每个 C++ 编译单元。
(将 clang++
替换为 g++
时同样有效。)
来自 C++ 标准 ([cpp.predefined, 3-4]):
The values of the predefined macros (except for
__FILE__
and__LINE__
) remain constant throughout the translation unit. If any of the pre-defined macro names in this subclause, or the identifier defined, is the subject of a #define or a #undef preprocessing directive, the behavior is undefined.
换句话说,__cplusplus
宏不仅仅是编译器在将控制权移交给您之前通过定义开始的东西;它是一个不可变常量,无法更改,尝试更改是错误的。
至于如果可能的话这是否是一个好方法:取决于上下文,但可能不是。这些 "fool the header" 黑客攻击(#define private public
,有人吗?)很少有效而且永远不安全。
编辑:哦,顺便说一下,即使您确实有一个宏,save/restore 也是合法的,但那不是正确的方法。参见 Can I redefine a C++ macro then define it back?。
Question 1: Why it is not working with the __cplusplus but works with AA
因为 __cplusplus
是一个 pre-defined 宏,并且(未)定义它的行为是未定义的:
stadard draft [cpp.predefined]
If any of the pre-defined macro names in this subclause, or the identifier defined, is the subject of a #define or a #undef preprocessing directive, the behavior is undefined. ...
AA
不是 pre-defined 宏,标识符也不是保留的。可以(重新)定义它。
Question 2: What do you think is it a good approach ?
(重新)定义保留标识符从来都不是一个好方法。甚至重新定义用户定义的宏也是一个可疑的提议。
如果可能,理想的方法可能是修复第三方软件。或者,您可以为没有问题的软件编写自定义 header。