Does int main() need a declaration on C++?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
When learning functions on C++, I was taught that functions need declarations to be called. For example:
#include <iostream>
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
It returns an error, as there is no declaration for the function sum
.
main.cpp:4:36: error: use of undeclared identifier 'sum'
std::cout << "The result is " << sum(1, 2);
^
1 error generated.
To fix this, I'd add the declaration:
#include <iostream>
int sum(int x, int y); // declaration
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
My question is, why we don't add a declaration for the main
function, as we'd have to add for other functions, like sum
?
c++ main forward-declaration function-declaration
|
show 4 more comments
When learning functions on C++, I was taught that functions need declarations to be called. For example:
#include <iostream>
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
It returns an error, as there is no declaration for the function sum
.
main.cpp:4:36: error: use of undeclared identifier 'sum'
std::cout << "The result is " << sum(1, 2);
^
1 error generated.
To fix this, I'd add the declaration:
#include <iostream>
int sum(int x, int y); // declaration
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
My question is, why we don't add a declaration for the main
function, as we'd have to add for other functions, like sum
?
c++ main forward-declaration function-declaration
17
Manually calling main invokes undefined behaviour.
– George
Apr 1 at 14:40
23
@MichaelStachowsky -- in C you're allowed to callmain
. In C++ you aren't; it isn't "just a function" -- it's special. Historically, the reason is that compilers added code tomain
to initialize global variables that required dynamic initialization; callingmain
from inside the program would re-initialize those variables, and the result would be chaos.
– Pete Becker
Apr 1 at 16:41
26
@Michael That you've tried something and found that "it works just fine" does not prove that something is not undefined behavior.
– Cody Gray♦
Apr 1 at 16:53
7
As an aside, you don't need a declaration forsum
if you put the definition above main in the file. For this reason, it is common to seemain
as the last function in C and C++ source code, so you don't need to have forward declarations for other functions defined in that file. Not like C# and Java that often putmain
first, although it is not required in those cases.
– Cody
Apr 1 at 16:59
10
Technically your example code has declaredmain
, a definition of a function also declares the function. That's why you can movesum
beforemain
to avoid having to separately declaresum
.
– Ross Ridge
Apr 1 at 18:49
|
show 4 more comments
When learning functions on C++, I was taught that functions need declarations to be called. For example:
#include <iostream>
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
It returns an error, as there is no declaration for the function sum
.
main.cpp:4:36: error: use of undeclared identifier 'sum'
std::cout << "The result is " << sum(1, 2);
^
1 error generated.
To fix this, I'd add the declaration:
#include <iostream>
int sum(int x, int y); // declaration
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
My question is, why we don't add a declaration for the main
function, as we'd have to add for other functions, like sum
?
c++ main forward-declaration function-declaration
When learning functions on C++, I was taught that functions need declarations to be called. For example:
#include <iostream>
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
It returns an error, as there is no declaration for the function sum
.
main.cpp:4:36: error: use of undeclared identifier 'sum'
std::cout << "The result is " << sum(1, 2);
^
1 error generated.
To fix this, I'd add the declaration:
#include <iostream>
int sum(int x, int y); // declaration
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
My question is, why we don't add a declaration for the main
function, as we'd have to add for other functions, like sum
?
c++ main forward-declaration function-declaration
c++ main forward-declaration function-declaration
edited Apr 1 at 15:01
NathanOliver
98.2k16138217
98.2k16138217
asked Apr 1 at 14:37
vnbrsvnbrs
1,56811024
1,56811024
17
Manually calling main invokes undefined behaviour.
– George
Apr 1 at 14:40
23
@MichaelStachowsky -- in C you're allowed to callmain
. In C++ you aren't; it isn't "just a function" -- it's special. Historically, the reason is that compilers added code tomain
to initialize global variables that required dynamic initialization; callingmain
from inside the program would re-initialize those variables, and the result would be chaos.
– Pete Becker
Apr 1 at 16:41
26
@Michael That you've tried something and found that "it works just fine" does not prove that something is not undefined behavior.
– Cody Gray♦
Apr 1 at 16:53
7
As an aside, you don't need a declaration forsum
if you put the definition above main in the file. For this reason, it is common to seemain
as the last function in C and C++ source code, so you don't need to have forward declarations for other functions defined in that file. Not like C# and Java that often putmain
first, although it is not required in those cases.
– Cody
Apr 1 at 16:59
10
Technically your example code has declaredmain
, a definition of a function also declares the function. That's why you can movesum
beforemain
to avoid having to separately declaresum
.
– Ross Ridge
Apr 1 at 18:49
|
show 4 more comments
17
Manually calling main invokes undefined behaviour.
– George
Apr 1 at 14:40
23
@MichaelStachowsky -- in C you're allowed to callmain
. In C++ you aren't; it isn't "just a function" -- it's special. Historically, the reason is that compilers added code tomain
to initialize global variables that required dynamic initialization; callingmain
from inside the program would re-initialize those variables, and the result would be chaos.
– Pete Becker
Apr 1 at 16:41
26
@Michael That you've tried something and found that "it works just fine" does not prove that something is not undefined behavior.
– Cody Gray♦
Apr 1 at 16:53
7
As an aside, you don't need a declaration forsum
if you put the definition above main in the file. For this reason, it is common to seemain
as the last function in C and C++ source code, so you don't need to have forward declarations for other functions defined in that file. Not like C# and Java that often putmain
first, although it is not required in those cases.
– Cody
Apr 1 at 16:59
10
Technically your example code has declaredmain
, a definition of a function also declares the function. That's why you can movesum
beforemain
to avoid having to separately declaresum
.
– Ross Ridge
Apr 1 at 18:49
17
17
Manually calling main invokes undefined behaviour.
– George
Apr 1 at 14:40
Manually calling main invokes undefined behaviour.
– George
Apr 1 at 14:40
23
23
@MichaelStachowsky -- in C you're allowed to call
main
. In C++ you aren't; it isn't "just a function" -- it's special. Historically, the reason is that compilers added code to main
to initialize global variables that required dynamic initialization; calling main
from inside the program would re-initialize those variables, and the result would be chaos.– Pete Becker
Apr 1 at 16:41
@MichaelStachowsky -- in C you're allowed to call
main
. In C++ you aren't; it isn't "just a function" -- it's special. Historically, the reason is that compilers added code to main
to initialize global variables that required dynamic initialization; calling main
from inside the program would re-initialize those variables, and the result would be chaos.– Pete Becker
Apr 1 at 16:41
26
26
@Michael That you've tried something and found that "it works just fine" does not prove that something is not undefined behavior.
– Cody Gray♦
Apr 1 at 16:53
@Michael That you've tried something and found that "it works just fine" does not prove that something is not undefined behavior.
– Cody Gray♦
Apr 1 at 16:53
7
7
As an aside, you don't need a declaration for
sum
if you put the definition above main in the file. For this reason, it is common to see main
as the last function in C and C++ source code, so you don't need to have forward declarations for other functions defined in that file. Not like C# and Java that often put main
first, although it is not required in those cases.– Cody
Apr 1 at 16:59
As an aside, you don't need a declaration for
sum
if you put the definition above main in the file. For this reason, it is common to see main
as the last function in C and C++ source code, so you don't need to have forward declarations for other functions defined in that file. Not like C# and Java that often put main
first, although it is not required in those cases.– Cody
Apr 1 at 16:59
10
10
Technically your example code has declared
main
, a definition of a function also declares the function. That's why you can move sum
before main
to avoid having to separately declare sum
.– Ross Ridge
Apr 1 at 18:49
Technically your example code has declared
main
, a definition of a function also declares the function. That's why you can move sum
before main
to avoid having to separately declare sum
.– Ross Ridge
Apr 1 at 18:49
|
show 4 more comments
7 Answers
7
active
oldest
votes
A definition of a function is also a declaration of a function.
The purpose of a declaring a function is to make it known to the compiler. Declaring a function without defining it allows a function to be used in places where it is inconvenient to define it. For example:
- If a function is used in a source file (A) other than the one it is defined in (B), we need to declare it in A (usually via a header that A includes, such as
B.h
). - If two or more functions may call each other, then we cannot define all those functions before the others—one of them has to be first. So declarations can be provided first, with definitions coming afterward.
- Many people prefer to put “higher level” routines earlier in a source file and subroutines later. Since those “higher level” routines call various subroutines, the subroutines must be declared earlier.
In C++, a user program never calls main
, so it never needs a declaration before the definition. (Note that you could provide one if you wished. There is nothing special about a declaration of main
in this regard.) In C, a program can call main
. In that case, it does require that a declaration be visible before the call.
Note that main
does need to be known to the code that calls it. This is special code in what is typically called the C++ runtime startup code. The linker includes that code for you automatically when you are linking a C++ program with the appropriate linker options. Whatever language that code is written in, it has whatever declaration of main
it needs in order to call it properly.
I think this is the most complete and correct answer so far. It's a pitty it won't get more popular because of the abundance of text. Could you add some tl;dr at the beginning? Also, I think, that it might not be obvious that the C++ compilers parse the code in such a sequential manner. Other languages overcome this issue by scanning declarations first and definitions later. C++ overcomes it only for class bodies.
– pkubik
Apr 1 at 23:26
Thank you for this! Indeed the most complete one. I can now understand this a bit more.
– vnbrs
Apr 2 at 11:54
add a comment |
I was taught that functions need declarations to be called.
Indeed. A function must be declared before it can be called.
why we don't add a declaration for the
main
function?
Well, you didn't call main
function. In fact, you must not call main
at all1, so there is never a need to declare main
before anything.
Technically though, all definitions are also declarations, so your definition of main
also declares main
.
Footnote 1: The C++ standard says it's undefined behaviour to call main
from within the program.
This allows C++ implementations to put special run-once startup code at the top of main, if they aren't able to have it run earlier from hooks in the startup code that normally calls main
. Some real implementations do in fact do this, e.g. calling a fast-math function that sets some FPU flags like denormals-are-zero.
On a hypothetical implementation, calling main could result in fun things like re-running constructors for all static variables, re-initializing the data structures used by new
/delete
to keep track of allocations, or other total breakage of your program. Or it might not cause any problem at all. Undefined behaviour doesn't mean it has to fail on every implementation.
add a comment |
The prototype is required if you want to call the function, but it's not yet available, like sum
in your case.
You must not call main
yourself, so there is no need to have a prototype. It's even a bad a idea to write a prototype.
It is not a "bad idea" at all to callmain
. C allows it; C++ makes it undefined for reasons which have nothing to do with it being a bad idea.
– Kaz
Apr 2 at 15:06
9
@Kaz It's a bad idea to do something whose behaviour is undefined.
– eerorika
Apr 2 at 15:19
@eeroika That's a circular argument. Recursivemain
that was well-defined came first. The answer says that not only must you not do this, but it's even a bad idea.That implies that it's a bad idea for additional reasons other than it being prohibited, or perhaps that it's prohibited due to being a bad idea, which is not so. This is just a feature of C that the C++ dialect fails to implement.
– Kaz
Apr 2 at 15:34
1
A C++ compiler is allowed to emit the translated imagemain
as if it wereextern "C"
linkage. Or to substitute a different symbol for its name entirely, like__main
or whatever. Yet, it's also allowed to ignore these considerations when compiling main, and treat it just as another function, so that themain
symbol is declared in the ordinary way. The recursive call tomain
may expect to be calling a C++ function calledmain
with ordinary C++ linkage, that supports overloading and all, yet there need not be such a symbol at all in the translation due to the special treatment.
– Kaz
Apr 2 at 15:39
1
@MatthieuBrucher Ah, OK; I misread that. The prototype could serve no useful purpose in C++.
– Kaz
Apr 2 at 15:40
|
show 2 more comments
No, the compiler does not need a forward declaration for main()
.
main()
is a special function in C++.
Some important things to remember about main() are:
- The linker requires that one and only one
main()
function exist when creating an executable program. - The compiler expects a main() function in one of the following two forms:
int main () { /* body */ }
int main (int argc, char *argv) { /* body */ }
where body
is zero or more statements
An additional acceptable form is implementation specific and provides a list of the environment variables at the time the function is called:
int main (int argc, char* argv, char *envp) { /* body */ }
The coder must provide the 'definition' of main using one of these acceptable forms, but the coder does not need to provide a declaration. The coded definiton is accepted by the compiler as the declaration of main().
- If no return statement is provided, the compiler will provide a
return 0;
as the last statement in the function body.
As an aside, there is sometimes confusion about whether a C++ program can make a call to main(). This is not recommended. The C++17 draft states that main() "shall not be used within a program." In other words, cannot be called from within a program. See e.g. Working Draft Standard for C++ Programming Language, dated "2017-03-21", Paragraph 6.6.1.3, page 66. I realize that some compilers support this (including mine), but the next version of the compiler could modify or remove that behavior as the standard uses the term "shall not".
Also note that the standard allows other implementation-defined signatures for main besides the two you listed here. A common option is to add a 3rd argument (after argv) that contains the environment variables (using the same method asextern char** environ
)
– SJL
Apr 1 at 19:51
@SJL: Absolutely! I have only listed the ones that "must" be implemented by the compiler. Theenviron
is also very helpful.
– Gardener
Apr 1 at 19:52
8
"compiler does not need a declaration formain()
" Every definition is a declaration, so I think the wording needs to be adjusted. "compiler declares it as one of the following two functions" Why "compiler declares"? We always provide a definition formain
ourselves.
– HolyBlackCat
Apr 1 at 20:02
1
@HolyBlackCat: I see your point. Wording is important. Even if I change it, without quoting the entire standard, there will not be a complete answer. The answer is meant to be simple. See what you think of this update.
– Gardener
Apr 1 at 20:14
6
There's nothing special about the main function with regards to (forward) declaration. That's simply a red herring. Rather, we don't need to forward declare it since we're not referring to it before its definition. That's all.
– Konrad Rudolph
Apr 1 at 22:19
add a comment |
It is illegal to call main
from inside your program. That means the only thing that is going to call it is the runtime and the compiler/linker can handle setting that up.This means you do not need a prototype for main
.
add a comment |
A definition of a function also implicitly declares it. If you need to reference a function before it is defined you need to declare it before you use it.
So writing the following is also valid:
int sum(int x, int y) {
return x + y;
}
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
If you use a declaration in one file to make a function known to the compiler before it is defined, then its definition has to be known at linking time:
main.cpp
int sum(int x, int y);
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
sum.cpp
int sum(int x, int y) {
return x + y;
}
Or sum
could have its origin in a library, so you do not even compile it yourself.
The main
function is not used/referenced in your code anywhere, so there is no need to add the declaration of main
anywhere.
Before and after your main
function the c++ library might execute some init and cleanup steps, and will call your main
function. If that part of the library would be represented as c++ code then it would contain a declaration of int main()
so that that it could be compiled. That code could look like this:
int main();
int __main() {
__startup_runtime();
main();
__cleanup_runtime();
}
But then you again have the same problem with __main
so at some point there is no c++ anymore and a certain function (main
) just represents the entry point of your code.
C++ makes it UB to callmain
from inside the program, so C++ compilers can put those startup/cleanup calls right into the realmain
if they want. This rule lets C++ compilers work on top of C environments, for example, giving somewhere for static constructors to be called from if there's no other mechanism a compiler can use. (Compilers also have to recognizemain
as a special function name to give it an implicitreturn 0
.)
– Peter Cordes
Apr 2 at 11:06
@PeterCordes from the perspective of the programmer it is UB to call themain
function due to the the standard. But how the compile vendors or the os handlesmain
is implementation dependent. So in theory the compiled result of themain
could look like a regular function that is called by the run-time, or it could not exists and as you said, the compilers can put those startup/cleanup calls right at the entry point of the application around the code that is shown in themain
.
– t.niese
Apr 2 at 11:40
Yup, in most implementations it is just a normal function (but with an implicitextern "C"
to not do C++ name mangling on it, so the CRT startup code can link to it regardless of function signature), with real init work done in CRT code and/or from dynamic linker hooks. But like I commented Joshua's answer, ICC (Intel's compiler) does in fact add some startup code insidemain
itself (godbolt.org/z/oWlmlc), including setting DAZ and FTZ to disable subnormals for its default of-ffast-math
. gcc/clang link different CRT startup files for fast-math or not.
– Peter Cordes
Apr 2 at 12:13
add a comment |
Nope. You can't call it anyway.
You only need forward declarations for functions called before they are defined. You need external declarations (which look exactly like forward declarations on purpose) for functions defined in other files.
But you can't call main
in C++ so you don't need one. This is because the C++ compiler is allowed to modify main to do global initialization.
[I looked at crt0.c and it does have a declaration for main but that's neither here nor there].
You can callmain
, it's just typically bad practice.
– Cruz Jean
Apr 1 at 14:40
8
@CruzJean not just a bad practice, it's undefined behavior as far as I know
– Guillaume Racicot
Apr 1 at 14:41
5
@CruzJean Not bad practice. Calling it invokes undefined behavior.
– Algirdas Preidžius
Apr 1 at 14:42
@AlgirdasPreidžius Ah, I stand corrected. Never knew about that.
– Cruz Jean
Apr 1 at 14:46
This is because the C++ compiler is allowed to modify main to do global initialization. Is it? I can't see how that would even work as you would be assigning inmain
which can change the observable effects of the program.
– NathanOliver
Apr 1 at 14:54
|
show 3 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55457704%2fdoes-int-main-need-a-declaration-on-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
A definition of a function is also a declaration of a function.
The purpose of a declaring a function is to make it known to the compiler. Declaring a function without defining it allows a function to be used in places where it is inconvenient to define it. For example:
- If a function is used in a source file (A) other than the one it is defined in (B), we need to declare it in A (usually via a header that A includes, such as
B.h
). - If two or more functions may call each other, then we cannot define all those functions before the others—one of them has to be first. So declarations can be provided first, with definitions coming afterward.
- Many people prefer to put “higher level” routines earlier in a source file and subroutines later. Since those “higher level” routines call various subroutines, the subroutines must be declared earlier.
In C++, a user program never calls main
, so it never needs a declaration before the definition. (Note that you could provide one if you wished. There is nothing special about a declaration of main
in this regard.) In C, a program can call main
. In that case, it does require that a declaration be visible before the call.
Note that main
does need to be known to the code that calls it. This is special code in what is typically called the C++ runtime startup code. The linker includes that code for you automatically when you are linking a C++ program with the appropriate linker options. Whatever language that code is written in, it has whatever declaration of main
it needs in order to call it properly.
I think this is the most complete and correct answer so far. It's a pitty it won't get more popular because of the abundance of text. Could you add some tl;dr at the beginning? Also, I think, that it might not be obvious that the C++ compilers parse the code in such a sequential manner. Other languages overcome this issue by scanning declarations first and definitions later. C++ overcomes it only for class bodies.
– pkubik
Apr 1 at 23:26
Thank you for this! Indeed the most complete one. I can now understand this a bit more.
– vnbrs
Apr 2 at 11:54
add a comment |
A definition of a function is also a declaration of a function.
The purpose of a declaring a function is to make it known to the compiler. Declaring a function without defining it allows a function to be used in places where it is inconvenient to define it. For example:
- If a function is used in a source file (A) other than the one it is defined in (B), we need to declare it in A (usually via a header that A includes, such as
B.h
). - If two or more functions may call each other, then we cannot define all those functions before the others—one of them has to be first. So declarations can be provided first, with definitions coming afterward.
- Many people prefer to put “higher level” routines earlier in a source file and subroutines later. Since those “higher level” routines call various subroutines, the subroutines must be declared earlier.
In C++, a user program never calls main
, so it never needs a declaration before the definition. (Note that you could provide one if you wished. There is nothing special about a declaration of main
in this regard.) In C, a program can call main
. In that case, it does require that a declaration be visible before the call.
Note that main
does need to be known to the code that calls it. This is special code in what is typically called the C++ runtime startup code. The linker includes that code for you automatically when you are linking a C++ program with the appropriate linker options. Whatever language that code is written in, it has whatever declaration of main
it needs in order to call it properly.
I think this is the most complete and correct answer so far. It's a pitty it won't get more popular because of the abundance of text. Could you add some tl;dr at the beginning? Also, I think, that it might not be obvious that the C++ compilers parse the code in such a sequential manner. Other languages overcome this issue by scanning declarations first and definitions later. C++ overcomes it only for class bodies.
– pkubik
Apr 1 at 23:26
Thank you for this! Indeed the most complete one. I can now understand this a bit more.
– vnbrs
Apr 2 at 11:54
add a comment |
A definition of a function is also a declaration of a function.
The purpose of a declaring a function is to make it known to the compiler. Declaring a function without defining it allows a function to be used in places where it is inconvenient to define it. For example:
- If a function is used in a source file (A) other than the one it is defined in (B), we need to declare it in A (usually via a header that A includes, such as
B.h
). - If two or more functions may call each other, then we cannot define all those functions before the others—one of them has to be first. So declarations can be provided first, with definitions coming afterward.
- Many people prefer to put “higher level” routines earlier in a source file and subroutines later. Since those “higher level” routines call various subroutines, the subroutines must be declared earlier.
In C++, a user program never calls main
, so it never needs a declaration before the definition. (Note that you could provide one if you wished. There is nothing special about a declaration of main
in this regard.) In C, a program can call main
. In that case, it does require that a declaration be visible before the call.
Note that main
does need to be known to the code that calls it. This is special code in what is typically called the C++ runtime startup code. The linker includes that code for you automatically when you are linking a C++ program with the appropriate linker options. Whatever language that code is written in, it has whatever declaration of main
it needs in order to call it properly.
A definition of a function is also a declaration of a function.
The purpose of a declaring a function is to make it known to the compiler. Declaring a function without defining it allows a function to be used in places where it is inconvenient to define it. For example:
- If a function is used in a source file (A) other than the one it is defined in (B), we need to declare it in A (usually via a header that A includes, such as
B.h
). - If two or more functions may call each other, then we cannot define all those functions before the others—one of them has to be first. So declarations can be provided first, with definitions coming afterward.
- Many people prefer to put “higher level” routines earlier in a source file and subroutines later. Since those “higher level” routines call various subroutines, the subroutines must be declared earlier.
In C++, a user program never calls main
, so it never needs a declaration before the definition. (Note that you could provide one if you wished. There is nothing special about a declaration of main
in this regard.) In C, a program can call main
. In that case, it does require that a declaration be visible before the call.
Note that main
does need to be known to the code that calls it. This is special code in what is typically called the C++ runtime startup code. The linker includes that code for you automatically when you are linking a C++ program with the appropriate linker options. Whatever language that code is written in, it has whatever declaration of main
it needs in order to call it properly.
answered Apr 1 at 20:28
Eric PostpischilEric Postpischil
80.4k890169
80.4k890169
I think this is the most complete and correct answer so far. It's a pitty it won't get more popular because of the abundance of text. Could you add some tl;dr at the beginning? Also, I think, that it might not be obvious that the C++ compilers parse the code in such a sequential manner. Other languages overcome this issue by scanning declarations first and definitions later. C++ overcomes it only for class bodies.
– pkubik
Apr 1 at 23:26
Thank you for this! Indeed the most complete one. I can now understand this a bit more.
– vnbrs
Apr 2 at 11:54
add a comment |
I think this is the most complete and correct answer so far. It's a pitty it won't get more popular because of the abundance of text. Could you add some tl;dr at the beginning? Also, I think, that it might not be obvious that the C++ compilers parse the code in such a sequential manner. Other languages overcome this issue by scanning declarations first and definitions later. C++ overcomes it only for class bodies.
– pkubik
Apr 1 at 23:26
Thank you for this! Indeed the most complete one. I can now understand this a bit more.
– vnbrs
Apr 2 at 11:54
I think this is the most complete and correct answer so far. It's a pitty it won't get more popular because of the abundance of text. Could you add some tl;dr at the beginning? Also, I think, that it might not be obvious that the C++ compilers parse the code in such a sequential manner. Other languages overcome this issue by scanning declarations first and definitions later. C++ overcomes it only for class bodies.
– pkubik
Apr 1 at 23:26
I think this is the most complete and correct answer so far. It's a pitty it won't get more popular because of the abundance of text. Could you add some tl;dr at the beginning? Also, I think, that it might not be obvious that the C++ compilers parse the code in such a sequential manner. Other languages overcome this issue by scanning declarations first and definitions later. C++ overcomes it only for class bodies.
– pkubik
Apr 1 at 23:26
Thank you for this! Indeed the most complete one. I can now understand this a bit more.
– vnbrs
Apr 2 at 11:54
Thank you for this! Indeed the most complete one. I can now understand this a bit more.
– vnbrs
Apr 2 at 11:54
add a comment |
I was taught that functions need declarations to be called.
Indeed. A function must be declared before it can be called.
why we don't add a declaration for the
main
function?
Well, you didn't call main
function. In fact, you must not call main
at all1, so there is never a need to declare main
before anything.
Technically though, all definitions are also declarations, so your definition of main
also declares main
.
Footnote 1: The C++ standard says it's undefined behaviour to call main
from within the program.
This allows C++ implementations to put special run-once startup code at the top of main, if they aren't able to have it run earlier from hooks in the startup code that normally calls main
. Some real implementations do in fact do this, e.g. calling a fast-math function that sets some FPU flags like denormals-are-zero.
On a hypothetical implementation, calling main could result in fun things like re-running constructors for all static variables, re-initializing the data structures used by new
/delete
to keep track of allocations, or other total breakage of your program. Or it might not cause any problem at all. Undefined behaviour doesn't mean it has to fail on every implementation.
add a comment |
I was taught that functions need declarations to be called.
Indeed. A function must be declared before it can be called.
why we don't add a declaration for the
main
function?
Well, you didn't call main
function. In fact, you must not call main
at all1, so there is never a need to declare main
before anything.
Technically though, all definitions are also declarations, so your definition of main
also declares main
.
Footnote 1: The C++ standard says it's undefined behaviour to call main
from within the program.
This allows C++ implementations to put special run-once startup code at the top of main, if they aren't able to have it run earlier from hooks in the startup code that normally calls main
. Some real implementations do in fact do this, e.g. calling a fast-math function that sets some FPU flags like denormals-are-zero.
On a hypothetical implementation, calling main could result in fun things like re-running constructors for all static variables, re-initializing the data structures used by new
/delete
to keep track of allocations, or other total breakage of your program. Or it might not cause any problem at all. Undefined behaviour doesn't mean it has to fail on every implementation.
add a comment |
I was taught that functions need declarations to be called.
Indeed. A function must be declared before it can be called.
why we don't add a declaration for the
main
function?
Well, you didn't call main
function. In fact, you must not call main
at all1, so there is never a need to declare main
before anything.
Technically though, all definitions are also declarations, so your definition of main
also declares main
.
Footnote 1: The C++ standard says it's undefined behaviour to call main
from within the program.
This allows C++ implementations to put special run-once startup code at the top of main, if they aren't able to have it run earlier from hooks in the startup code that normally calls main
. Some real implementations do in fact do this, e.g. calling a fast-math function that sets some FPU flags like denormals-are-zero.
On a hypothetical implementation, calling main could result in fun things like re-running constructors for all static variables, re-initializing the data structures used by new
/delete
to keep track of allocations, or other total breakage of your program. Or it might not cause any problem at all. Undefined behaviour doesn't mean it has to fail on every implementation.
I was taught that functions need declarations to be called.
Indeed. A function must be declared before it can be called.
why we don't add a declaration for the
main
function?
Well, you didn't call main
function. In fact, you must not call main
at all1, so there is never a need to declare main
before anything.
Technically though, all definitions are also declarations, so your definition of main
also declares main
.
Footnote 1: The C++ standard says it's undefined behaviour to call main
from within the program.
This allows C++ implementations to put special run-once startup code at the top of main, if they aren't able to have it run earlier from hooks in the startup code that normally calls main
. Some real implementations do in fact do this, e.g. calling a fast-math function that sets some FPU flags like denormals-are-zero.
On a hypothetical implementation, calling main could result in fun things like re-running constructors for all static variables, re-initializing the data structures used by new
/delete
to keep track of allocations, or other total breakage of your program. Or it might not cause any problem at all. Undefined behaviour doesn't mean it has to fail on every implementation.
edited Apr 2 at 10:49
Peter Cordes
134k18203342
134k18203342
answered Apr 1 at 14:51
eerorikaeerorika
89.4k664136
89.4k664136
add a comment |
add a comment |
The prototype is required if you want to call the function, but it's not yet available, like sum
in your case.
You must not call main
yourself, so there is no need to have a prototype. It's even a bad a idea to write a prototype.
It is not a "bad idea" at all to callmain
. C allows it; C++ makes it undefined for reasons which have nothing to do with it being a bad idea.
– Kaz
Apr 2 at 15:06
9
@Kaz It's a bad idea to do something whose behaviour is undefined.
– eerorika
Apr 2 at 15:19
@eeroika That's a circular argument. Recursivemain
that was well-defined came first. The answer says that not only must you not do this, but it's even a bad idea.That implies that it's a bad idea for additional reasons other than it being prohibited, or perhaps that it's prohibited due to being a bad idea, which is not so. This is just a feature of C that the C++ dialect fails to implement.
– Kaz
Apr 2 at 15:34
1
A C++ compiler is allowed to emit the translated imagemain
as if it wereextern "C"
linkage. Or to substitute a different symbol for its name entirely, like__main
or whatever. Yet, it's also allowed to ignore these considerations when compiling main, and treat it just as another function, so that themain
symbol is declared in the ordinary way. The recursive call tomain
may expect to be calling a C++ function calledmain
with ordinary C++ linkage, that supports overloading and all, yet there need not be such a symbol at all in the translation due to the special treatment.
– Kaz
Apr 2 at 15:39
1
@MatthieuBrucher Ah, OK; I misread that. The prototype could serve no useful purpose in C++.
– Kaz
Apr 2 at 15:40
|
show 2 more comments
The prototype is required if you want to call the function, but it's not yet available, like sum
in your case.
You must not call main
yourself, so there is no need to have a prototype. It's even a bad a idea to write a prototype.
It is not a "bad idea" at all to callmain
. C allows it; C++ makes it undefined for reasons which have nothing to do with it being a bad idea.
– Kaz
Apr 2 at 15:06
9
@Kaz It's a bad idea to do something whose behaviour is undefined.
– eerorika
Apr 2 at 15:19
@eeroika That's a circular argument. Recursivemain
that was well-defined came first. The answer says that not only must you not do this, but it's even a bad idea.That implies that it's a bad idea for additional reasons other than it being prohibited, or perhaps that it's prohibited due to being a bad idea, which is not so. This is just a feature of C that the C++ dialect fails to implement.
– Kaz
Apr 2 at 15:34
1
A C++ compiler is allowed to emit the translated imagemain
as if it wereextern "C"
linkage. Or to substitute a different symbol for its name entirely, like__main
or whatever. Yet, it's also allowed to ignore these considerations when compiling main, and treat it just as another function, so that themain
symbol is declared in the ordinary way. The recursive call tomain
may expect to be calling a C++ function calledmain
with ordinary C++ linkage, that supports overloading and all, yet there need not be such a symbol at all in the translation due to the special treatment.
– Kaz
Apr 2 at 15:39
1
@MatthieuBrucher Ah, OK; I misread that. The prototype could serve no useful purpose in C++.
– Kaz
Apr 2 at 15:40
|
show 2 more comments
The prototype is required if you want to call the function, but it's not yet available, like sum
in your case.
You must not call main
yourself, so there is no need to have a prototype. It's even a bad a idea to write a prototype.
The prototype is required if you want to call the function, but it's not yet available, like sum
in your case.
You must not call main
yourself, so there is no need to have a prototype. It's even a bad a idea to write a prototype.
edited Apr 2 at 15:42
answered Apr 1 at 14:39
Matthieu BrucherMatthieu Brucher
17.4k42345
17.4k42345
It is not a "bad idea" at all to callmain
. C allows it; C++ makes it undefined for reasons which have nothing to do with it being a bad idea.
– Kaz
Apr 2 at 15:06
9
@Kaz It's a bad idea to do something whose behaviour is undefined.
– eerorika
Apr 2 at 15:19
@eeroika That's a circular argument. Recursivemain
that was well-defined came first. The answer says that not only must you not do this, but it's even a bad idea.That implies that it's a bad idea for additional reasons other than it being prohibited, or perhaps that it's prohibited due to being a bad idea, which is not so. This is just a feature of C that the C++ dialect fails to implement.
– Kaz
Apr 2 at 15:34
1
A C++ compiler is allowed to emit the translated imagemain
as if it wereextern "C"
linkage. Or to substitute a different symbol for its name entirely, like__main
or whatever. Yet, it's also allowed to ignore these considerations when compiling main, and treat it just as another function, so that themain
symbol is declared in the ordinary way. The recursive call tomain
may expect to be calling a C++ function calledmain
with ordinary C++ linkage, that supports overloading and all, yet there need not be such a symbol at all in the translation due to the special treatment.
– Kaz
Apr 2 at 15:39
1
@MatthieuBrucher Ah, OK; I misread that. The prototype could serve no useful purpose in C++.
– Kaz
Apr 2 at 15:40
|
show 2 more comments
It is not a "bad idea" at all to callmain
. C allows it; C++ makes it undefined for reasons which have nothing to do with it being a bad idea.
– Kaz
Apr 2 at 15:06
9
@Kaz It's a bad idea to do something whose behaviour is undefined.
– eerorika
Apr 2 at 15:19
@eeroika That's a circular argument. Recursivemain
that was well-defined came first. The answer says that not only must you not do this, but it's even a bad idea.That implies that it's a bad idea for additional reasons other than it being prohibited, or perhaps that it's prohibited due to being a bad idea, which is not so. This is just a feature of C that the C++ dialect fails to implement.
– Kaz
Apr 2 at 15:34
1
A C++ compiler is allowed to emit the translated imagemain
as if it wereextern "C"
linkage. Or to substitute a different symbol for its name entirely, like__main
or whatever. Yet, it's also allowed to ignore these considerations when compiling main, and treat it just as another function, so that themain
symbol is declared in the ordinary way. The recursive call tomain
may expect to be calling a C++ function calledmain
with ordinary C++ linkage, that supports overloading and all, yet there need not be such a symbol at all in the translation due to the special treatment.
– Kaz
Apr 2 at 15:39
1
@MatthieuBrucher Ah, OK; I misread that. The prototype could serve no useful purpose in C++.
– Kaz
Apr 2 at 15:40
It is not a "bad idea" at all to call
main
. C allows it; C++ makes it undefined for reasons which have nothing to do with it being a bad idea.– Kaz
Apr 2 at 15:06
It is not a "bad idea" at all to call
main
. C allows it; C++ makes it undefined for reasons which have nothing to do with it being a bad idea.– Kaz
Apr 2 at 15:06
9
9
@Kaz It's a bad idea to do something whose behaviour is undefined.
– eerorika
Apr 2 at 15:19
@Kaz It's a bad idea to do something whose behaviour is undefined.
– eerorika
Apr 2 at 15:19
@eeroika That's a circular argument. Recursive
main
that was well-defined came first. The answer says that not only must you not do this, but it's even a bad idea.That implies that it's a bad idea for additional reasons other than it being prohibited, or perhaps that it's prohibited due to being a bad idea, which is not so. This is just a feature of C that the C++ dialect fails to implement.– Kaz
Apr 2 at 15:34
@eeroika That's a circular argument. Recursive
main
that was well-defined came first. The answer says that not only must you not do this, but it's even a bad idea.That implies that it's a bad idea for additional reasons other than it being prohibited, or perhaps that it's prohibited due to being a bad idea, which is not so. This is just a feature of C that the C++ dialect fails to implement.– Kaz
Apr 2 at 15:34
1
1
A C++ compiler is allowed to emit the translated image
main
as if it were extern "C"
linkage. Or to substitute a different symbol for its name entirely, like __main
or whatever. Yet, it's also allowed to ignore these considerations when compiling main, and treat it just as another function, so that the main
symbol is declared in the ordinary way. The recursive call to main
may expect to be calling a C++ function called main
with ordinary C++ linkage, that supports overloading and all, yet there need not be such a symbol at all in the translation due to the special treatment.– Kaz
Apr 2 at 15:39
A C++ compiler is allowed to emit the translated image
main
as if it were extern "C"
linkage. Or to substitute a different symbol for its name entirely, like __main
or whatever. Yet, it's also allowed to ignore these considerations when compiling main, and treat it just as another function, so that the main
symbol is declared in the ordinary way. The recursive call to main
may expect to be calling a C++ function called main
with ordinary C++ linkage, that supports overloading and all, yet there need not be such a symbol at all in the translation due to the special treatment.– Kaz
Apr 2 at 15:39
1
1
@MatthieuBrucher Ah, OK; I misread that. The prototype could serve no useful purpose in C++.
– Kaz
Apr 2 at 15:40
@MatthieuBrucher Ah, OK; I misread that. The prototype could serve no useful purpose in C++.
– Kaz
Apr 2 at 15:40
|
show 2 more comments
No, the compiler does not need a forward declaration for main()
.
main()
is a special function in C++.
Some important things to remember about main() are:
- The linker requires that one and only one
main()
function exist when creating an executable program. - The compiler expects a main() function in one of the following two forms:
int main () { /* body */ }
int main (int argc, char *argv) { /* body */ }
where body
is zero or more statements
An additional acceptable form is implementation specific and provides a list of the environment variables at the time the function is called:
int main (int argc, char* argv, char *envp) { /* body */ }
The coder must provide the 'definition' of main using one of these acceptable forms, but the coder does not need to provide a declaration. The coded definiton is accepted by the compiler as the declaration of main().
- If no return statement is provided, the compiler will provide a
return 0;
as the last statement in the function body.
As an aside, there is sometimes confusion about whether a C++ program can make a call to main(). This is not recommended. The C++17 draft states that main() "shall not be used within a program." In other words, cannot be called from within a program. See e.g. Working Draft Standard for C++ Programming Language, dated "2017-03-21", Paragraph 6.6.1.3, page 66. I realize that some compilers support this (including mine), but the next version of the compiler could modify or remove that behavior as the standard uses the term "shall not".
Also note that the standard allows other implementation-defined signatures for main besides the two you listed here. A common option is to add a 3rd argument (after argv) that contains the environment variables (using the same method asextern char** environ
)
– SJL
Apr 1 at 19:51
@SJL: Absolutely! I have only listed the ones that "must" be implemented by the compiler. Theenviron
is also very helpful.
– Gardener
Apr 1 at 19:52
8
"compiler does not need a declaration formain()
" Every definition is a declaration, so I think the wording needs to be adjusted. "compiler declares it as one of the following two functions" Why "compiler declares"? We always provide a definition formain
ourselves.
– HolyBlackCat
Apr 1 at 20:02
1
@HolyBlackCat: I see your point. Wording is important. Even if I change it, without quoting the entire standard, there will not be a complete answer. The answer is meant to be simple. See what you think of this update.
– Gardener
Apr 1 at 20:14
6
There's nothing special about the main function with regards to (forward) declaration. That's simply a red herring. Rather, we don't need to forward declare it since we're not referring to it before its definition. That's all.
– Konrad Rudolph
Apr 1 at 22:19
add a comment |
No, the compiler does not need a forward declaration for main()
.
main()
is a special function in C++.
Some important things to remember about main() are:
- The linker requires that one and only one
main()
function exist when creating an executable program. - The compiler expects a main() function in one of the following two forms:
int main () { /* body */ }
int main (int argc, char *argv) { /* body */ }
where body
is zero or more statements
An additional acceptable form is implementation specific and provides a list of the environment variables at the time the function is called:
int main (int argc, char* argv, char *envp) { /* body */ }
The coder must provide the 'definition' of main using one of these acceptable forms, but the coder does not need to provide a declaration. The coded definiton is accepted by the compiler as the declaration of main().
- If no return statement is provided, the compiler will provide a
return 0;
as the last statement in the function body.
As an aside, there is sometimes confusion about whether a C++ program can make a call to main(). This is not recommended. The C++17 draft states that main() "shall not be used within a program." In other words, cannot be called from within a program. See e.g. Working Draft Standard for C++ Programming Language, dated "2017-03-21", Paragraph 6.6.1.3, page 66. I realize that some compilers support this (including mine), but the next version of the compiler could modify or remove that behavior as the standard uses the term "shall not".
Also note that the standard allows other implementation-defined signatures for main besides the two you listed here. A common option is to add a 3rd argument (after argv) that contains the environment variables (using the same method asextern char** environ
)
– SJL
Apr 1 at 19:51
@SJL: Absolutely! I have only listed the ones that "must" be implemented by the compiler. Theenviron
is also very helpful.
– Gardener
Apr 1 at 19:52
8
"compiler does not need a declaration formain()
" Every definition is a declaration, so I think the wording needs to be adjusted. "compiler declares it as one of the following two functions" Why "compiler declares"? We always provide a definition formain
ourselves.
– HolyBlackCat
Apr 1 at 20:02
1
@HolyBlackCat: I see your point. Wording is important. Even if I change it, without quoting the entire standard, there will not be a complete answer. The answer is meant to be simple. See what you think of this update.
– Gardener
Apr 1 at 20:14
6
There's nothing special about the main function with regards to (forward) declaration. That's simply a red herring. Rather, we don't need to forward declare it since we're not referring to it before its definition. That's all.
– Konrad Rudolph
Apr 1 at 22:19
add a comment |
No, the compiler does not need a forward declaration for main()
.
main()
is a special function in C++.
Some important things to remember about main() are:
- The linker requires that one and only one
main()
function exist when creating an executable program. - The compiler expects a main() function in one of the following two forms:
int main () { /* body */ }
int main (int argc, char *argv) { /* body */ }
where body
is zero or more statements
An additional acceptable form is implementation specific and provides a list of the environment variables at the time the function is called:
int main (int argc, char* argv, char *envp) { /* body */ }
The coder must provide the 'definition' of main using one of these acceptable forms, but the coder does not need to provide a declaration. The coded definiton is accepted by the compiler as the declaration of main().
- If no return statement is provided, the compiler will provide a
return 0;
as the last statement in the function body.
As an aside, there is sometimes confusion about whether a C++ program can make a call to main(). This is not recommended. The C++17 draft states that main() "shall not be used within a program." In other words, cannot be called from within a program. See e.g. Working Draft Standard for C++ Programming Language, dated "2017-03-21", Paragraph 6.6.1.3, page 66. I realize that some compilers support this (including mine), but the next version of the compiler could modify or remove that behavior as the standard uses the term "shall not".
No, the compiler does not need a forward declaration for main()
.
main()
is a special function in C++.
Some important things to remember about main() are:
- The linker requires that one and only one
main()
function exist when creating an executable program. - The compiler expects a main() function in one of the following two forms:
int main () { /* body */ }
int main (int argc, char *argv) { /* body */ }
where body
is zero or more statements
An additional acceptable form is implementation specific and provides a list of the environment variables at the time the function is called:
int main (int argc, char* argv, char *envp) { /* body */ }
The coder must provide the 'definition' of main using one of these acceptable forms, but the coder does not need to provide a declaration. The coded definiton is accepted by the compiler as the declaration of main().
- If no return statement is provided, the compiler will provide a
return 0;
as the last statement in the function body.
As an aside, there is sometimes confusion about whether a C++ program can make a call to main(). This is not recommended. The C++17 draft states that main() "shall not be used within a program." In other words, cannot be called from within a program. See e.g. Working Draft Standard for C++ Programming Language, dated "2017-03-21", Paragraph 6.6.1.3, page 66. I realize that some compilers support this (including mine), but the next version of the compiler could modify or remove that behavior as the standard uses the term "shall not".
edited Apr 2 at 10:02
iMalinowski
10914
10914
answered Apr 1 at 14:58
GardenerGardener
1,5101616
1,5101616
Also note that the standard allows other implementation-defined signatures for main besides the two you listed here. A common option is to add a 3rd argument (after argv) that contains the environment variables (using the same method asextern char** environ
)
– SJL
Apr 1 at 19:51
@SJL: Absolutely! I have only listed the ones that "must" be implemented by the compiler. Theenviron
is also very helpful.
– Gardener
Apr 1 at 19:52
8
"compiler does not need a declaration formain()
" Every definition is a declaration, so I think the wording needs to be adjusted. "compiler declares it as one of the following two functions" Why "compiler declares"? We always provide a definition formain
ourselves.
– HolyBlackCat
Apr 1 at 20:02
1
@HolyBlackCat: I see your point. Wording is important. Even if I change it, without quoting the entire standard, there will not be a complete answer. The answer is meant to be simple. See what you think of this update.
– Gardener
Apr 1 at 20:14
6
There's nothing special about the main function with regards to (forward) declaration. That's simply a red herring. Rather, we don't need to forward declare it since we're not referring to it before its definition. That's all.
– Konrad Rudolph
Apr 1 at 22:19
add a comment |
Also note that the standard allows other implementation-defined signatures for main besides the two you listed here. A common option is to add a 3rd argument (after argv) that contains the environment variables (using the same method asextern char** environ
)
– SJL
Apr 1 at 19:51
@SJL: Absolutely! I have only listed the ones that "must" be implemented by the compiler. Theenviron
is also very helpful.
– Gardener
Apr 1 at 19:52
8
"compiler does not need a declaration formain()
" Every definition is a declaration, so I think the wording needs to be adjusted. "compiler declares it as one of the following two functions" Why "compiler declares"? We always provide a definition formain
ourselves.
– HolyBlackCat
Apr 1 at 20:02
1
@HolyBlackCat: I see your point. Wording is important. Even if I change it, without quoting the entire standard, there will not be a complete answer. The answer is meant to be simple. See what you think of this update.
– Gardener
Apr 1 at 20:14
6
There's nothing special about the main function with regards to (forward) declaration. That's simply a red herring. Rather, we don't need to forward declare it since we're not referring to it before its definition. That's all.
– Konrad Rudolph
Apr 1 at 22:19
Also note that the standard allows other implementation-defined signatures for main besides the two you listed here. A common option is to add a 3rd argument (after argv) that contains the environment variables (using the same method as
extern char** environ
)– SJL
Apr 1 at 19:51
Also note that the standard allows other implementation-defined signatures for main besides the two you listed here. A common option is to add a 3rd argument (after argv) that contains the environment variables (using the same method as
extern char** environ
)– SJL
Apr 1 at 19:51
@SJL: Absolutely! I have only listed the ones that "must" be implemented by the compiler. The
environ
is also very helpful.– Gardener
Apr 1 at 19:52
@SJL: Absolutely! I have only listed the ones that "must" be implemented by the compiler. The
environ
is also very helpful.– Gardener
Apr 1 at 19:52
8
8
"compiler does not need a declaration for
main()
" Every definition is a declaration, so I think the wording needs to be adjusted. "compiler declares it as one of the following two functions" Why "compiler declares"? We always provide a definition for main
ourselves.– HolyBlackCat
Apr 1 at 20:02
"compiler does not need a declaration for
main()
" Every definition is a declaration, so I think the wording needs to be adjusted. "compiler declares it as one of the following two functions" Why "compiler declares"? We always provide a definition for main
ourselves.– HolyBlackCat
Apr 1 at 20:02
1
1
@HolyBlackCat: I see your point. Wording is important. Even if I change it, without quoting the entire standard, there will not be a complete answer. The answer is meant to be simple. See what you think of this update.
– Gardener
Apr 1 at 20:14
@HolyBlackCat: I see your point. Wording is important. Even if I change it, without quoting the entire standard, there will not be a complete answer. The answer is meant to be simple. See what you think of this update.
– Gardener
Apr 1 at 20:14
6
6
There's nothing special about the main function with regards to (forward) declaration. That's simply a red herring. Rather, we don't need to forward declare it since we're not referring to it before its definition. That's all.
– Konrad Rudolph
Apr 1 at 22:19
There's nothing special about the main function with regards to (forward) declaration. That's simply a red herring. Rather, we don't need to forward declare it since we're not referring to it before its definition. That's all.
– Konrad Rudolph
Apr 1 at 22:19
add a comment |
It is illegal to call main
from inside your program. That means the only thing that is going to call it is the runtime and the compiler/linker can handle setting that up.This means you do not need a prototype for main
.
add a comment |
It is illegal to call main
from inside your program. That means the only thing that is going to call it is the runtime and the compiler/linker can handle setting that up.This means you do not need a prototype for main
.
add a comment |
It is illegal to call main
from inside your program. That means the only thing that is going to call it is the runtime and the compiler/linker can handle setting that up.This means you do not need a prototype for main
.
It is illegal to call main
from inside your program. That means the only thing that is going to call it is the runtime and the compiler/linker can handle setting that up.This means you do not need a prototype for main
.
answered Apr 1 at 14:41
NathanOliverNathanOliver
98.2k16138217
98.2k16138217
add a comment |
add a comment |
A definition of a function also implicitly declares it. If you need to reference a function before it is defined you need to declare it before you use it.
So writing the following is also valid:
int sum(int x, int y) {
return x + y;
}
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
If you use a declaration in one file to make a function known to the compiler before it is defined, then its definition has to be known at linking time:
main.cpp
int sum(int x, int y);
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
sum.cpp
int sum(int x, int y) {
return x + y;
}
Or sum
could have its origin in a library, so you do not even compile it yourself.
The main
function is not used/referenced in your code anywhere, so there is no need to add the declaration of main
anywhere.
Before and after your main
function the c++ library might execute some init and cleanup steps, and will call your main
function. If that part of the library would be represented as c++ code then it would contain a declaration of int main()
so that that it could be compiled. That code could look like this:
int main();
int __main() {
__startup_runtime();
main();
__cleanup_runtime();
}
But then you again have the same problem with __main
so at some point there is no c++ anymore and a certain function (main
) just represents the entry point of your code.
C++ makes it UB to callmain
from inside the program, so C++ compilers can put those startup/cleanup calls right into the realmain
if they want. This rule lets C++ compilers work on top of C environments, for example, giving somewhere for static constructors to be called from if there's no other mechanism a compiler can use. (Compilers also have to recognizemain
as a special function name to give it an implicitreturn 0
.)
– Peter Cordes
Apr 2 at 11:06
@PeterCordes from the perspective of the programmer it is UB to call themain
function due to the the standard. But how the compile vendors or the os handlesmain
is implementation dependent. So in theory the compiled result of themain
could look like a regular function that is called by the run-time, or it could not exists and as you said, the compilers can put those startup/cleanup calls right at the entry point of the application around the code that is shown in themain
.
– t.niese
Apr 2 at 11:40
Yup, in most implementations it is just a normal function (but with an implicitextern "C"
to not do C++ name mangling on it, so the CRT startup code can link to it regardless of function signature), with real init work done in CRT code and/or from dynamic linker hooks. But like I commented Joshua's answer, ICC (Intel's compiler) does in fact add some startup code insidemain
itself (godbolt.org/z/oWlmlc), including setting DAZ and FTZ to disable subnormals for its default of-ffast-math
. gcc/clang link different CRT startup files for fast-math or not.
– Peter Cordes
Apr 2 at 12:13
add a comment |
A definition of a function also implicitly declares it. If you need to reference a function before it is defined you need to declare it before you use it.
So writing the following is also valid:
int sum(int x, int y) {
return x + y;
}
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
If you use a declaration in one file to make a function known to the compiler before it is defined, then its definition has to be known at linking time:
main.cpp
int sum(int x, int y);
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
sum.cpp
int sum(int x, int y) {
return x + y;
}
Or sum
could have its origin in a library, so you do not even compile it yourself.
The main
function is not used/referenced in your code anywhere, so there is no need to add the declaration of main
anywhere.
Before and after your main
function the c++ library might execute some init and cleanup steps, and will call your main
function. If that part of the library would be represented as c++ code then it would contain a declaration of int main()
so that that it could be compiled. That code could look like this:
int main();
int __main() {
__startup_runtime();
main();
__cleanup_runtime();
}
But then you again have the same problem with __main
so at some point there is no c++ anymore and a certain function (main
) just represents the entry point of your code.
C++ makes it UB to callmain
from inside the program, so C++ compilers can put those startup/cleanup calls right into the realmain
if they want. This rule lets C++ compilers work on top of C environments, for example, giving somewhere for static constructors to be called from if there's no other mechanism a compiler can use. (Compilers also have to recognizemain
as a special function name to give it an implicitreturn 0
.)
– Peter Cordes
Apr 2 at 11:06
@PeterCordes from the perspective of the programmer it is UB to call themain
function due to the the standard. But how the compile vendors or the os handlesmain
is implementation dependent. So in theory the compiled result of themain
could look like a regular function that is called by the run-time, or it could not exists and as you said, the compilers can put those startup/cleanup calls right at the entry point of the application around the code that is shown in themain
.
– t.niese
Apr 2 at 11:40
Yup, in most implementations it is just a normal function (but with an implicitextern "C"
to not do C++ name mangling on it, so the CRT startup code can link to it regardless of function signature), with real init work done in CRT code and/or from dynamic linker hooks. But like I commented Joshua's answer, ICC (Intel's compiler) does in fact add some startup code insidemain
itself (godbolt.org/z/oWlmlc), including setting DAZ and FTZ to disable subnormals for its default of-ffast-math
. gcc/clang link different CRT startup files for fast-math or not.
– Peter Cordes
Apr 2 at 12:13
add a comment |
A definition of a function also implicitly declares it. If you need to reference a function before it is defined you need to declare it before you use it.
So writing the following is also valid:
int sum(int x, int y) {
return x + y;
}
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
If you use a declaration in one file to make a function known to the compiler before it is defined, then its definition has to be known at linking time:
main.cpp
int sum(int x, int y);
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
sum.cpp
int sum(int x, int y) {
return x + y;
}
Or sum
could have its origin in a library, so you do not even compile it yourself.
The main
function is not used/referenced in your code anywhere, so there is no need to add the declaration of main
anywhere.
Before and after your main
function the c++ library might execute some init and cleanup steps, and will call your main
function. If that part of the library would be represented as c++ code then it would contain a declaration of int main()
so that that it could be compiled. That code could look like this:
int main();
int __main() {
__startup_runtime();
main();
__cleanup_runtime();
}
But then you again have the same problem with __main
so at some point there is no c++ anymore and a certain function (main
) just represents the entry point of your code.
A definition of a function also implicitly declares it. If you need to reference a function before it is defined you need to declare it before you use it.
So writing the following is also valid:
int sum(int x, int y) {
return x + y;
}
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
If you use a declaration in one file to make a function known to the compiler before it is defined, then its definition has to be known at linking time:
main.cpp
int sum(int x, int y);
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
sum.cpp
int sum(int x, int y) {
return x + y;
}
Or sum
could have its origin in a library, so you do not even compile it yourself.
The main
function is not used/referenced in your code anywhere, so there is no need to add the declaration of main
anywhere.
Before and after your main
function the c++ library might execute some init and cleanup steps, and will call your main
function. If that part of the library would be represented as c++ code then it would contain a declaration of int main()
so that that it could be compiled. That code could look like this:
int main();
int __main() {
__startup_runtime();
main();
__cleanup_runtime();
}
But then you again have the same problem with __main
so at some point there is no c++ anymore and a certain function (main
) just represents the entry point of your code.
edited Apr 1 at 20:49
answered Apr 1 at 20:29
t.nieset.niese
22.7k64066
22.7k64066
C++ makes it UB to callmain
from inside the program, so C++ compilers can put those startup/cleanup calls right into the realmain
if they want. This rule lets C++ compilers work on top of C environments, for example, giving somewhere for static constructors to be called from if there's no other mechanism a compiler can use. (Compilers also have to recognizemain
as a special function name to give it an implicitreturn 0
.)
– Peter Cordes
Apr 2 at 11:06
@PeterCordes from the perspective of the programmer it is UB to call themain
function due to the the standard. But how the compile vendors or the os handlesmain
is implementation dependent. So in theory the compiled result of themain
could look like a regular function that is called by the run-time, or it could not exists and as you said, the compilers can put those startup/cleanup calls right at the entry point of the application around the code that is shown in themain
.
– t.niese
Apr 2 at 11:40
Yup, in most implementations it is just a normal function (but with an implicitextern "C"
to not do C++ name mangling on it, so the CRT startup code can link to it regardless of function signature), with real init work done in CRT code and/or from dynamic linker hooks. But like I commented Joshua's answer, ICC (Intel's compiler) does in fact add some startup code insidemain
itself (godbolt.org/z/oWlmlc), including setting DAZ and FTZ to disable subnormals for its default of-ffast-math
. gcc/clang link different CRT startup files for fast-math or not.
– Peter Cordes
Apr 2 at 12:13
add a comment |
C++ makes it UB to callmain
from inside the program, so C++ compilers can put those startup/cleanup calls right into the realmain
if they want. This rule lets C++ compilers work on top of C environments, for example, giving somewhere for static constructors to be called from if there's no other mechanism a compiler can use. (Compilers also have to recognizemain
as a special function name to give it an implicitreturn 0
.)
– Peter Cordes
Apr 2 at 11:06
@PeterCordes from the perspective of the programmer it is UB to call themain
function due to the the standard. But how the compile vendors or the os handlesmain
is implementation dependent. So in theory the compiled result of themain
could look like a regular function that is called by the run-time, or it could not exists and as you said, the compilers can put those startup/cleanup calls right at the entry point of the application around the code that is shown in themain
.
– t.niese
Apr 2 at 11:40
Yup, in most implementations it is just a normal function (but with an implicitextern "C"
to not do C++ name mangling on it, so the CRT startup code can link to it regardless of function signature), with real init work done in CRT code and/or from dynamic linker hooks. But like I commented Joshua's answer, ICC (Intel's compiler) does in fact add some startup code insidemain
itself (godbolt.org/z/oWlmlc), including setting DAZ and FTZ to disable subnormals for its default of-ffast-math
. gcc/clang link different CRT startup files for fast-math or not.
– Peter Cordes
Apr 2 at 12:13
C++ makes it UB to call
main
from inside the program, so C++ compilers can put those startup/cleanup calls right into the real main
if they want. This rule lets C++ compilers work on top of C environments, for example, giving somewhere for static constructors to be called from if there's no other mechanism a compiler can use. (Compilers also have to recognize main
as a special function name to give it an implicit return 0
.)– Peter Cordes
Apr 2 at 11:06
C++ makes it UB to call
main
from inside the program, so C++ compilers can put those startup/cleanup calls right into the real main
if they want. This rule lets C++ compilers work on top of C environments, for example, giving somewhere for static constructors to be called from if there's no other mechanism a compiler can use. (Compilers also have to recognize main
as a special function name to give it an implicit return 0
.)– Peter Cordes
Apr 2 at 11:06
@PeterCordes from the perspective of the programmer it is UB to call the
main
function due to the the standard. But how the compile vendors or the os handles main
is implementation dependent. So in theory the compiled result of the main
could look like a regular function that is called by the run-time, or it could not exists and as you said, the compilers can put those startup/cleanup calls right at the entry point of the application around the code that is shown in the main
.– t.niese
Apr 2 at 11:40
@PeterCordes from the perspective of the programmer it is UB to call the
main
function due to the the standard. But how the compile vendors or the os handles main
is implementation dependent. So in theory the compiled result of the main
could look like a regular function that is called by the run-time, or it could not exists and as you said, the compilers can put those startup/cleanup calls right at the entry point of the application around the code that is shown in the main
.– t.niese
Apr 2 at 11:40
Yup, in most implementations it is just a normal function (but with an implicit
extern "C"
to not do C++ name mangling on it, so the CRT startup code can link to it regardless of function signature), with real init work done in CRT code and/or from dynamic linker hooks. But like I commented Joshua's answer, ICC (Intel's compiler) does in fact add some startup code inside main
itself (godbolt.org/z/oWlmlc), including setting DAZ and FTZ to disable subnormals for its default of -ffast-math
. gcc/clang link different CRT startup files for fast-math or not.– Peter Cordes
Apr 2 at 12:13
Yup, in most implementations it is just a normal function (but with an implicit
extern "C"
to not do C++ name mangling on it, so the CRT startup code can link to it regardless of function signature), with real init work done in CRT code and/or from dynamic linker hooks. But like I commented Joshua's answer, ICC (Intel's compiler) does in fact add some startup code inside main
itself (godbolt.org/z/oWlmlc), including setting DAZ and FTZ to disable subnormals for its default of -ffast-math
. gcc/clang link different CRT startup files for fast-math or not.– Peter Cordes
Apr 2 at 12:13
add a comment |
Nope. You can't call it anyway.
You only need forward declarations for functions called before they are defined. You need external declarations (which look exactly like forward declarations on purpose) for functions defined in other files.
But you can't call main
in C++ so you don't need one. This is because the C++ compiler is allowed to modify main to do global initialization.
[I looked at crt0.c and it does have a declaration for main but that's neither here nor there].
You can callmain
, it's just typically bad practice.
– Cruz Jean
Apr 1 at 14:40
8
@CruzJean not just a bad practice, it's undefined behavior as far as I know
– Guillaume Racicot
Apr 1 at 14:41
5
@CruzJean Not bad practice. Calling it invokes undefined behavior.
– Algirdas Preidžius
Apr 1 at 14:42
@AlgirdasPreidžius Ah, I stand corrected. Never knew about that.
– Cruz Jean
Apr 1 at 14:46
This is because the C++ compiler is allowed to modify main to do global initialization. Is it? I can't see how that would even work as you would be assigning inmain
which can change the observable effects of the program.
– NathanOliver
Apr 1 at 14:54
|
show 3 more comments
Nope. You can't call it anyway.
You only need forward declarations for functions called before they are defined. You need external declarations (which look exactly like forward declarations on purpose) for functions defined in other files.
But you can't call main
in C++ so you don't need one. This is because the C++ compiler is allowed to modify main to do global initialization.
[I looked at crt0.c and it does have a declaration for main but that's neither here nor there].
You can callmain
, it's just typically bad practice.
– Cruz Jean
Apr 1 at 14:40
8
@CruzJean not just a bad practice, it's undefined behavior as far as I know
– Guillaume Racicot
Apr 1 at 14:41
5
@CruzJean Not bad practice. Calling it invokes undefined behavior.
– Algirdas Preidžius
Apr 1 at 14:42
@AlgirdasPreidžius Ah, I stand corrected. Never knew about that.
– Cruz Jean
Apr 1 at 14:46
This is because the C++ compiler is allowed to modify main to do global initialization. Is it? I can't see how that would even work as you would be assigning inmain
which can change the observable effects of the program.
– NathanOliver
Apr 1 at 14:54
|
show 3 more comments
Nope. You can't call it anyway.
You only need forward declarations for functions called before they are defined. You need external declarations (which look exactly like forward declarations on purpose) for functions defined in other files.
But you can't call main
in C++ so you don't need one. This is because the C++ compiler is allowed to modify main to do global initialization.
[I looked at crt0.c and it does have a declaration for main but that's neither here nor there].
Nope. You can't call it anyway.
You only need forward declarations for functions called before they are defined. You need external declarations (which look exactly like forward declarations on purpose) for functions defined in other files.
But you can't call main
in C++ so you don't need one. This is because the C++ compiler is allowed to modify main to do global initialization.
[I looked at crt0.c and it does have a declaration for main but that's neither here nor there].
edited Apr 1 at 14:44
answered Apr 1 at 14:39
JoshuaJoshua
24.4k550104
24.4k550104
You can callmain
, it's just typically bad practice.
– Cruz Jean
Apr 1 at 14:40
8
@CruzJean not just a bad practice, it's undefined behavior as far as I know
– Guillaume Racicot
Apr 1 at 14:41
5
@CruzJean Not bad practice. Calling it invokes undefined behavior.
– Algirdas Preidžius
Apr 1 at 14:42
@AlgirdasPreidžius Ah, I stand corrected. Never knew about that.
– Cruz Jean
Apr 1 at 14:46
This is because the C++ compiler is allowed to modify main to do global initialization. Is it? I can't see how that would even work as you would be assigning inmain
which can change the observable effects of the program.
– NathanOliver
Apr 1 at 14:54
|
show 3 more comments
You can callmain
, it's just typically bad practice.
– Cruz Jean
Apr 1 at 14:40
8
@CruzJean not just a bad practice, it's undefined behavior as far as I know
– Guillaume Racicot
Apr 1 at 14:41
5
@CruzJean Not bad practice. Calling it invokes undefined behavior.
– Algirdas Preidžius
Apr 1 at 14:42
@AlgirdasPreidžius Ah, I stand corrected. Never knew about that.
– Cruz Jean
Apr 1 at 14:46
This is because the C++ compiler is allowed to modify main to do global initialization. Is it? I can't see how that would even work as you would be assigning inmain
which can change the observable effects of the program.
– NathanOliver
Apr 1 at 14:54
You can call
main
, it's just typically bad practice.– Cruz Jean
Apr 1 at 14:40
You can call
main
, it's just typically bad practice.– Cruz Jean
Apr 1 at 14:40
8
8
@CruzJean not just a bad practice, it's undefined behavior as far as I know
– Guillaume Racicot
Apr 1 at 14:41
@CruzJean not just a bad practice, it's undefined behavior as far as I know
– Guillaume Racicot
Apr 1 at 14:41
5
5
@CruzJean Not bad practice. Calling it invokes undefined behavior.
– Algirdas Preidžius
Apr 1 at 14:42
@CruzJean Not bad practice. Calling it invokes undefined behavior.
– Algirdas Preidžius
Apr 1 at 14:42
@AlgirdasPreidžius Ah, I stand corrected. Never knew about that.
– Cruz Jean
Apr 1 at 14:46
@AlgirdasPreidžius Ah, I stand corrected. Never knew about that.
– Cruz Jean
Apr 1 at 14:46
This is because the C++ compiler is allowed to modify main to do global initialization. Is it? I can't see how that would even work as you would be assigning in
main
which can change the observable effects of the program.– NathanOliver
Apr 1 at 14:54
This is because the C++ compiler is allowed to modify main to do global initialization. Is it? I can't see how that would even work as you would be assigning in
main
which can change the observable effects of the program.– NathanOliver
Apr 1 at 14:54
|
show 3 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55457704%2fdoes-int-main-need-a-declaration-on-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
17
Manually calling main invokes undefined behaviour.
– George
Apr 1 at 14:40
23
@MichaelStachowsky -- in C you're allowed to call
main
. In C++ you aren't; it isn't "just a function" -- it's special. Historically, the reason is that compilers added code tomain
to initialize global variables that required dynamic initialization; callingmain
from inside the program would re-initialize those variables, and the result would be chaos.– Pete Becker
Apr 1 at 16:41
26
@Michael That you've tried something and found that "it works just fine" does not prove that something is not undefined behavior.
– Cody Gray♦
Apr 1 at 16:53
7
As an aside, you don't need a declaration for
sum
if you put the definition above main in the file. For this reason, it is common to seemain
as the last function in C and C++ source code, so you don't need to have forward declarations for other functions defined in that file. Not like C# and Java that often putmain
first, although it is not required in those cases.– Cody
Apr 1 at 16:59
10
Technically your example code has declared
main
, a definition of a function also declares the function. That's why you can movesum
beforemain
to avoid having to separately declaresum
.– Ross Ridge
Apr 1 at 18:49