如何使替换 c 函数的变量名成为错误?



我的代码神秘地停止工作。我发现我不小心在我的main.cpp中写了int listen;,并在我的network.cpp中使用了 listen,这似乎试图将 int 作为函数而不是 C 函数调用。更改变量的名称(或使其静态(解决了该问题。

是否有任何警告我可以打开,这样我就不会再被这样的事情抓住了?我发现的最接近的是建议我将变量设置为静态的东西,如果它们不需要是 extern

此处代码

//a.cpp
#include<cstdio>
int main() { puts("Hello"); }

//b.cpp
int puts;

您拥有的是 ODR 违规。在两个不同的 TU 中,puts有两种不同的定义。标准(N4713 - C++17草案(说

§6.2 单定义规则

    每个
  1. 程序应只包含该程序中使用的每个非内联函数或变量的一个定义 在丢弃的语句 (9.4.1( 之外;无需诊断。

这当然是C++的。C 也有类似的规则。

由于"无需诊断",编译器链不需要为代码发出错误或警告。

据我所知,流行的编译器上没有标志来发出 ODR 违规的错误/警告。这是因为编译器如何优化其解析。请参阅此精彩答案以获取更多信息。

您可以遵循一些好的做法来最大程度地减少此类错误:

  • 在C++中,不要在全局空间声明符号。使用命名空间。

  • 在 C 中,您可以在全局变量前面加上g_。如果你写一个库,你也会添加一个库前缀到所有全局。

  • (正如你所建议的(使仅在其 TU 中使用的符号具有内部链接(将它们声明static或在未命名的命名空间中(。

  • 使用更有意义、更相关的名称。 例如,您可以将其命名为server_is_listening而不是listen(或类似的东西,使其使用有意义(。

-Werror=missing-variable-declarations可能会有所帮助。它强制您使用 static 来避免此问题或在其他地方声明变量(即标头(。在包含 C 函数的任何文件中包含该标头将导致错误,从而导致另一个捕获错误的机会

最新更新