弃用 static 关键字...不再?

Posted

技术标签:

【中文标题】弃用 static 关键字...不再?【英文标题】:Deprecation of the static keyword... no more? 【发布时间】:2011-06-11 05:25:15 【问题描述】:

在 C++ 中,可以在翻译单元中使用 static 关键字来影响符号(变量或函数声明)的可见性。

在 n3092 中,这已被弃用:

附录 D.2 [depr.static] 在命名空间范围内声明对象时,不推荐使用 static 关键字(参见 3.3.6)。

在 n3225 中,这已被删除。

only article I could find 有点不正式。

它确实强调了,为了与 C 的兼容性(以及将 C 程序编译为 C++ 的能力),弃用是令人讨厌的。但是,将 C 程序直接编译为 C++ 可能已经是一种令人沮丧的体验,因此我不确定是否值得考虑。

有谁知道为什么改了?

【问题讨论】:

你在 C 的命名空间范围内声明对象? 嘿,谢谢,找到了在哪里获得它。试图删除评论,但你在那里打败了我。 问题来自***.com/questions/4725204/… 这也让 C++ 委员会有机会在下一版本的标准中取消不赞成的某些内容:-) ***.com/questions/4422507/… 【参考方案1】:

1012. Undeprecating static 下的 C++ Standard Core Language Defect Reports and Accepted Issues, Revision 94 中,他们指出:

尽管 7.3.1.1 [namespace.unnamed] 声明不推荐使用 static 关键字在命名空间范围内声明变量,因为未命名命名空间提供了更好的替代方案,但该功能不太可能在任何时候被删除可预见的未来。

这基本上是说弃用static 并没有真正的意义。它永远不会从 C++ 中删除。它仍然很有用,因为如果您只想声明具有内部链接的函数或对象,则不需要使用未命名的 namespace 所需的样板代码。

【讨论】:

好吧,似乎弃用会鼓励人们使用未命名的命名空间,这将是一件好事。 @nbt:因为你不能使用静态符号作为模板参数,而且因为许多新手会发现静态更容易使用,然后不想尝试 和 等。只是一个快速的想法。 " 因为您不需要带有未命名命名空间的样板代码"?什么“样板代码”?超出“namespace ”和“”的内容? @towi 与 static 相比,有两个额外的大括号,并且在许多编码样式中,您将编写至少 3 行代码来缩进声明。 我喜欢将辅助函数、全局变量等声明为静态并尽可能接近它们的用法。为此目的,命名空间 语法很难看,而“静态”很好。其他人喜欢把他们所有的帮助内容放在文件的顶部。命名空间 语法在那里更有用。所以这真的是风格问题。它们最终都是等价的。【参考方案2】:

我会尝试回答你的问题,虽然这是一个老问题,而且看起来不是很重要(它确实不是很重要本身),并且得到了很好的答案已经。我想回答这个问题的原因是,当语言基于现有语言时,它与标准演变和语言设计的基本问题有关:什么时候应该以不兼容的方式弃用、删除或更改语言特性? em>

在 C++ 中,可以在翻译单元中使用 static 关键字来影响符号(变量或函数声明)的可见性。

实际上是链接。

在 n3092 中,这已被弃用:

弃用表示:

意图在未来移除某些功能;这并不意味着不推荐使用的功能将在下一个标准版本中删除,或者它们必须“很快”删除,或者根本不删除。未弃用的功能可能会在下一个标准版本中删除。 正式尝试不鼓励使用它

后一点很重要。虽然从来没有正式承诺你的程序不会被破坏,有时是默默地,按照下一个标准,委员会应该尽量避免破坏“合理”的代码。弃用应该告诉程序员依赖某些特性是不合理的

它确实强调了,为了与 C 的兼容性(以及将 C 程序编译为 C++ 的能力),弃用是令人讨厌的。但是,将 C 程序直接编译为 C++ 可能已经是一种令人沮丧的体验,因此我不确定是否值得考虑。

保留 C/C++ 通用子集非常重要,尤其是对于头文件。当然,static 全局声明是带有内部链接的符号声明,这在头文件中不是很有用。

但问题不仅仅是与 C 的兼容性,而是与现有 C++ 的兼容性:有大量现有的有效 C++ 程序使用 static 全局声明。这段代码不仅在形式上合法,而且是合理的,因为它按照预期的使用方式使用了定义明确的语言特性

