Declaring main as friend considered harmful?

2019-04-19 02:44发布

问题:

Discussion

I know that main can be a friend of a class:

#include <iostream>

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

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

LIVE DEMO

However, I feel that although this is perfectably allowable it conceals many dangers.

Questions

  1. Are there any valuable uses in making main a friend of a class?
  2. Are there any reasons that declaring main as friend of a class should be considered harmful?

回答1:

The choice whether to use or avoid a legal feature becomes moot if the feature is not, in fact, legal. I believe there's serious doubt surrounding this, because the Standard says

The function main shall not be used within a program.

There's already a question regarding whether befriending ::main() is in fact allowed, and you'll find more details in my answer there.



回答2:

The general frienship considerations should be identical as for any other functions.


However I see one possible danger:

C++ Standard :

  • Section § 11.3 (Friends)

A function first declared in a friend declaration has external linkage

  • Section § 3.6.1 (Main Function)

The linkage of main is implementation-defined

So if your implementation expects main() not to have external linkage and you first declare main() as a friend (as in your example), you contradict the standard.



回答3:

Ben already indicated that the draft C++ standard in section 3.6.1 Main function says:

The function main shall not be used within a program. [...]

but the term used is not defined and so it is not clear what the interpretation should be. Fortunately for us, we can find two pieces of evidence outside of SO that strongly indicates any use at all of main is ill-formed.

First we have this discussion in the undefined behaviour study group discussion list in the thread What does "The function main shall not be used within a program" mean?, this quote from here seems to sum up the sentiment:

C++98's mention of 'use' had a cross-reference to 3.2 [basic.def.odr]. C++11 no longer has the cross-reference, and was not changed to say 'odr-use', so I expect it means any use.

we have further evidence from original proposal: N3154 to fix Defect report 1109 would have changed 3.6.1 to:

The function main shall not be odr-used (3.2) within a program. ...

but was amended when accepted and we can see that the new proposal: N3214 changed to what we have today:

The function main shall not be used within a program