如何避免来自 C 中的#define 的名称冲突? (或 C++)
how to avoid name conflicts coming from #define in C? (or C++)
这应该是一个非常基本的问题,我可以通过更改一些名称来避免这种情况,但我想也许我在这里遗漏了什么。
我已经为这个问题做了一个最简单的代码。
conv.h :
1 struct convpar_ {
2 int K;
3 } convpar_;
test.c :
1 #include <stdio.h>
2 #include "conv.h"
3
4 #define K 7
5
6 typedef struct convpar_ convpar;
7
8 void func1(convpar cp)
9 {
10 printf("cp.K = %d\n", cp.K);
11 }
12
13 main()
14 {
15 convpar cp = {K};
16
17 func1(cp);
18 }
如果我这样做 cc test.c -o test
,我会得到
cc test.c -o test
test.c: In function 'func1':
test.c:13: error: expected identifier before numeric constant
我知道这是因为我在第 4 行将字符 'K' 定义为 '7',这使得第 10 行在预处理后出现 printf("cp.7" = %d\n", cp.7);
。当我将 convpar_ 的成员 K 的名称更改为其他名称(例如 Ki)时,这个问题就消失了。
但有时,当我想定义一个常量时,它恰好是一个全局变量的名称或我在同一个文件中使用的结构的成员变量,我定义了变量in. 解决这个问题的正确方法是什么? (这也适用于 C++)
您无法解决这个问题,因为这是预处理器的目标:即时修改您的代码。解决方案是采用良好的编码习惯:不要将预处理器用于一般编程。此外,使用带有名称空间的命名规则。什么?将其命名为 CONVERSION_ID_K、CONVERSION_ID_L,依此类推。变量等使用小写
“如何避免命名冲突”的答案通常是:使用专有名称(而不是 K
)。此外,对于 C++,use namespaces and don't use using-directives i.e. using namespace
.
所以代码可以变成这样:
#include <iostream>
namespace MyNamespaceName {
struct MyStructName {
int myVariableName;
};
// probably even a member function, and struct->class, and member variable private
void MyFunctionName(MyStructName const& myStructInstanceName) {
std::cout << "clearStructInstanceName.clearVariableName = "
<< myStructInstanceName.myVariableName
<< '\n';
}
static constexpr auto myStaticVariableName = 7;
}
int main() {
auto const myStructInstanceName =
::MyNamespaceName::MyStructName {
::MyNamespaceName::myStaticVariableName
};
::MyNamespaceName::MyFunctionName(myStructInstanceName);
}
在大多数情况下,这可能有点矫枉过正,但在处理大型协作项目时,您确实需要保持全局命名空间干净,并考虑到会有其他人与您有相同的变量名。
这应该是一个非常基本的问题,我可以通过更改一些名称来避免这种情况,但我想也许我在这里遗漏了什么。
我已经为这个问题做了一个最简单的代码。
conv.h :
1 struct convpar_ {
2 int K;
3 } convpar_;
test.c :
1 #include <stdio.h>
2 #include "conv.h"
3
4 #define K 7
5
6 typedef struct convpar_ convpar;
7
8 void func1(convpar cp)
9 {
10 printf("cp.K = %d\n", cp.K);
11 }
12
13 main()
14 {
15 convpar cp = {K};
16
17 func1(cp);
18 }
如果我这样做 cc test.c -o test
,我会得到
cc test.c -o test
test.c: In function 'func1':
test.c:13: error: expected identifier before numeric constant
我知道这是因为我在第 4 行将字符 'K' 定义为 '7',这使得第 10 行在预处理后出现 printf("cp.7" = %d\n", cp.7);
。当我将 convpar_ 的成员 K 的名称更改为其他名称(例如 Ki)时,这个问题就消失了。
但有时,当我想定义一个常量时,它恰好是一个全局变量的名称或我在同一个文件中使用的结构的成员变量,我定义了变量in. 解决这个问题的正确方法是什么? (这也适用于 C++)
您无法解决这个问题,因为这是预处理器的目标:即时修改您的代码。解决方案是采用良好的编码习惯:不要将预处理器用于一般编程。此外,使用带有名称空间的命名规则。什么?将其命名为 CONVERSION_ID_K、CONVERSION_ID_L,依此类推。变量等使用小写
“如何避免命名冲突”的答案通常是:使用专有名称(而不是 K
)。此外,对于 C++,use namespaces and don't use using-directives i.e. using namespace
.
所以代码可以变成这样:
#include <iostream>
namespace MyNamespaceName {
struct MyStructName {
int myVariableName;
};
// probably even a member function, and struct->class, and member variable private
void MyFunctionName(MyStructName const& myStructInstanceName) {
std::cout << "clearStructInstanceName.clearVariableName = "
<< myStructInstanceName.myVariableName
<< '\n';
}
static constexpr auto myStaticVariableName = 7;
}
int main() {
auto const myStructInstanceName =
::MyNamespaceName::MyStructName {
::MyNamespaceName::myStaticVariableName
};
::MyNamespaceName::MyFunctionName(myStructInstanceName);
}
在大多数情况下,这可能有点矫枉过正,但在处理大型协作项目时,您确实需要保持全局命名空间干净,并考虑到会有其他人与您有相同的变量名。