2017-06-13 27 views
5

有一条规则规定,不应在C或C++中定义或使用以下划线开头且后跟大写的标识符(例如, _Foo。这是因为这些标识符是由编译器保留的,因此可能会与某些编译器代码发生冲突并导致未定义的行为。由标识符以下划线开始导致的错误的现实示例

虽然这个规则是众所周知的,并被许多编码标准所采用,但我从来没有见过这种规则可以防止很多损害的真实生活情况。

有人知道一个违反此规则的真实案例吗?编辑:我正在谈论的代码,编译和链接很好,但由于这个显示意外的行为。

+3

如果存在名称冲突,那么应该在编译时检测到它,而不是在运行时检测到崩溃或其他UB。 –

+0

此外,还会保留任何位置包含两个连续下划线“__”的标识符名称。 –

+3

我在这里看到了几个问题,这些问题归结为一个系统头文件被跳过,因为程序员使用一个保留名称作为包含守护宏,并以系统头已使用的相同名称结束。不过,这不是一个容易搜索的问题。 –

回答

3

我工作的系统中,我们的应用程序代码有一个函数_bind()(用于绑定SQL语句中的主机变量),它没有变成静态的,因此它是公开的。

在一个O的一个版本(至少)/ S(我忘了,这一切都是在上个千年),该系统提供的功能_bind()这 - 惊喜,惊喜 - 有不同的接口,并做了一个不同作业(将套接字绑定到IP地址或其附近)。当应用程序代码与系统库链接时,系统库代码在尝试建立网络连接时最终调用_bind()函数。事情进展不顺利。

我们重命名了该函数或将其设为静态(或两者)并且问题消失了。现代共享库可以最大限度地减少发生这种事情的可能性。我们的代码使用了静态库,我认为O/S也使用了静态C库(很久以前!)。使用共享库会改变动态。

遗漏了大量模糊细节的伪信息 - 这种情况往往是一个暂时的问题,因为人们很快修复它们。

+0

'_bind'(不像例如'_Bind'或'__bind')不会被保留用于实现,这是一个OS函数,而不是一个标准函数。当包含操作系统头文件(WinDef.h任何人?)时,可能会发生各种不好的事情,这些都未包含在语言标准中。 –

+0

@ArneVogel标识符以下划线开始(不一定是后跟一个大写字母)在全局范围内保留(如果有内存服务的话)。 – Quentin

+0

以下划线和小写字母开头的应用程序标识符在文件范围内有效。 “这通常是通过使用前缀(通常是一个或多个下划线)完成的,C和C++在这方面值得注意:C99保留以两个下划线或下划线开头并带有大写字母的标识符,并进一步保留以在文件范围内使用一个下划线(在普通和标记空间中); [1]使用C++ 03进一步保留包含任何地方的双下划线的标识符“来源:https://en.wikipedia.org/wiki/Reserved_word #Reserved_ranges –

相关问题