70

I was reading the C++ FAQs and I noticed one sentence.

main() cannot be inline.

Why is this?

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
jon
  • 615
  • 5
  • 4
  • 56
    More interesting question for me: why somebody want to try to inline it? – RiaD Aug 08 '11 at 11:59
  • 7
    To inline your main in os kernel code? :) – Mehran Aug 08 '11 at 13:08
  • 21
    This is silly, right? Inlining is where the contents of a method are placed into the calling code directly, rather than being a separate method. That means you'd need to recompile your OS to have your `main` function compiled into it. So the answer is, because you can't recompile your OS? – Kieren Johnstone Aug 08 '11 at 15:15
  • 3
    @Kieren: That's why you don't ever want to physically inline the function. It's not strictly the same as why the function _shall not_ be marked `inline` (which, remember, is just a hint!). – Lightness Races in Orbit Aug 08 '11 at 17:37
  • 5
    Putting this in a C++ FAQ seems kinda silly to me because why would you want to do that. That's like when you see a warning label for a situation that doesn't make any sense. – jhocking Aug 08 '11 at 17:42
  • 1
    It could be in the FAQ just to make people think about what inlining actually is to avoid people trying to optimize code by inlining main and such. Personally I would see it as better to be sure to point out that it's just hints to the compiler. – Hobblin Aug 08 '11 at 19:26
  • 1
    I disagree with the close voters, but why does this question have ~40 upvotes? – Chris Lutz Aug 10 '11 at 07:17
  • 1
    good question, it shouldn't be closed – Tebe Aug 10 '11 at 13:06
  • 2
    it is food for thought that people here think debate is not constructive. it is true that SO actively discourages debate. and it seems to me that that attracts people who do not understand the value of debate. this question is a very clear example that lack of proper facilities for debate fosters misconceptions. i.e., a technically incorrect answer selected as solution, with 80+ votes. – Cheers and hth. - Alf Aug 10 '11 at 15:44
  • Related: [Restrictions on main() function](http://stackoverflow.com/questions/4144030/restrictions-on-the-main-function) – Armen Tsirunyan Aug 13 '11 at 06:34

17 Answers17

105

In C++ it is not legal to call the main function in your code, so there'd be no way it could ever be inlined.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • 17
    This *is* the reason, think about it. – Tamás Szelei Aug 08 '11 at 11:04
  • 17
    @iammilind: `*static_cast(0) = 10` compiles too, and that does not mean that it is correct... as is the case with any ODR violation, and so many other things... the fact that it compiles does not mean that it is a legal program. – David Rodríguez - dribeas Aug 08 '11 at 11:20
  • 5
    @iammilind: The statement "it compiles" requires context. Because it's certainly not required to by the standard to compile, and it in fact does not compile in all cases. – Benjamin Lindley Aug 08 '11 at 11:20
  • 4
    *sigh* for anyone wondering, op asked in a comment "for a reason" then I commented answering him, but he deleted his. Not cool, op. – Tamás Szelei Aug 08 '11 at 11:43
  • 1
    @iammilind: Just for the record that code does not compile on g++ with `-pedantic-errors`. – sepp2k Aug 08 '11 at 11:49
  • 1
    @iammilind : http://stackoverflow.com/questions/5177167/why-does-my-c-compiler-allow-recursive-calls-to-main/5177289#5177289 – Prasoon Saurav Aug 08 '11 at 11:54
  • 3
    -1 "There'd be no way it could ever be inlined" is incorrect. Plus, it's only the smallest part of the reason, a quite irrelevant part. :-) – Cheers and hth. - Alf Aug 08 '11 at 12:12
  • 1
    @Alf: How is it incorrect? If I'm not allowed to call a function, then where could it be inlined? – sepp2k Aug 08 '11 at 12:15
  • 4
    @sepp2k: see my answer. but in short, machine code inlining is irrelevant to the question, but technically it can be inlined in the call from the runtime library, in 2 different ways. it's not done, however, since there's no advantage. :-) – Cheers and hth. - Alf Aug 08 '11 at 12:19
  • @sepp2k: The function code being physically inlined is not the same as the function being marked `inline`. – Lightness Races in Orbit Aug 08 '11 at 12:21
  • @Alf P. Steinbach, actually it can't be inlined in the runtime library because the runtime library is compiled separately from your application and does not #include your header with the inline definition. – psusi Aug 08 '11 at 14:32
  • @psusi: you're wrong and it has already been discussed. please read before asserting. – Cheers and hth. - Alf Aug 08 '11 at 14:33
  • @psusi: The linker can do inlining in certain situations. – Lightness Races in Orbit Aug 08 '11 at 16:44
  • @Tomalak Geret'kal, huh? The linker doesn't generate asm. That's why you have to put the definition of an inline in the header; so the compiler can see the definition and generate the asm inline. – psusi Aug 08 '11 at 18:21
  • @psusi: http://stackoverflow.com/questions/5987020/can-the-linker-inline-functions – Lightness Races in Orbit Aug 08 '11 at 21:21
  • @iammilind: If you call `main()` from `main()`, then this call definitely cannot be inlined... (at least not recursively) – Chris Lercher Aug 09 '11 at 20:53
  • As to why main() cannot be called, you can see [this question](http://stackoverflow.com/questions/4144030/restrictions-on-the-main-function) – Armen Tsirunyan Aug 13 '11 at 06:35
66

Because the standard says so:

[2003: 3.6.1/3]: The function main shall not be used (3.2) within a program. The linkage (3.5) of main is implementation-defined. A program that declares main to be inline or static is ill-formed. The name main is not otherwise reserved. [Example: member functions, classes, and enumerations can be called main, as can entities in other namespaces. ]

And why does it say so? Because it's trying to leave as much about the implementation of main to the individual .. well, implementation .. as is possible, and doesn't want to limit implementations by requiring that inline be valid here when it arguably has no practical benefit.


My friend on the committee confirmed this:

There's no reason why an inline main() wouldn't work, per se. [..] I could have a C++ interpreter that can invoke inlined main(). [..] [But] inline/static main() are forbidden in order to hopefully avoid confusion. I find it hard to imagine that the rationale would be anything additional to what's already been said in [this Q&A].


BTW, don't confuse the inline hint keyword with actually inlining functions. You can mark a function inline and it may not be physically inlined.

So, even if it were true that main "cannot be inlined" (and strictly speaking it is not true, though inlining main would be rather awkward and pointless as explained in other answers), it could theoretically still support the inline hint keyword just fine.

It doesn't for the reason stated above, and in litb's answer: it would complicate matters for no real benefit.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 4
    +1 for quoting the standard. However, this may not fully answer the O.P.'s question; so far, I haven't seen any justifiable answer against, except your post. – Thomas Matthews Aug 08 '11 at 16:02
  • @Thomas: The rationale I gave is pretty much the same as that found in the other answers, just with less detail as to _why_ there may be no practical benefit. :) – Lightness Races in Orbit Aug 08 '11 at 16:43
  • re "doesn't want to limit implementations by requiring that inline be valid", supporting `inline` for `main`is trivial since it can just be ignored, hence that does not limit any implementation, hence, this possible reason for the standard's prohibition does not hold water. sorry. but i don't have more to offer than in my answer, that it doesn't make sense to have `inline` (and on that we agree I think). – Cheers and hth. - Alf Jan 09 '14 at 05:41
  • @Cheersandhth.-Alf: It would sort of imply that you can define `main` in multiple TUs if the definitions are all lexically identical (amongst other restrictions) which just makes so little sense as to be worth prohibiting. – Lightness Races in Orbit Jan 09 '14 at 12:50
  • @LightnessRacesinOrbit: I see what you mean but... `main` being a function implies that it can be called from user code (except that's not allowed), that its address can be taken (except that's not allowed), that it's UB to flow off the end (except that that's specifically supported and well-defined), that any call must match the formal argument list (except that in practice the same runtime library call invokes it regardless of formal argument list), so on. I.e., since `main` is very special the usual implications are easily defined away. It was a good idea though. :) But didn't pan out. :( – Cheers and hth. - Alf Jan 09 '14 at 19:45
  • On the contrary, you just disproved your own point by showing how many special rules exist for `main` that don't really _need_ to exist. – Lightness Races in Orbit Jan 09 '14 at 19:50
  • @LightnessRacesinOrbit: What does it mean that linkage of main is implementation-defined? Why it is implementation-defined? – Destructor Jun 07 '15 at 07:58
  • 2
    @meet: Why should it not be? Unlike other functions that the user defines, `main` has a meaning that must interact with the implementation's runtime and with the host operating system (because it's the program entrypoint), so it makes no sense for a committee of people to mandate too much about it. Recall that the linkage of other functions is user-defined so, in fact, the standard _is_ constraining `main` slightly here, by saying "listen to your compiler vendor because _they_ get to choose this one not you". :) – Lightness Races in Orbit Jun 07 '15 at 13:51
