14

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?
Nemo
  • 70,042
  • 10
  • 116
  • 153
101010
  • 41,839
  • 11
  • 94
  • 168
  • 12
    This is really no different for `main` than for any other function. – Wyzard Jul 31 '14 at 22:35
  • 1
    There's nothing wrong with making `main` a friend as such, is the reasons behind it that are usually the problem. – OMGtechy Jul 31 '14 at 22:58
  • What "dangers" would those be, then? – Lightness Races in Orbit Jul 31 '14 at 23:20
  • The things we know, that aren't actually so... – Ben Voigt Jul 31 '14 at 23:21
  • 12
    I'm saddened that out of all of the horrible things I have done with C++ that this never occurred to me. – Retired Ninja Jul 31 '14 at 23:28
  • 1
    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. – keshlam Aug 01 '14 at 01:18
  • In my [answer here](http://stackoverflow.com/a/25298934/1708801) 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. – Shafik Yaghmour Aug 14 '14 at 15:02
  • @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. – 101010 Aug 14 '14 at 15:16
  • Howcome this has +8, but [almost exactly the same question](http://stackoverflow.com/questions/17048904/c-friend-as-main-in-class/) got -3 ? – M.M Aug 15 '14 at 03:04
  • @MattMcNabb Are you asking me? I didn't down-vote. Seems like a question for meta though. – 101010 Aug 15 '14 at 03:07

3 Answers3

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.

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Cute question; best answer. Although this does appear to be an indisputable ambiguity in the standard. – Nemo Aug 01 '14 at 01:50
  • So if I figured out correctly main shouldn't be declared friend at all, or at least avoid to do so? – 101010 Aug 01 '14 at 22:23
  • Plus I think that that answer fits best to this question ;) – 101010 Aug 01 '14 at 22:30
  • @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. – Ben Voigt Aug 01 '14 at 22:47
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.

quantdev
  • 23,517
  • 5
  • 55
  • 88
  • If you're using `std::cout`, you're probably not using a freestanding environment. – Keith Thompson Jul 31 '14 at 23:14
  • 1
    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. – Ben Voigt Jul 31 '14 at 23:15
  • @BenVoigt : I agree, I'll remove that note. – quantdev Jul 31 '14 at 23:25
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

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740