我试图理解libspatialindex源代码。作为C ++的新手,我很难理解宏的概念。 库的C语言API包装器sidx_api.cc直接和间接包括许多标头,其中两个看似定义了同一宏,涉及到与动态库的接口,而没有'undef':
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
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
答案 0 :(得分:2)
如果重新定义它,则需要使用完全相同的预处理令牌列表来重新定义它。对于函数宏和对象宏都是如此。
当前定义为类对象宏的标识符不应由另一个#define预处理指令重新定义,除非第二个定义是类对象宏定义并且两个替换列表相同。< / p>
同样,当前定义为类似函数的宏的标识符不应由另一个#define预处理指令重新定义,除非第二个定义是具有相同编号和拼写的类似函数的宏定义参数,并且两个替换列表相同。
因此,此定义使用shall
。
现在,从4.Conformance p2
:
如果违反了约束外部出现的“应”或“不应当”的要求,则该行为是不确定的。
这是官方定义。因此,在重新定义宏符号之前,无需将宏符号从预处理器的环境中删除(使用#undef),就可以得到未定义的行为。
如果在C的某些实现中发现其他情况,则这不是标准化的。
正确地,您将在外部设置的某些条件的函数中插入不同的定义:
#if COND
#define M M1
#else
#define M M2
#endif
如果您使用一些重新定义它的库,请确保有一些宏可以设置COND
并使它们定义得很好。您需要学习如何使用该库。用不同的pp令牌列表重新定义它是无效的。
答案 1 :(得分:2)
这里没有非法重新定义宏。可以使用相同的定义多次定义一些,这是可以的。造成问题的是不完全相同的定义。
DLL本身始终使用由项目设置定义的SIDX_DLL_EXPORT
构建。无需定义此宏即可构建使用DLL的代码。
第二个标头是DLL的一部分。始终在定义SIDX_DLL_EXPORT
的情况下进行编译。因此,由它定义的宏(如果有)始终与第一个标头中定义的宏相同。这样相同的重新定义不构成问题。