是否可以在不使用"undef"的情况下重新定义宏?
Is it possible to redefine a macro without the use of ‘undef’?
我试图理解libspatialindex源代码。作为 c++ 的新手,我很难理解宏的概念。 该库的 C API 包装器 sidx_api.cc 直接或间接包含许多标头,其中两个似乎定义了相同的宏,涉及连接动态库,没有"undef":
工具.h
45 #if (defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64) && !defined __GNUC__
46 #ifdef SIDX_DLL_EXPORT
47 #define SIDX_DLL __declspec(dllexport)
48 #else
49 #define SIDX_DLL __declspec(dllimport)
50 #endif
51
52 // Nuke this annoying warning. See http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
53 #pragma warning( disable: 4251 )
54
55 #else
56 #define SIDX_DLL
57 #endif
sidx_export.h
29 #pragma once
30
31 #ifndef SIDX_C_DLL
32 #if defined(_MSC_VER)
33 # define SIDX_C_DLL __declspec(dllexport)
34 # define SIDX_DLL __declspec(dllexport)
35 #else
36 # if defined(USE_GCC_VISIBILITY_FLAG)
37 # define SIDX_C_DLL __attribute__ ((visibility("default")))
38 # define SIDX_DLL __attribute__ ((visibility("default")))
39 # else
40 # define SIDX_C_DLL
41 # define SIDX_DLL
42 # endif
43 #endif
44 #endif
我相信在没有"undef"的情况下重新定义宏是有问题的,例如,正如这里和这里所讨论的那样。 我在这里错过了什么吗? 谢谢。
这里没有非法重新定义的宏。有些可能会用相同的定义多次定义,这是可以的。构成问题的是不相同的定义。
DLL 本身始终使用项目设置定义的SIDX_DLL_EXPORT
生成。使用 DLL 的代码是在未定义此宏的情况下生成的。
第二个标头是 DLL 的一部分。它始终在定义SIDX_DLL_EXPORT
的情况下进行编译。因此,它定义的宏(如果有)始终与第一个标头中定义的宏相同。这种相同的重新定义并不构成问题。
如果重新定义它,则需要使用完全相同的预处理令牌列表重新定义它。 对于函数宏和对象宏都是如此。
从6.10.3 Macroreplacement p2
:
当前定义为类对象宏的标识符不应由另一个 #define 预处理指令重新定义,除非第二个定义是类对象的宏定义并且两个替换列表相同。
同样,当前定义为类函数宏的标识符不应由另一个 #define 预处理指令重新定义,除非第二个定义是具有相同参数数量和拼写的类似函数的宏定义,并且两个替换列表相同。
所以这个定义使用shall
.
现在,从4.Conformance p2
:
如果违反了出现在约束之外的"应"或"不应"要求,则行为未定义。
这是官方定义。 因此,在重新定义宏符号之前,如果不将宏符号从预处理器的环境中删除(使用 #undef),您将获得未定义的行为。
如果您在 C 的某些实现中发现其他情况,则这不是标准化的。
正确的是插入不同的定义,以响应您在外部设置的某些条件的功能:
#if COND
#define M M1
#else
#define M M2
#endif
如果你使用一些重新定义它的库,肯定有一些宏可以设置COND
并使事物定义得很好。 您需要学习如何使用库。 使用不同的 pp 令牌列表重新定义它是无效的。
- 定义C++新的环境变量并在 bat 文件中使用它
- 从使用概念定义的函数返回新对象
- 如何在C++中为 if 和 else 语句定义新行为
- 如何从 C++ 中的现有模板函数定义新函数
- 自定义分配器,包括放置新案例
- 正在通过const-ref未定义的行为捕获新构造的对象
- 如何在CPropertySheet中定义新颜色
- 谁定义新操作员
- 未定义的符号'fixed_address_empty_string':带有protobuf的新张量流运算
- 新的C ,未定义的参考
- boost :: fibonacci_heap:带有比较器重新定义圆形定义错误的嵌套定义
- 宏,用于定义带有添加前缀的新宏
- 取消脱壳:使用模板在多行类型定义中添加一个尖括号后的新行
- C 通过Typedef定义新类型
- 通过在此指针上放置新位置重新初始化对象时未定义的行为
- 在 ss.clear() 之后使用 ss.str( " ") 用于新定义的字符串流
- 是标头文件中使用“新”定义的成员指针泄漏
- 自定义容器在保留空间时不必要地创建新元素实例
- 操作员新[]定义分解
- 为什么不调用复制构造函数将临时对象复制到新定义的对象