27

The C runtime library needs to find this symbol in order to "know" which function to run.

Ringding
  • 2,856
  • 17
  • 10
  • Does this mean that linkers can't find the symbols for other inlined functions? – Thomas Matthews Aug 08 '11 at 15:59
  • @Thomas Matthews: Depends on how smart the linker is. Generally speaking, no, linkers are not aware of inline functions; they have internal linkage. More modern linkers are a bit smarter in that they'll try to do whole program optimizations, and that's a whole different ballgame. :) – Billy ONeal Aug 08 '11 at 16:03
  • I'd also say that in C runtime there is (usually) an explicit `call` to the `main()` function, and it is almost always linked dynamically. So there is just no way it could work *in a typical case*. – Catherine Aug 08 '11 at 18:37
17

You cannot directly call main() (it's forbidden in c++), so there is no point of inlining it.

Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
14

Usually main() is called from systems init() function. Thus, it is needed that there can be exactly one definition for main().

Now, if we can inline the main() function and include in a header file then, for every translation unit there will be different definition for main(). Which is not allowed. You can declare main() in a namespace and inline it. But not the global main().

iammilind
  • 68,093
  • 33
  • 169
  • 336
10

firstly you must understand how work function with inline

example:

 inline void f() {
     int a  = 3;
     a += 3;
     cout << a;
 }

 int main() {
      f();
      return 0;
 }

will look like to the compiler as:

 int main() {
        int a  = 3;
        a += 3;
        cout << a;
        return 0;
 }

looking at this example, how do you want to make main inline? This method is inline immediately.

nirmus
  • 4,913
  • 9
  • 31
  • 50
7

Others have remarked that an invocation of main can not meaningfully be inlined at the machine code level. That's rubbish. It would require a bit of help from the linker (like global optimization) or else per-application recompilation of a bit of the runtime library, but it's quite doable, no technical problem here.

However, the hinting effect of inline, that calls should preferably be inlined, is irrelevant for a function that is only called once and at the top level of control, as main is.

The only guaranteed effect of inline is to allow an external linkage function to be defined (identically) in two or more translation units, i.e. affecting the One Definition Rule.

As a practical matter this allows the definition to be placed in a header file, and placing it in a header file is a also practically necessary to guarantee identical definitions.

That does not make sense for main, so there is no reason for main to be inline.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 1
    "There is no reason for `main` to be `inline`" is compelling, but not a direct explanation as why it's been made so that it _cannot_ be marked `inline`. – Lightness Races in Orbit Aug 08 '11 at 12:22
  • I have explained the same thing in my answer. However, yours is more elaborate. – iammilind Aug 08 '11 at 12:29
  • Well, I think, the standard does not go out of its way to support things nobody will ever use. But I think in addition, the description of `main` is not perfect. For example, I have always thought and still do think that the "after the first statement of main" bit is fundamentally wrong. But I have never seen it discussed anywhere. Maybe, it's just my imperfect understanding of English... – Cheers and hth. - Alf Aug 08 '11 at 13:47
  • 1
    @anonymous downvoters: please explain your reasons for downvoting, so that others can benefit from your insights (he he). – Cheers and hth. - Alf Aug 10 '11 at 11:14
  • @Alf: Along similar lines, the standard does not go out of its way to prohibit things unless there's a proper reason for it. :) – Lightness Races in Orbit Aug 11 '11 at 00:13
  • I disagree that it does not make sense for main to be defined in a header. There are quite a few libraries/frameworks that include an implementation of `main` that when linked, invokes your code indirectly. A priori, I don't see a significant difference between that and defining main in a header. – Tim Seguine Oct 06 '16 at 20:12
  • @TimSeguine: I agree that it can make sense to place `main` in a header, intended to be included in one translation unit only. As a matter fact I've done that ([example at github](https://github.com/alf-p-steinbach/cppx/blob/master/source_code/cppx/basics_and_main.hpp)). But it does not then make sense to guarantee identical definitions in multiple translation units. Nor does any other reason for `inline` then apply, as I see it. – Cheers and hth. - Alf Oct 06 '16 at 22:54
  • Something like guaranteed COMDAT folding could be useful. But since the standard doesn't guarantee that, I have to concede you are correct. – Tim Seguine Oct 07 '16 at 11:28
  • The prohibition of main being inline contributed to the fact that newer embedded systems use an entry point with different name. E.g. loop() or start(). Because there compiler inherently inlines code of program into kernel's image. – Swift - Friday Pie Nov 01 '18 at 13:28
7

The C++ standard says that the main function cannot be inlined, per @Tomalak Geret'kal's reply. This response discusses possibility of inlining of the main function, were the restriction in the Standard removed.

Definition of Inline
The inline keyword is a suggestion to the compiler to paste the contents of the function in-situ. One intent is to remove the overhead present in calling and returning from a function (subroutine).

An important situation of inlining is the case where there is a pointer to the function. In this case, there must be at least one static copy of the function. In this case, the linker can resolve "external linkages" of the inlined function because there is one static version.

Important to note that the compiler and linker determine whether or not to paste the contents or calls a single instance of the function.

Also of note, functions that are not tagged by the programmer may also be inlined by the compiler.

Inlining the main function
Since there is only one invocation of main allowed, how it is linked is up to the compiler. Single instances of inline functions are allowed by the Standard. The compiler is allowed to convert an inlined function into a function call to a single instance. So the compiler would ignore an inline suggestion for the main function.

The compiler and linker would have to insure that only one instance of the inlined main function exists. This where the tricky part comes in, especially with external linkage. One process for ensuring one instance is to leave information that a translation has a 'main' function whether or not it is inlined. Note: When a call to an inline function is made, the compiler is allowed to remove the function from the symbol tables for external linkage, since the idea is that the function won't be called by external functions.

Summary
Technically, there is nothing preventing the main function from being inlined. The machinery already exists for converting inlined functions into single instances and for identifying multiple instances of a function. When there is a pointer to an inlined function, a single instance of a function is made, so it has an address. This machinery would satisfy the Run-Time Library requirements for main having an address. In the case of inline for the main function, it would be ignored but there should not be any reason to prevent this syntax (except confusing people). After all, there are already syntax cases that are redundant, such as declaring a parameter that is passed by value (copy) as const.

"That's just my opinion, I could be wrong." -- Dennis Miller, comedian.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
6

You can only define main once. So putting inline would not serve any purpose - inline only has a significant purpose on functions you can define multiple times in a program (all definitions will be treated as if there were only one definition and all definitions are required to be the same).

Because inline functions can be defined multiple times in a program, and inline also serves the purpose of making calls to an inline-marked function as fast as possible, the Standard requires inline functions to be defined in every translation unit in which it is used. So compilers will usually throw away the definition of a function if it is inline and the function wasn't used by the code in the current translation unit. To do that for main would be entirely wrong, which goes to show that inline and the semantics main has is entirely incompatible.

Note that the question in your title "Why main() in C++ cannot be inlined?" and the statement you quote out of the Standard concern different things. You are asking whether the function can be inlined, which commonly is understood to insert the code of a called function completely or partially into the calling function. Just marking a function inline doesn't imply inlining that function at all. It's entirely the compiler's decision, and of course if you never call main (and you cannot do so) then there is nothing to be inlined.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 1
    The terminology in the standard is a bit awkward, but while it's true that an inline function can be multiply defined, all of the definitions must be identical, and the behavior of the code must be as if it were only defined once. (The fact that an inline function must be defined in every translation unit that uses it is a bit more problematic. The only translation unit which will use it is one you didn't write, delivered already compiled with your system.) – James Kanze Aug 08 '11 at 17:50
  • 2
    @James: re the parenthetical remark, yeah, but the Implementation is allowed to do any magic it wants. – Cheers and hth. - Alf Aug 08 '11 at 21:51
  • @Alf Agreed, as long as the observable behavior is maintained. But the standard doesn't require any such magic; allowing `main` to be inline would require it. Historically, C++ didn't like requiring magic. (But that was before templates.) – James Kanze Aug 09 '11 at 09:22
