math.h macro collisions
math.h macro collisions
math.h中的宏DOMAIN
与枚举以及可能的其他类型冲突。我不知道该怎么办。
#include <algorithm>
enum Type { DOMAIN };
int main(){
Type t = Type::DOMAIN;
return 0;
}
使用标志-std=c++11编译。这个代码的C99版本编译得非常好:
#include <algorithm>
enum Type { DOMAIN };
int main(){
Type t = DOMAIN;
return 0;
}
我检查了源代码,库是罪魁祸首。算法包括stl_algo.h,其中有ifdef:
#if __cplusplus >= 201103L
#include <random> // for std::uniform_int_distribution
#include <functional> // for std::bind
#endif
以下代码在c++11编译器上编译良好:
#include <random>
#include <iostream>
int main(){
std::cout << DOMAIN << std::endl;
return 0;
}
这是一个功能还是一个bug?
EDIT*脏修复:
#ifdef DOMAIN
#undef DOMAIN
#endif
这是一个bug(如果你想大方一点,也可以是一个"疣"(。
这个答案的其余部分只涉及GCC和Gnu标准的C库头。man
页面引用的是linux系统(但我添加了man7.org的链接(
DOMAIN
宏来自math.h
的System V支持。(请参阅man matherr
。(System V支持通常通过定义_SVID_SOURCE
功能测试宏来启用(请参见man feature_test_macros
(,但如果定义了_GNU_SOURCE
,则会与一系列其他扩展一起启用;如果未定义功能测试宏,则默认情况下会启用。
如果--std
选项被省略或设置为gnu##
,则gcc
为C程序预定义_GNU_SOURCE
。各种--std=c##
选项导致定义__STRICT_ANSI__
。因此,使用某些明确的C标准编译C代码将抑制System V扩展。需要这样做是因为System V扩展与标准不兼容,甚至与Posix也不兼容,因为它们污染了全局命名空间。(DOMAIN
只是这种污染的一个例子。(
然而,即使指定了--std=c++##
,g++
也定义了_GNU_SOURCE
,因此System V扩展将悄悄进入
一个丑陋的解决方法是自己设置功能,然后取消定义__USE_SVID
:
#include <features.h>
#undef __USE_SVID
#include <random>
#include <iostream>
int main(){
std::cout << DOMAIN << std::endl;
return 0;
}
(在coliru上直播(
IMHO,这应该没有必要。但它就在那里。
N4140的§17.6.5.2[res.on.headers]/1规定:
C++标头可以包括其他C++标头。C++标头应提供其概要中出现的声明和定义。大纲中显示的C++标头(包括其他C++标头(应提供出现在其他标头概要中的声明和定义。
因此,<algorithm>
到#include <cmath>
将有问题的宏常量注入到您的命名空间中是有效的。
然而,请注意,标准(§17.6.4.3.1[宏名称]/1(不允许您的"快速且肮脏的修复":
包含标准库标头的翻译单元不得在任何标准库标头中声明
#define
或#undef
名称。
您必须为enum
常量选择一个不同于DOMAIN
的名称。
- LPWSTR typedef and macro?
- 如何修复MSVC++(Microsoft Visual studio)中"macro overloading"的可变参数宏相关问题?
- CALLBACK macro (QT)
- Specific C++ Macro
- QT Macro q_slots'''类访问限制之后
- 如何在Macro BranchCallback中固定界限/更改变量界限?C
- Qt with Visual Studio macro issue
- Replacing __LINE__ macro
- how to #define c++ STL macro
- CMake C/C++ macro generating
- 为什么海湾合作委员会声称我违反了"at least one argument for variadic macro",而我至少有一个论点?
- c++ macro containing Q_OBJECT
- Mutex Protect Macro
- 动态变量上的c++MACRO未声明标识符
- Variadic Macro without __VA_ARGS__
- #ifdef macro
- Handling c++ wxWidgets EVT_MAXIMIZE macro
- 是“ Gnu-Zero-variadic-Macro-arguments”可靠地忽略
- MACRO取决于其文件夹位置
- math.h macro collisions