<p>I noticed C defines the entry point as a <code>main()</code> function. So does Java. So does C++ (or not, because functions called as global variable initializers are called before <code>main()</code>. I was wondering. Is there a reason for requiring a user-defined function to be the entry point of the program? Is this (typically) how executable work, or is this just a higher level language requirement? Could a language be designed that does not use a function as an entry point, that executes very slightly faster because the function-call overhead of calling <code>main()</code> is eliminated?</p>

<functions>
Entry point of low level languages
CC BY-SA 4.0
2023-05-26T19:39:12.287Z
It's not just "low level" languages that do it. Java, Kotlin, and Rust I would not consider low level, but they all use a `main` function
Seggan
CC BY-SA 4.0
2023-05-26T19:45:40.477Z
Haskell too I think
Seggan
CC BY-SA 4.0
2023-05-26T19:55:12.897Z
C# has one but now you can write top-level code if you prefer, and Swift you can either have `@main` or a file with top-level code. The only languages I can think of that _only_ use top-level code and not a main function are scripting languages.
Bbrk24
CC BY-SA 4.0
2023-05-26T19:57:19.163Z
See also [`((constructor))`/`((destructor))` attributes](https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html) for doing things outside `main` in gcc
RubenVerg
CC BY-SA 4.0
2023-05-26T20:27:31.737Z
This is essentially a duplicate of [What are the advantages and disadvantages of only allowing top level declarations?](https://languagedesign.stackexchange.com/q/1053/89) ─ if you allow only declarations at the top level then your program's entry point must likewise be a declaration (e.g. a function declaration). Inversely, if you allow statements at the top level then the top-level statements must be the entry point because "when the program starts" is the only sensible time to execute those statements.
kaya3
CC BY-SA 4.0
2023-05-26T20:36:05.267Z
@kaya3 I am not specifically asking about 'top level' - I am asking about ways to define entry points other than functions. Which may or may not be 'top level.'
CPlus
CC BY-SA 4.0
2023-05-26T21:20:21.357Z
@Seggan Haskell has no `main` function. It has a `main` constant, which is of some type `IO a`.
Longinus
CC BY-SA 4.0
2023-05-26T21:39:39.333Z
I don't think this is a dupe of the proposed question. This is asking about the performance penalty of calling a function at the start of a program (and makes the assumption, which I had assumed not to be the case, that `main` is physically called using something like a `call` instruction). Whether or not the assumption underlying this question is correct, and the tradeoffs of a language where that is true, are both independent of the dupe target and interesting in their own right.
rydwolf
CC BY-SA 4.0
2023-05-27T02:35:07.110Z
IMO this question has more to do with low-level semantics while the other one is about syntax. For instance I don't think any of the current answers can be meaningfully moved.
Longinus
CC BY-SA 4.0
2023-05-28T11:06:26.030Z
IMHO this question paints a very unrealistic picture of what function call overhead really is. Compared to the runtime cost of creating a process, calling a function is diminishingly cheap. Most probably the "overhead" of calling main is not even measurable in all non-pathological circumstances. And aside from that, how do you know that languages that allow top level code don't bundle all that up in a `main` function internally that is then called by the runtime on execution?
chrysante
CC BY-SA 4.0
2023-05-28T18:13:55.943Z
@chrysante The question paints a picture about the function call overhead, and if the picture is unrealistic, that could be part of an answer.
CPlus
<p>The alternative to collecting all the main code in a function is having it at the top level of your source files. While there is a executable implementation reason to have main be its own thing (see, for example, <a href="https://en.wikipedia.org/wiki/Crt0" rel="nofollow noreferrer">crt0.s</a> and <a href="https://wiki.osdev.org/Creating_a_C_Library" rel="nofollow noreferrer">OSDev's Creating a C Library</a>), a very useful advantage of having a <code>main</code> function is knowing that the main program logic all lives in the same place. While for small scripts it may be useful to just put code in the root of the file (and most scripting languages do allow to do that), as a codebase gets larger it becomes more difficult to find where the program starts.</p>

CC BY-SA 4.0
2023-05-26T20:00:54.577Z
2023-05-26T20:00:54.577Z
RubenVerg
<p>When the operating system loads and executes a program, or if there is no operating system and some machine/environment needs to boot, there's a first instruction of the program or startup sequence for the session. Many languages or operating system environments load + set up the data/program as requested and then invoke a common entry/starting point, from where the software's implementation proceeds to organize and jump in its control flow.</p>
<p>Modules/libraries (SOs, DLLs, other) may have their own initialization code implementation which is invoked by the system on them being loaded as dependencies for setup purposes (but could be exploited?), before the start function/method of the main program is invoked. The main benefit is that this starting point is a common interface, so for any kind of module or program, the environment has a way to identify this start position to then jump to it after it is done with its setup, and passes off control to the user code.</p>
<p>It's also easily imaginable that there could (likely is) some language which is primarily event-driven/reactive, and its loading consists of just registering event handlers. Which event is invoked first may entirely depend on the outside system/environment, so there would not be a single nor guaranteed starting point for where user code is executed first. A REPL environment may invoke a set of scripts/functions without there being a &quot;program&quot; that's bound together by a single start/main point and then subsequent dispatch to its parts.</p>
<p>Having a main/starting function/point is mostly a convenient convention. It might be an option to continue execution at whichever point it was last left off, as with Smalltalk images, which just continue a session. There might not be a hard technical reason for it. If the system/environment handles the invokation, that itself had a starting point, and at some point inevitably there's the first instruction that needs to be found at some place/spot when the machine is turned on.</p>
<p>Performance-wise, saving the <code>main()</code> function call of C would be pretty insignificant compared to all the time spent on loading and setup.</p>

CC BY-SA 4.0
2024-06-15T02:57:04.430Z
2024-06-15T02:57:04.430Z
skreutzer
<p>This depends both on language design as well as, more broadly, operating system design.</p>
<p>Many languages such as Python, PHP, Ruby or ECMAScript, but also Swift, C# or Holy C, as well as many implementations, do not require routines as entry points and instead start &quot;executing from the top of a file&quot; - whatever that means according to each of those.</p>
<pre class="lang-php prettyprint-override"><code>function hello(string $s)
{
    echo(&quot;Hello &quot; . $s . &quot;!&quot;);
}

hello(&quot;World!&quot;); //interpreter just runs that
</code></pre>
<p>Others have as entry point the computation of a variable or constant.<br />
Haskell is notable there: it has a <code>main</code> constant of some <code>IO a</code> type.</p>
<pre class="lang-hs prettyprint-override"><code>hello :: String -&gt; IO ()
hello s = putStrLn $ &quot;Hello &quot; ++ s ++ &quot;!&quot;

main :: IO ()
main = hello &quot;World&quot;
</code></pre>
<p>Note how <code>hello</code> is a function but <code>main</code> is not.</p>
<p>But those rules are established by programming languages.<br />
Operating systems and language implementations may disagree and come up with their own sets of rules.<br />
Languages, OSs and implementations may or may not be compatible with each other.</p>
<p>For instance C and C++ both are specified in terms of two distinct <em>environments</em>: Hosted and Freestanding.<br />
In Hosted environment, you have access to the full standard libraries and must have a <code>main</code> routine as entry point, while in Freestanding environment, only a subset of the stdlibs are exposed and whether or not an entry point is necessary at all is implementation-defined (C++20§6.9.3.1.).</p>
<p>C++ also goes out of its way to give many rules to <code>main</code> including:</p>
<ul>
<li>it may not be predefined,</li>
<li>it may not be overloaded,</li>
<li>it must have a &quot;type with C++ language linkage,&quot;</li>
<li>its actual linkage is implementation-defined,</li>
<li>it must return an <code>int</code>,</li>
<li>that returned <code>int</code> is implicitly 0 if not written by the user,</li>
<li><strong><code>main</code>'s type is implementation-defined</strong>,</li>
<li>an implementation must allow <strong>at least</strong> <code>()</code> and <code>(int, char**)</code> as parameters,</li>
<li>if present, argc must be the length of a vector pointed to by argv minus one,</li>
<li><code>argv[argc]</code> must be 0,</li>
<li><strong>nowhere in a program may <code>main</code> be &quot;used.&quot;</strong></li>
</ul>
<p>So as you can see, many implementation-defined properties.</p>
<p>Meanwhile, compilers for <a href="https://learn.microsoft.com/en-us/windows/win32/learnwin32/winmain--the-application-entry-point" rel="noreferrer">MS Windows</a> extend C and C++ with additional entry points that the Windows ecosystem rely on and that are exposed to the user.<br />
Notably,</p>
<ul>
<li><code>main</code> is called by &quot;console applications,&quot;</li>
<li><code>WinMain</code> is called by &quot;GUI applications,&quot;</li>
<li><code>wWinMain</code> is the same as <code>WinMain</code> but accepts 16bits characters as input,</li>
<li><a href="https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain" rel="noreferrer"><code>DllMain</code></a> is called by DLLs at load time, unload time, and when threads spawn and die while the DLL is linked in.</li>
</ul>
<p>UNIX and Win32 also allow <code>main</code> a third parameter of type <code>char**</code> (envp) and Darwin allows it a fourth of the same type (apple).</p>
<p>Then you also have Java codebases which may contain multiple <code>main</code> static methods stored in different classes, and where you have to specify which class to load <code>main</code> from - done either from the shell or by having a <code>Main-Class</code> entry in a JAR's manifest.</p>
<blockquote>
<p>Is this (typically) how executable work, or is this just a higher level language requirement?</p>
</blockquote>
<p>Typically, an executable has metadata that contains an address of where to start executing code.<br />
In <a href="https://en.wikipedia.org/wiki/Executable_and_Linkable_Format" rel="noreferrer">ELF</a> that is <code>e_entry</code> at offset 0x18.<br />
In <a href="https://en.wikipedia.org/wiki/Portable_Executable" rel="noreferrer">PE</a> that is <code>AddressOfEntryPoint</code> at offset 0x28.</p>
<p>Also note that we have to take into account the workings of runtime system libraries (RTSs).<br />
For instance GNU works by having entry points invoke <a href="https://github.com/lattera/glibc/blob/master/sysdeps/x86_64/start.S" rel="noreferrer"><code>__libc_start_main</code></a> which not only calls <code>main</code> but also runs routines from the <code>.init</code> and <code>.fini</code> sections, as well as sees pointers in the <code>.preinit_array</code>, <code>.init_array</code>, and <code>.fini_array</code> sections called by the dynamic linker.<br />
<a href="https://www.sco.com/developers/gabi/latest/ch5.dynamic.html#init_fini" rel="noreferrer">https://www.sco.com/developers/gabi/latest/ch5.dynamic.html#init_fini</a><br />
<a href="https://maskray.me/blog/2021-11-07-init-ctors-init-array" rel="noreferrer">https://maskray.me/blog/2021-11-07-init-ctors-init-array</a></p>
<p>As far as executables for x86-64, ARM, and other typical architectures go, there is no concept of &quot;function.&quot; Only code, addresses, and jumps.</p>
<blockquote>
<p>Could a language be designed that does not use a function as an entry point, that executes very slightly faster because the function-call overhead of calling main() is eliminated?</p>
</blockquote>
<p>That is a purely compiler-related question, not a language-related one.<br />
A compiler is free to inline everything inside <code>_start</code> and to eliminate all calls if it wants to. It can also eliminate all jumps, and in fact on x86-64, you can use only <a href="https://github.com/xoreaxeaxeax/movfuscator" rel="noreferrer"><code>mov</code></a> if you wish to.</p>

CC BY-SA 4.0
2023-05-26T22:05:31.803Z
2023-05-27T02:29:59.297Z
2023-05-27T02:29:59.297Z
Longinus
# Entry point of low level languages
Posted by: username_0 on 2023-05-26
I noticed C defines the entry point as a `main()` function. So does Java. So does C++ (or not, because functions called as global variable initializers are called before `main()`. I was wondering. Is there a reason for requiring a user-defined function to be the entry point of the program? Is this (typically) how executable work, or is this just a higher level language requirement? Could a language be designed that does not use a function as an entry point, that executes very slightly faster because the function-call overhead of calling `main()` is eliminated?
**Tags:** functions
> **Comments:**
> **username_1**: It's not just "low level" languages that do it. Java, Kotlin, and Rust I would not consider low level, but they all use a `main` function  
> **username_1**: Haskell too I think  
> **username_2**: C# has one but now you can write top-level code if you prefer, and Swift you can either have `@main` or a file with top-level code. The only languages I can think of that _only_ use top-level code and not a main function are scripting languages.  
> **username_3**: See also [`((constructor))`/`((destructor))` attributes](https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html) for doing things outside `main` in gcc  
> **username_4**: This is essentially a duplicate of [What are the advantages and disadvantages of only allowing top level declarations?](https://languagedesign.stackexchange.com/q/1053/89) ─ if you allow only declarations at the top level then your program's entry point must likewise be a declaration (e.g. a function declaration). Inversely, if you allow statements at the top level then the top-level statements must be the entry point because "when the program starts" is the only sensible time to execute those statements.  
> **username_0**: @kaya3 I am not specifically asking about 'top level' - I am asking about ways to define entry points other than functions. Which may or may not be 'top level.'  
> **username_5**: @Seggan Haskell has no `main` function. It has a `main` constant, which is of some type `IO a`.  
> **username_6**: I don't think this is a dupe of the proposed question. This is asking about the performance penalty of calling a function at the start of a program (and makes the assumption, which I had assumed not to be the case, that `main` is physically called using something like a `call` instruction). Whether or not the assumption underlying this question is correct, and the tradeoffs of a language where that is true, are both independent of the dupe target and interesting in their own right.  
> **username_5**: IMO this question has more to do with low-level semantics while the other one is about syntax. For instance I don't think any of the current answers can be meaningfully moved.  
> **username_7**: IMHO this question paints a very unrealistic picture of what function call overhead really is. Compared to the runtime cost of creating a process, calling a function is diminishingly cheap. Most probably the "overhead" of calling main is not even measurable in all non-pathological circumstances. And aside from that, how do you know that languages that allow top level code don't bundle all that up in a `main` function internally that is then called by the runtime on execution?  
> **username_0**: @chrysante The question paints a picture about the function call overhead, and if the picture is unrealistic, that could be part of an answer.  
---
## 3 answers
### Answer by username_5 on 2023-05-26. Score: 8 | Accepted answer
This depends both on language design as well as, more broadly, operating system design.
Many languages such as Python, PHP, Ruby or ECMAScript, but also Swift, C# or Holy C, as well as many implementations, do not require routines as entry points and instead start "executing from the top of a file" - whatever that means according to each of those.
function hello(string $s)
{
    echo("Hello " . $s . "!");
}

hello("World!"); //interpreter just runs that

Others have as entry point the computation of a variable or constant.
Haskell is notable there: it has a main constant of some IO a type.
hello :: String -> IO ()
hello s = putStrLn $ "Hello " ++ s ++ "!"

main :: IO ()
main = hello "World"

Note how hello is a function but main is not.
But those rules are established by programming languages.
Operating systems and language implementations may disagree and come up with their own sets of rules.
Languages, OSs and implementations may or may not be compatible with each other.
For instance C and C++ both are specified in terms of two distinct environments: Hosted and Freestanding.
In Hosted environment, you have access to the full standard libraries and must have a main routine as entry point, while in Freestanding environment, only a subset of the stdlibs are exposed and whether or not an entry point is necessary at all is implementation-defined (C++20§6.9.3.1.).
C++ also goes out of its way to give many rules to main including:

it may not be predefined,
it may not be overloaded,
it must have a "type with C++ language linkage,"
its actual linkage is implementation-defined,
it must return an int,
that returned int is implicitly 0 if not written by the user,
main's type is implementation-defined,
an implementation must allow at least () and (int, char**) as parameters,
if present, argc must be the length of a vector pointed to by argv minus one,
argv[argc] must be 0,
nowhere in a program may main be "used."

So as you can see, many implementation-defined properties.
Meanwhile, compilers for MS Windows extend C and C++ with additional entry points that the Windows ecosystem rely on and that are exposed to the user.
Notably,

main is called by "console applications,"
WinMain is called by "GUI applications,"
wWinMain is the same as WinMain but accepts 16bits characters as input,
DllMain is called by DLLs at load time, unload time, and when threads spawn and die while the DLL is linked in.

UNIX and Win32 also allow main a third parameter of type char** (envp) and Darwin allows it a fourth of the same type (apple).
Then you also have Java codebases which may contain multiple main static methods stored in different classes, and where you have to specify which class to load main from - done either from the shell or by having a Main-Class entry in a JAR's manifest.

Is this (typically) how executable work, or is this just a higher level language requirement?

Typically, an executable has metadata that contains an address of where to start executing code.
In ELF that is e_entry at offset 0x18.
In PE that is AddressOfEntryPoint at offset 0x28.
Also note that we have to take into account the workings of runtime system libraries (RTSs).
For instance GNU works by having entry points invoke __libc_start_main which not only calls main but also runs routines from the .init and .fini sections, as well as sees pointers in the .preinit_array, .init_array, and .fini_array sections called by the dynamic linker.
https://www.sco.com/developers/gabi/latest/ch5.dynamic.html#init_fini
https://maskray.me/blog/2021-11-07-init-ctors-init-array
As far as executables for x86-64, ARM, and other typical architectures go, there is no concept of "function." Only code, addresses, and jumps.

Could a language be designed that does not use a function as an entry point, that executes very slightly faster because the function-call overhead of calling main() is eliminated?

That is a purely compiler-related question, not a language-related one.
A compiler is free to inline everything inside _start and to eliminate all calls if it wants to. It can also eliminate all jumps, and in fact on x86-64, you can use only mov if you wish to.
---
### Answer by username_3 on 2023-05-26. Score: 2
The alternative to collecting all the main code in a function is having it at the top level of your source files. While there is a executable implementation reason to have main be its own thing (see, for example, [crt0.s](https://en.wikipedia.org/wiki/Crt0) and [OSDev's Creating a C Library](https://wiki.osdev.org/Creating_a_C_Library)), a very useful advantage of having a `main` function is knowing that the main program logic all lives in the same place. While for small scripts it may be useful to just put code in the root of the file (and most scripting languages do allow to do that), as a codebase gets larger it becomes more difficult to find where the program starts.
---
### Answer by username_8 on 2024-06-15. Score: 1
When the operating system loads and executes a program, or if there is no operating system and some machine/environment needs to boot, there's a first instruction of the program or startup sequence for the session. Many languages or operating system environments load + set up the data/program as requested and then invoke a common entry/starting point, from where the software's implementation proceeds to organize and jump in its control flow.

Modules/libraries (SOs, DLLs, other) may have their own initialization code implementation which is invoked by the system on them being loaded as dependencies for setup purposes (but could be exploited?), before the start function/method of the main program is invoked. The main benefit is that this starting point is a common interface, so for any kind of module or program, the environment has a way to identify this start position to then jump to it after it is done with its setup, and passes off control to the user code.

It's also easily imaginable that there could (likely is) some language which is primarily event-driven/reactive, and its loading consists of just registering event handlers. Which event is invoked first may entirely depend on the outside system/environment, so there would not be a single nor guaranteed starting point for where user code is executed first. A REPL environment may invoke a set of scripts/functions without there being a "program" that's bound together by a single start/main point and then subsequent dispatch to its parts.

Having a main/starting function/point is mostly a convenient convention. It might be an option to continue execution at whichever point it was last left off, as with Smalltalk images, which just continue a session. There might not be a hard technical reason for it. If the system/environment handles the invokation, that itself had a starting point, and at some point inevitably there's the first instruction that needs to be found at some place/spot when the machine is turned on.

Performance-wise, saving the `main()` function call of C would be pretty insignificant compared to all the time spent on loading and setup.
---