仅仅因为现在有一种“更好的方式”(根据某些人的说法)来做某事并不会使以旧方式编写的程序“糟糕”或“不合理”。在 C 和 C++ 社区中都很好地理解在全局范围内声明对象和函数时使用 static 关键字的能力,并且最常正确使用。

以类似的方式,我不会仅仅因为“C 风格的转换很糟糕”而将 C 风格的转换为 double 更改为 static_cast<double>,因为 static_cast<double> 增加了零信息和零安全性。

每当发明一种新的做某事的方法时,所有程序员都会急于重写他们现有的定义良好的工作代码,这种想法简直太疯狂了。 如果你想删除所有继承的 C 丑陋和问题,你不改变 C++,你发明了一种新的编程语言。 一半删除 static 的使用几乎不会让 C++ 减少 C-ugly .

代码更改需要一个理由,“旧的就是坏的”绝不是代码更改的理由。

重大的语言更改需要非常充分的理由。让语言稍微简单一点绝不是做出重大改变的理由。

static 不好的原因非常薄弱,甚至不清楚为什么不同时弃用对象和函数声明 - 对它们进行不同的处理几乎不会使 C++ 更简单或更正交。

所以,真的,这是一个悲伤的故事。不是因为它产生的实际后果:它的实际后果完全为零。但因为这表明 ISO 委员会明显缺乏常识

【讨论】:

正如您自己指出的那样,弃用它的目的是阻止它的使用。然而,你并没有争论不鼓励使用它是错误的。我当然希望没有人鼓励人们在匿名命名空间上使用命名空间范围的静态声明。除非他们特别需要交叉编译 C。 我不太关心使用全局范围 static 或匿名命名空间的人,我既不鼓励也不反对。我的观点是,如果你真的想阻止人们使用匿名命名空间,你必须给他们很好的论据。在实践中,我相信在大多数实现中,在未命名命名空间中声明的实体是使用随机名称导出的符号,因此会增大导出表。声明为static、OTOH 的实体不会以任何方式导出。因此,许多人根据这一观察选择使用static "正如您自己指出的那样,弃用它的目的是阻止它的使用。" 阻止它使用的目的是它可能有一天会消失。我的观点是 namespace-scope static 永远不会消失,因此弃用它是错误的。 “但你没有提出不鼓励使用它是错误的论据。” 我没有看到任何令人信服的论据表明使用命名空间范围static 是“错误的”。仅仅为了阻止它的使用而弃用它是错误的,因为没有人真正相信它会消失,而且它并不能让人们相信使用它是“错误的”。 我当然希望没有人鼓励人们在匿名命名空间上使用命名空间范围的静态声明。”有些人认为static 更好,并鼓励它使用匿名命名空间。我的观点不是任何一个都比另一个好。我的观点是 1)没有任何功能(static,匿名名称空间)是“错误的”。 2) 弃用一个有用的、定义明确的、广泛使用的、永远不会成功的特性是错误的。这样做会降低 C++ 委员会的可信度(而且已经很低了)。 整个语言将“有一天消失”。让我们弃用 C++。【参考方案3】:

无论是否已弃用,删除此语言功能都会破坏现有代码并惹恼人们。

整个静态弃用事情只是“匿名命名空间比静态更好”和“引用是更好的指针”的一厢情愿。哈哈。

【讨论】:

“引用是更好的指针”?不,智能指针是更智能的指针。您不能对从堆、错误、空闲存储区分配的内存使用引用。 对不起,我忘了用讽刺的笑脸结束它。 @Dan:这正是这个答案所说的:“一厢情愿”沿着类似的错误思路。未命名的命名空间是一项重要功能,就像 global-scope-static 一样,尽管原因略有不同,尽管它们在适用性上有一些重叠。 @Fred, @Maxim:如果我误解了,或者我的记忆有问题,我很抱歉。但是我没有将“引用是更好的指针”归类为等同于“匿名命名空间比静态更好”作为一厢情愿的情况。我很清楚使后者坚持下去的尝试,但我不记得有人认真提议用引用替换指针。再说一次,也许是我自己缺乏意识。 @DanBreslau: char* foo = new char; char& ref = *foo; 仅仅因为最初给你一个指针,就说明你使用引用的能力没有任何意义。

以上是关于弃用 static 关键字...不再?的主要内容,如果未能解决你的问题,请参考以下文章

static关键字

static关键字

03_5_static关键字

java之关键字static

static关键字静态代码块

Java-13,static关键字