Is it legal to recurse into main() in C++? [duplicate] - c++

This question already has answers here:
Can main function call itself in C++?
(9 answers)
Closed 4 years ago.
I read that the C++ standard forbids recursion in main(), but g++ compiles the following code without complaint:
int main()
{
main();
}
Can anyone clarify this?

According to the standard in 3.6.1/3, it's not :
The function main shall not be used
(3.2) within a program
The definition of used being :
An object or non-overloaded
function is used if its name appears in a potentially-evaluated expression.

I'll do the fish and explain why this is verboten. Before a C or C++ program can start running, the CRT has to be initialized first. Open stdin/out/err, call initializers, that sort of thing. There are two basic strategies to get this done, a heavy platform implementation detail.
The program's start address points to the CRT init function, which eventually calls main(). Common on full-featured operating systems that have a fancy loader which can support arbitrary sections in the executable image.
The compiler injects code into the main() function that calls the CRT initialization function. The start function is always main(). Common on embedded platforms with limited loader capabilities. Recursing main() is now a problem, the CRT startup code will be called again with an unpredictable stack state.

The claim here is that it is indeed specifically forbidden:
Well, the standard states:
3.6.1.3
"The function main shall not be used within a program."
5.2.2.9
"Recursive calls are permitted, except to the function named main"
You can, of course, do this:
int main(int argc, char* argv[]) {
return foo(argc, argv);
}
int foo(int argc, char* argv[]) {
if (some_condition) {
return foo(argc, argv);
}
return 0;
}
(Note I added a get-out clause. I can't even hypothetically code infinite recursion, it repeats on me.)

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

Other people have addressed the standards part. However, I'd like to note that g++ (at least 4.6.2) will reject this if you use -pedantic-errors with at least one of these errors (depending on main signature):
error: ISO C++ forbids calling ‘::main’ from within program [-pedantic]
error: ISO C++ forbids taking address of function ‘::main’ [-pedantic]

Related

Explicitly passing *this in C++

While reading about *this, I saw:
When a nonstatic member function is called for an object, the compiler
passes the object's address to the function as a hidden argument.
Then I tried:
#include <iostream>
class MyClass
{
int myVar;
public:
MyClass(const int& val) : myVar{val} {}
// int getVar(MyClass* this) <-- Error: expected ',' or '...' before 'this'
int getVar()
{
return this->myVar;
}
};
int main()
{
MyClass obj(22);
// std::cout << obj.getVar(&obj); <-- Error: no matching function
// std::cout << MyClass::getVar(&obj); <-- Error: no matching function
std::cout << obj.getVar();
return 0;
}
Why am I not able to access the hidden argument? Is it called 'hidden' because of that?
Are only compilers allowed to do this? Can't we explicitly mention *this in the function signature?
The closest answer I've found before asking this is this. But I tried that way and still got the error. Could I get an explanation of those error messages? Because, if the compiler actually modifies those function signatures to contain *this then that should have worked, isn't it?
Are only compilers allowed to do this?
Precisely. That's why it's called hidden: It's something that the compiler does on your behalf, but which is hidden from the C++ code that uses it.
The compiler must pass the this pointer to the member function somehow, but it does not need to tell you how it does it. It could compile the code to the equivalent of MyClass::getVar(&obj), passing the this pointer in the same way that it would pass the argument for the C function free(foo). Or it might use a different mechanism that is totally incompatible with non-member argument passing. What it does under the hood is defined by the platform's Abstract Binary Interface standard (ABI), which is not part of the C++ language standard. What happens under Windows could be vastly different from what happens under Linux, and Linux on ARM could be different from Linux on X86, etc.
That said, you can take a look at what actually happens by telling your compiler to produce the assembly code. For gcc, the incantation would be
g++ -S -Os interestingCode.cpp
This will produce a .s file that contains how g++ actually translated your code.
obj.getVar(&obj)
This version cannot compile because the getVar() member function is not declared to take any parameters.
MyClass::getVar(&obj)
This version is using the syntax to access a static function but getVar() is not static, nor does it accept any parameters.
Note: The obj.getVar() call works because it is specifying which object instance to use (i.e., the obj. part) to execute the member function and is conceptually how the member function is passed the this pointer.
When you are doing obj.getVar() it is already explicitly specified the pointer *this=&obj and passed implicitly to getVar. It is not hidden. It is explicitly passed leftside of the function. You can use obj.getVar() or ptrObj->getVar() but in C++ is not allowed to use such construction getVar(thisptr). Hidden means the variable named this is nowhere declared, but you can use inside the function.

LNK2019 unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ) [duplicate]

