Declaring main as friend considered harmful?
Asked Answered
P

4

15

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?
Publias answered 31/7, 2014 at 22:33 Comment(10)
This is really no different for main than for any other function.Tinsel
There's nothing wrong with making main a friend as such, is the reasons behind it that are usually the problem.Katz
What "dangers" would those be, then?Snakebite
The things we know, that aren't actually so...Antecedent
I'm saddened that out of all of the horrible things I have done with C++ that this never occurred to me.Harry
Opinion: Generally, "friend" should be a last resort if you really can't make it work reasonably any other way. Put a proper interface on foo() rather than friending it.Peptic
In my answer here I found a lot of details as to what any use of main means and the interpretation seems to mean any use period. I am debating whether to add an answer but will definitely do so if you strongly feel the new details I found are worth adding.Doelling
@ShafikYaghmour Yes, go ahead. IMHO the 2 questions are quite related as to the contradiction they exhibit in contrast to the standard (i.e., "The function main shall not be used within a program"). Consequently, any arguments that support the claim main shall not be used anywhere else in the program are welcome.Publias
Howcome this has +8, but almost exactly the same question got -3 ?Yield
@MattMcNabb Are you asking me? I didn't down-vote. Seems like a question for meta though.Publias
A
16

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.

Antecedent answered 31/7, 2014 at 23:14 Comment(4)
Cute question; best answer. Although this does appear to be an indisputable ambiguity in the standard.Phytology
So if I figured out correctly main shouldn't be declared friend at all, or at least avoid to do so?Publias
Plus I think that that answer fits best to this question ;)Publias
@40two: I definitely wouldn't do it. But then, most often a main() function does little besides opening a log file, maybe install an exception handler, and then call an application-specific startup function. Since that startup function is quite ordinary, it can be a friend.Antecedent
R
8

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.

Rate answered 31/7, 2014 at 23:0 Comment(3)
If you're using std::cout, you're probably not using a freestanding environment.Marcos
More to the point, it doesn't matter one whit whether your program is required to define a main function, it only matters whether your program does provide one, and surely whoever is writing friend int main(); is fully in control of that.Antecedent
@BenVoigt : I agree, I'll remove that note.Rate
D
4

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

Doelling answered 15/8, 2014 at 2:42 Comment(0)
P
1

With CWG Issue 2811, the wording of [basic.start.main] p3 was changed to:

The function main shall not be named by an expression.

A friend declaration is not an expression, so it would be fine to make main a friend, would it not be for the issues pointed out in @quantdev's answer.

Even historically, it was illegal to "use" main, which had a strong connotation of odr-use. A friend declaration wouldn't be odr-use either.

Polyamide answered 24/4 at 21:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.