将main声明为友元是否有害?

14

讨论

我知道在C++中,main函数可以成为一个class的友元:

#include <iostream>

class foo {
  friend int main();
  int i = 4;
};

int main() {
  foo obj;
  std::cout << obj.i << std::endl;
}

实时演示

然而,我认为虽然这是完全允许的,但它隐藏了许多危险。

问题

  1. 使 main 成为类的友元是否有价值的用途?
  2. 声明将 main 作为类的友元应该被视为有害吗?

12
对于main函数来说,这并没有什么不同于其他函数。 - Wyzard
1
main 声明为友元本身并没有什么问题,问题通常在于背后的原因。 - OMGtechy
12
我感到悲伤,因为在我使用C++时,尽管我做了许多可怕的事情,但从未想到过这一点。 - Retired Ninja
1
观点:通常情况下,“友元”应该是最后的选择,只有在其他方式无法合理实现时才使用。应该给foo()放置一个适当的接口而不是将其设置为友元。 - keshlam
为什么这个问题得到了+8,但是几乎完全相同的问题却得到了-3? - M.M
显示剩余5条评论
3个回答

16
如果某个合法特性实际上并不合法,那么使用或避免使用该特性的选择变得毫无意义。我认为这方面存在严重的疑问,因为标准规定:

在程序中,不得使用函数 main

已经有一个关于是否允许将 ::main() 定为友元的问题,你可以在我的回答中找到更多细节。

好问题,最佳答案。虽然标准中似乎存在不可争辩的歧义。 - Nemo
所以如果我理解正确,主函数根本不应该声明为友元,或者至少要避免这样做? - 101010
我认为这个答案最适合这个问题 ;) - 101010
@40two:我绝对不会这样做。但通常,main()函数除了打开日志文件、安装异常处理程序之外,几乎什么都不做,然后调用一个特定于应用程序的启动函数。由于该启动函数非常普通,因此可以将其设置为友元函数。 - Ben Voigt

8
一般的友元函数注意事项应该与其他函数相同。
然而我看到一个可能的危险:
C++标准:
§ 11.3节 (Friends)部分
“在friend声明中首次声明的函数具有外部链接”
§ 3.6.1节 (Main Function)部分
“main的链接是实现定义的”
因此,如果您的实现希望 main() 没有外部链接,并且您首先将 main() 声明为友元(如您的示例中所示),则会违反标准。

如果你在使用 std::cout,那么你很可能不是在使用独立环境。 - Keith Thompson
1
更重要的是,你的程序是否需要定义一个 main 函数并不重要,重要的是你的程序是否提供了这个函数。而且,写下 friend int main(); 的人肯定完全掌控着这一点。 - Ben Voigt
@BenVoigt:我同意,我会删除那个注释。 - quantdev

4

Ben已经在第3.6.1主函数中指出,草案C++标准规定:

程序中不得使用main函数。[...]

但术语使用没有被定义,因此不清楚应该如何解释。幸运的是,我们可以在Stack Overflow以外找到两个强烈表明任何main使用都是非法的证据。

首先,在未定义行为研究组讨论列表中有这个讨论线程“The function main shall not be used within a program”是什么意思?这里的引用似乎总结了这种情绪:

C++98中“use”的提及有一个与3.2 [basic.def.odr]的交叉引用。 C++11不再具有交叉引用,并且未更改为说'odr-use',因此我认为它意味着任何使用。

我们还从原始提案:N3154和修复缺陷报告1109中获得了进一步的证据,将会更改3.6.1为:

在程序内,函数main不应被odr使用(3.2)。...

但是在被接受后进行了修改,我们可以看到新的提案:N3214变成了今天的形式:

程序中不得使用函数main


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接