使用前导下划线实际上会造成麻烦吗?

时间:2012-04-03 15:51:00

标签: c++ coding-style standards

C / C ++标准保留lead with an underscore (plus an uppercase letter if not in the global namespace) or contain two or more adjacent underscores的所有标识符。例如:

int _myGlobal;
namespace _mine
{
    void Im__outta__control() {}
    int _LivingDangerously;
}

但是,如果我不在乎呢?如果我决定危险地生活并使用这些“保留”标识符怎么办?我的生活会有多危险?

您是否曾经看到过因用户代码使用保留标识符而导致的编译器或链接器问题?

到目前为止,下面的答案相当于“为什么在这样做时违反规则可能会造成麻烦?”但是想象一下,你已经有了一系列违反规则的代码。在什么时候,违反规则的麻烦成本会超过重构代码以符合要求的成本?或者,如果程序员开发了一种需要狂野下划线的个人编码风格(例如,可能来自另一种语言)呢?假设改变他们的编码风格对他们来说或多或少是痛苦的,那么是什么能激发他们克服痛苦呢?

或者我可以反过来问同样的问题。什么是具体地 C / C ++库正在使用用户容易与之相冲突的保留字?他们是否声明可能会造成名称冲突的全局变量?功能?类?当然,每个图书馆都是不同的,但这种碰撞一般会如何表现出来?

我教过那些带着这些问题来找我的软件学生,而且我能告诉他们的是“这违反了规则。”这是一个迷信,挥手的答案。此外,在二十多年的C ++编程中,我从未看到因破坏保留字规则而导致的编译器或链接器错误。

面对任何规则的好怀疑论者都会问:“我为什么要关心?”所以:我为什么要关心?

4 个答案:

答案 0 :(得分:3)

我现在关心,因为我刚刚遇到了下划线,大型和旧代码库的故障,主要针对Windows并使用VS2005编译,但有些也是交叉编译到Linux。在分析更新gcc的更新时,为了便于语法检查,我在cygwin下重建了一些。我从一条线上得到了完全无法理解的错误(对我的小脑子):

template< size_t _N = 0 > class CSomeForwardRef;

这产生了如下错误:

error: expected ‘>’ before numeric constant

谷歌发现该错误https://svn.boost.org/trac/boost/ticket/2245https://svn.boost.org/trac/boost/ticket/7203两者都暗示了迷路#define可能会阻碍。果然,通过-E对预处理源进行检查,并通过包含路径进行搜索,发现了一些与位相关的.h(忘记了哪个)定义了_N。后来在同样的奥德赛中我遇到了与_L类似的问题。

编辑:与位不相关但与char相关:/usr/include/ctype.h - 以下是一些示例以及ctype.h如何使用它们:

#define _L      02
#define _N      04
.
.
.
#define isalpha(__c)    (__ctype_lookup(__c)&(_U|_L))
#define isupper(__c)    ((__ctype_lookup(__c)&(_U|_L))==_U)
#define islower(__c)    ((__ctype_lookup(__c)&(_U|_L))==_L)
#define isdigit(__c)    (__ctype_lookup(__c)&_N)
#define isxdigit(__c)   (__ctype_lookup(__c)&(_X|_N))

我将扫描所有下划线标识符的来源,并通过重命名我们在错误中创建的所有内容进行清除...

乔恩

答案 1 :(得分:2)

我的生活会有多危险?
在下次编译器升级时危险到足以破坏您的代码。

考虑未来,您的代码可能无法移植,并且将来可能会中断,因为您的实现中的未来增强版本可能与您使用的符号名称完全相同。

因为这个问题有一个小问题:“这可能是错的,但它有多么错,如果有错误”的味道,我认为 Murphy's law < / strong>相当恰当地回答:

  

“任何可能出错的地方都会出错(当你最不期待的时候)”。 [#]

[#] ()是我的发明而不是墨菲的。

答案 2 :(得分:1)

如果您尝试在实际存在冲突的地方构建代码,您将看到奇怪的构建错误,或者更糟糕的是,根本没有构建错误和不正确的运行时行为。

我看到有人使用保留的标识符,当它在新平台上导致构建问题时必须更改。

这不是那么可能,但没有理由这样做。

答案 3 :(得分:1)

结果可能会根据您将使用的具体编译器而有所不同。 关于“危险等级” - 每次你都会遇到错误 - 你将不得不怀疑它是来自你实施的逻辑还是来自你没有使用标准的事实。

但这不是全部......让我们假设有人告诉你:“它非常安全!” 所以,你可以毫无问题地做到这一点(仅假设...) 当你遇到一个错误时它会重新定义你的想法吗?或者你会想知道他是否有一个轻微的错误他错了? :)

所以,你看,无论你得到哪个答案,它都永远不会是一个好的答案。 (这让我真的像你的问题)