是否可以在不使用"undef"的情况下重新定义宏?

Is it possible to redefine a macro without the use of ‘undef’?

本文关键字:quot 新定义 定义 情况下 undef 是否      更新时间:2023-10-16

我试图理解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 令牌列表重新定义它是无效的。