3

If you linked statically to the CRT and enabled some link-time compilation-inlining (like MSVC has) it might be possible to inline it.

But it doesn't really make sense. It will be called once and that function call-overhead is practically naught compared to everything else that is done before the first line in main executes.

...

Aaand, it is an easy way to force the symbol to appear only once in your executable. :)

Macke
  • 24,812
  • 7
  • 82
  • 118
2

There are a number of basic reasons. Basically, main is called from the basic initialization routine of the runtime, and only from there. That code was (obviously) compiled without knowing that your main was inlined. Modern compiler technology is capable of inlining across module boundaries, but it's an advanced feature, not supported by many older compilers. And of course, the benefits of inlining are only present when a function is called very frequently; by definition, main will be called exactly once, no more, no less.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
2

I see the standard says so, but the real practical answer would be as simple as stating that the runtime added to every C and C++ program has to call to some point in the executable. That function should have an external symbol (and address when running) so that the linker can find it to be called at the beginning of execution. Hence you cannot declare it as inline, because inlined the compiler wouldn't generate an external symbol for it.

Diego Sevilla
  • 28,636
  • 4
  • 59
  • 87
1

Since its the main() function, which starts the execution, when the code gets compiled to binary, everything is in the main() itself. so you can say, it already inlined!

And yes, its illegal to use inline for your C++ program, that's more about a syntax!