Questions
What is the proper signature of the main function in C++?
What is the correct return type, and what does it mean to return a value from main?
What are the allowed parameter types, and what are their meanings?
Is this system-specific?
Have those rules changed over time?
What happens if I violate them?
The main function must be declared as a non-member function in the global namespace. This means that it cannot be a static or non-static member function of a class, nor can it be placed in a namespace (even the unnamed namespace).
The name main is not reserved in C++ except as a function in the global namespace. You are free to declare other entities named main, including among other things, classes, variables, enumerations, member functions, and non-member functions not in the global namespace.
You can declare a function named main as a member function or in a namespace, but such a function would not be the main function that designates where the program starts.
The main function cannot be declared as static or inline. It also cannot be overloaded; there can be only one function named main in the global namespace.
The main function cannot be used in your program: you are not allowed to call the main function from anywhere in your code, nor are you allowed to take its address.
The return type of main must be int. No other return type is allowed (this rule is in bold because it is very common to see incorrect programs that declare main with a return type of void; this is probably the most frequently violated rule concerning the main function).
There are two declarations of main that must be allowed:
int main() // (1)
int main(int, char*[]) // (2)
In (1), there are no parameters.
In (2), there are two parameters and they are conventionally named argc and argv, respectively. argv is a pointer to an array of C strings representing the arguments to the program. argc is the number of arguments in the argv array.
Usually, argv[0] contains the name of the program, but this is not always the case. argv[argc] is guaranteed to be a null pointer.
Note that since an array type argument (like char*[]) is really just a pointer type argument in disguise, the following two are both valid ways to write (2) and they both mean exactly the same thing:
int main(int argc, char* argv[])
int main(int argc, char** argv)
Some implementations may allow other types and numbers of parameters; you'd have to check the documentation of your implementation to see what it supports.
main() is expected to return zero to indicate success and non-zero to indicate failure. You are not required to explicitly write a return statement in main(): if you let main() return without an explicit return statement, it's the same as if you had written return 0;. The following two main() functions have the same behavior:
int main() { }
int main() { return 0; }
There are two macros, EXIT_SUCCESS and EXIT_FAILURE, defined in <cstdlib> that can also be returned from main() to indicate success and failure, respectively.
The value returned by main() is passed to the exit() function, which terminates the program.
Note that all of this applies only when compiling for a hosted environment (informally, an environment where you have a full standard library and there's an OS running your program). It is also possible to compile a C++ program for a freestanding environment (for example, some types of embedded systems), in which case startup and termination are wholly implementation-defined and a main() function may not even be required. If you're writing C++ for a modern desktop OS, though, you're compiling for a hosted environment.
From Standard docs., 3.6.1.2 Main Function,
It shall have a return
type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following
definitions of main:
int main() { / ... / } and
int main(int argc, char* argv[]) { / ... / }
In the latter form argc shall be the number of arguments passed to the program from the environment in which the
program is run.If argc is nonzero these arguments shall be supplied in argv[0] through argv[argc-1] as pointers to
the initial characters of null-terminated multibyte strings.....
Hope that helps..
The exact wording of the latest published standard (C++14) is:
An implementation shall allow both
a function of () returning int and
a function of (int, pointer to pointer to char) returning int
as the type of main.
This makes it clear that alternative spellings are permitted so long as the type of main is the type int() or int(int, char**). So the following are also permitted:
int main(void)
auto main() -> int
int main ( )
signed int main()
typedef char **a; typedef int b, e; e main(b d, a c)
The two valid mains are int main() and int main(int, char*[]). Any thing else may or may not compile. If main doesn't explicitly return a value, 0 is implicitly returned.
Details on return values and their meaning
Per 3.6.1 ([basic.start.main]):
A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing
return 0;
The behavior of std::exit is detailed in section 18.5 ([support.start.term]), and describes the status code:
Finally, control is returned to the host environment. If status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.

Type definition of command line arguments (argc, argv, args) [duplicate]

Questions
What is the proper signature of the main function in C++?
What is the correct return type, and what does it mean to return a value from main?
What are the allowed parameter types, and what are their meanings?
Is this system-specific?
Have those rules changed over time?
What happens if I violate them?
The main function must be declared as a non-member function in the global namespace. This means that it cannot be a static or non-static member function of a class, nor can it be placed in a namespace (even the unnamed namespace).
The name main is not reserved in C++ except as a function in the global namespace. You are free to declare other entities named main, including among other things, classes, variables, enumerations, member functions, and non-member functions not in the global namespace.
You can declare a function named main as a member function or in a namespace, but such a function would not be the main function that designates where the program starts.
The main function cannot be declared as static or inline. It also cannot be overloaded; there can be only one function named main in the global namespace.
The main function cannot be used in your program: you are not allowed to call the main function from anywhere in your code, nor are you allowed to take its address.
The return type of main must be int. No other return type is allowed (this rule is in bold because it is very common to see incorrect programs that declare main with a return type of void; this is probably the most frequently violated rule concerning the main function).
There are two declarations of main that must be allowed:
int main() // (1)
int main(int, char*[]) // (2)
In (1), there are no parameters.
In (2), there are two parameters and they are conventionally named argc and argv, respectively. argv is a pointer to an array of C strings representing the arguments to the program. argc is the number of arguments in the argv array.
Usually, argv[0] contains the name of the program, but this is not always the case. argv[argc] is guaranteed to be a null pointer.
Note that since an array type argument (like char*[]) is really just a pointer type argument in disguise, the following two are both valid ways to write (2) and they both mean exactly the same thing:
int main(int argc, char* argv[])
int main(int argc, char** argv)
Some implementations may allow other types and numbers of parameters; you'd have to check the documentation of your implementation to see what it supports.
main() is expected to return zero to indicate success and non-zero to indicate failure. You are not required to explicitly write a return statement in main(): if you let main() return without an explicit return statement, it's the same as if you had written return 0;. The following two main() functions have the same behavior:
int main() { }
int main() { return 0; }
There are two macros, EXIT_SUCCESS and EXIT_FAILURE, defined in <cstdlib> that can also be returned from main() to indicate success and failure, respectively.
The value returned by main() is passed to the exit() function, which terminates the program.
Note that all of this applies only when compiling for a hosted environment (informally, an environment where you have a full standard library and there's an OS running your program). It is also possible to compile a C++ program for a freestanding environment (for example, some types of embedded systems), in which case startup and termination are wholly implementation-defined and a main() function may not even be required. If you're writing C++ for a modern desktop OS, though, you're compiling for a hosted environment.
From Standard docs., 3.6.1.2 Main Function,
It shall have a return
type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following
definitions of main:
int main() { / ... / } and
int main(int argc, char* argv[]) { / ... / }
In the latter form argc shall be the number of arguments passed to the program from the environment in which the
program is run.If argc is nonzero these arguments shall be supplied in argv[0] through argv[argc-1] as pointers to
the initial characters of null-terminated multibyte strings.....
Hope that helps..
The exact wording of the latest published standard (C++14) is:
An implementation shall allow both
a function of () returning int and
a function of (int, pointer to pointer to char) returning int
as the type of main.
This makes it clear that alternative spellings are permitted so long as the type of main is the type int() or int(int, char**). So the following are also permitted:
int main(void)
auto main() -> int
int main ( )
signed int main()
typedef char **a; typedef int b, e; e main(b d, a c)
The two valid mains are int main() and int main(int, char*[]). Any thing else may or may not compile. If main doesn't explicitly return a value, 0 is implicitly returned.
Details on return values and their meaning
Per 3.6.1 ([basic.start.main]):
A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing
return 0;
The behavior of std::exit is detailed in section 18.5 ([support.start.term]), and describes the status code:
Finally, control is returned to the host environment. If status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.

Can we add CV-qualifiers to the arguments of main?

As far as I know, in C or C++, the signature of main should either be int main(void) (void is optional in C++) or int main(int, char**). However, the following code compiles with no warnings (-Wall -Wextra -Wpedantic) in gcc/g++/clang/clang++
int main(int, const char * const * const argv){}
Live on Coliru
Is the code above legal? In other words, can we add CV-qualifiers to the arguments of main, or is this just an extension of the compiler that requires no diagnostic?
The C++11 Standard allows the implementation to accept any signature it likes it only mandates the two presented in question. It must also have a return type of int.
3.6.1 Main Function [basic.start.main]
2 An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall
allow both of the following definitions of main:
int main() { /* ...
*/ }
and
int main(int argc, char* argv[]) { /* ...
*/ }
So to address the main question:
Can we add CV-qualifiers to the arguments of main?
We can if the implementation supports it but if we do then the code is less likely to be portable.
The code will only be fully portable if it adds (at most) cv qualifiers to the parameter variable itself, not its pointed-to types:
// still portable, same signature as int main(int, char**)
int main(int, char** const argv);
// not portable
int main(int, char* const* argv);
// not portable
int main(int, const char** argv);
Remember that C and C++ are two distinct languages. The answer happens to be pretty much the same for both, but it's worth covering what the C standard says as well -- especially given the language-lawyer tag. The link is to the N1570 draft of C11.
Section 5.1.2.2.1 covers the definition of main for hosted implementations:
The function called at program startup is named main. The
implementation declares no prototype for this function. It shall be
defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv,
though any names may be used, as they are local to the function in
which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent; or in some other implementation-defined manner.
A definition with added const or volatile qualifiers is not equivalent to the forms shown, so an implementation is not obliged to accept it. But since that section is not a constraint, an implementation is not required to complain about it either. And in particular, if an implementation documents that it accepts const and/or volatile qualifiers, then they're perfectly valid for that implementation.
(In practice, most compilers probably won't complain.)
Note that this applies only to hosted implementations. For a freestanding implementation (typically for an embedded target with no OS):
... the name and type of the function called at program
startup are implementation-defined.
(5.1.2.1 paragraph 1) which means that there are no portable definitions of the main function for freestanding implementations (it needn't even be called main).

Unexpected success of C Code

I am testing the following code in Code::Blocks v 12.11:
#include <stdio.h>
int main()
{
display();
return 0;
}
void display()
{
printf("\nHi");
}
It compiles successfully and runs well.I am unable to understand why?
My queries are as follows:
A function or variable needs to be at least declared before getting used in C/C++. Here,there is no declaration before we called the function display().
By default,all functions have return type as int.So,I am expecting a compilation error here but it went through successfully.The compiler would have assumed display() to be int display() and then we defined it as void display().
In C++, functions must be declared or defined before being use; that code cannot be C++.
In C89 or pre-standard C, if the compiler encounters an identifier followed by an open parenthesis, it is a function call, and if there is no declaration or definition in effect, then the return type is implicitly int and the number and types of the arguments is unspecified. (Thus, in the example, display() is a function returning an int and taking an indefinite — but not variable — number of arguments.)
In C99 or C11, in any strict compliance mode, you must have a declaration or definition of the function in scope before calling. It still doesn't have to be a prototype (the inferred declaration int display(); is not a prototype, and the definition is also not a prototype — it would need to be int display(void) to provide a prototype!).
Because of the inferred type for display() and the contradictory definition, you should get a compilation error, I believe. It would be at best a sloppy compiler that allowed it through, even in C89 mode. Indeed, I think even a pre-standard compiler should complain about the difference between the assumed and actual return types, but of course there was no standard so you couldn't complain (and, in any case, that standard is 24 years old now — compilers that only support that are verging on the archaic).
Which compiler (and version) are you using on which platform?
GCC 4.8.2 on Mac OS X 10.9, even with things set as permissive as possible, says:
dec.c:9:6: warning: conflicting types for ‘display’ [enabled by default]
void display()
^
dec.c:5:5: note: previous implicit declaration of ‘display’ was here
display();
^
Your code works perfectly well as a .c file and shows error when it is executed as a .cpp file
I hope this post explains why.
Why are function declaration mandatory in C++ and not in C?