linuxeasy
  • 6,269
  • 7
  • 33
  • 40
1

For most combinations of compiler/archetecture, the main() function in the source becomes a reasonably normal function in the final binary. This is only because it's convenient on those archetectures, not because the standard says it must be so.

On memory constrained archetectures, many compilers, ones which produce a flat binary (like intex hex format) instead of a dynamic linker friendly container (like elf or xcoff), optimize all of the boilerplate away, since it would just be bloat. Some architectures don't support function calls at all (only a limited subset of C++ is possible on these platforms.)

In order to support the widest variety of such architectures and build environments, the standard elects keep the semantics of main() as open as possible, so that the compiler can do what's right for the widest variety of platforms. That means that many features available in the language as a whole cannot apply to the startup and shutdown of the application itself.

If you need something like an inline main() (or reentrancy, or any fancy feature) you can of course call the main function something else:

inline int myMain(int argc, char **argv) { /* whatever */ }
int main(int argc, char **argv) { return myMain(argc, argv); }
SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
1

Inline functions are having static scope by-default. It means if we declare main() as inline, it's scope will be limited to the file where it is defined. Yet, the C start-up library (provided by compiler vendor) needs 'main' to be a global symbol. There are some compilers that allow to modify entry point function (e.g. main) using linker flags.

Venki
  • 149
  • 2
  • 6
0

inline functions don't usually have an address, so there is no portable way to call main, main() needs an address on which the init code can jump into. Inlined functions are meant to be stuck into the calling function, if main is inlined, it should be inlined into the init code of the program, which is not portable either.

Santosh
  • 799
  • 7
  • 14
-2

operating system loads binary data to memory; looks for entry point (the 'main' symbol in c/c++); makes far jump to the addres of the entry point label. Operating system does not know anything about main function in your code until the program is not loaded.

Interfere
  • 21
  • 5
  • 8
    On most or probably all systems it's not the OS that is responsible for calling `main`. Instead, the OS calls the machine code level **entry point** for the program. For C and C++ that entry point is typically a function in the run time library, which in turn does various initialization chores, then calls `main`, and finally cleans up (e.g. calls installed exit handlers) and exits. – Cheers and hth. - Alf Aug 08 '11 at 12:10