This question already has answers here:
What should main() return in C and C++?
(19 answers)
Closed 9 years ago.
Does it matter which way I declare the main function in a C++ (or C) program?
The difference is one is the correct way to define main, and the other is not.
And yes, it does matter. Either
int main(int argc, char** argv)
or
int main()
are the proper definition of your main per the C++ spec.
void main(int argc, char** argv)
is not and was, IIRC, a perversity that came with older Microsoft's C++ compilers.
https://isocpp.org/wiki/faq/newbie#main-returns-int
Bjarne Stroustrup made this quite clear:
The definition void main() is not and never has been C++, nor has it even been C.
See reference.
You should use int main. Both the C and C++ standards specify that main should return a value.
For C++, only int is allowed. For C, C99 says only int is allowed. The prior standard allowed for a void return.
In short, always int.
The point is, C programs (and C++ the same) always (should?) return a success value or error code, so they should be declared that way.
A long time ago I found this page (void main(void)) which contained many reasons outside of the "the standard says it is not valid" argument. On particular operating systems/architectures it could cause the stack to become corrupted and or other nasty things to happen.
If you're going by the spec, then you should always declare main returning an int.
In reality, though, most compilers will let you get away with either one, so the real difference is if you want / need to return a value to the shell.
In C++, main() must return int. However, C99 allows main() to have a non-int return type. Here is the excerpt from the C99 standard.
5.1.2.2.1 Program startup
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.
Also note that gcc does compile void main() although practically, it does a return 0; on encountering a closing brace.
Related
This is a thought experiment.
This question is intentionally trying to do something easy in a difficult way. I am aware of the many ways to do this using iostream, std.h, etc. Please do not suggest answers that circumvent the challenge.
Using C++,
Only using main() without any header files included, is it possible to write a program that creates a variable of any type, and outputs the value of the variable in any way, such as printing it in console, saving it to a file, anything like that?
The goal is to have a .main file that looks like:
int main(){
Some code;
return 0;
}
I've tried using C's printf but that requires a header.
The best I could come up with is saving the value to a specific space in memory then using another program to read that block. But that is somewhat circumventing the goal of outputting only from main.
This may be impossible.
If you want to have no code outside of main, in C you could do this:
int main()
{
int puts(const char *);
puts("Sup!\n");
return 0;
}
Or the same thing with printf, or any other C standard library function.
It wouldn't work in C++ though, since in C++ the puts declaration needs extern "C" to disable name mangling, which can only be used outside of functions.
There's a trick that lets you do it in C++:
int main()
{
extern int puts;
((int(*)(const char *))&puts)("Sup!\n");
return 0;
}
Variable names are not mangled, so by tricking the compiler into thinking that puts is a variable rather than a function, you can get rid of the mangling without extern C.
Technically, this satisfies your constraints:
int main() {
return 123;
}
Most OSs allow you to check a program's return code. So this communicates one number to the outside world. The available range of values may differ with the OS.
You wrote "only main", but extern "C" cannot go into a block. So, if you can live with that line outside the main function, here's the code you asked for:
extern "C" int printf(const char *fmt, ...);
int main() {
printf("Hello %s\n", "world");
return 0;
}
Proof: https://godbolt.org/z/41WhGYc79
Perhaps I haven't understood correctly, but if you want to avoid the includes/libraries then the short answer is no. A C++ header (apart from templates) is just a declaration of a possible link-time function availability and you will always need them.
Almost anything meaningful you can do with C++ (as in any programming language, even assembly) requires a call to the underlying OS and this requires a header and a library link.
Even something as simple as a char output requires thousands of lines to communicate with a device driver to output to screen.
Even if you don't include anything, the compiler will inject code (CRT) that calls the OS by using a library no matter what. Even a simple main() requires lots of calls to the OS, for actually there is no "main" entry point in the executable.
That does not exactly answer your question, but if you were doing this in C rather than C++, then for most compilers that would be a valid program (without any includes):
int main()
{
printf("hello");
return 0;
}
Although it generates a warning.
Combining two of the answers above I was able to use printf by replacing the parts of
extern int puts;
((int(*)(const char *))&puts)("Sup!\n");
With parts that would allow printf:
extern int printf;
((int(*)(const char *fmt, ...))&printf)("%d\n", 10);
So the full code would be:
int main(){
int num = 10;
extern int printf;
((int(*)(const char *fmt, ...))&printf)("%d\n", num);
return 0;
}
I hope this helps, this is a combination of two responses not my own.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
How does the main() function handle a variable number of arguments without the use of ellipses (...)? For processing variable number of arguments, last argument to the function should be ... which is not the case with the main() function.
Basically, main() is special, and it has two standard-defined forms:
int main(int argc, char **argv)
int main(void)
The system may support other forms; it is common that the environment is also made available:
int main(int argc, char **argv, char **envp)
These forms are fixed. The only unusual thing is that a system must support either of the first two (and some systems support others as well).
The variable number of command line arguments is handled via an array of pointers to strings (that's argv above), unlike say execl() from POSIX.
See also:
How does the main() function in C work?
What should main() return in C and C++?
rahul manglani commented:
The two links you mentioned made it pretty clear. There are different possible approaches listed there, which of them is actually being used is not mentioned.
In a sense, it doesn't matter; the system simply has to work, and the people who produce 'the system' must make it work. You as the programmer using the system don't need to know how it works; you can simply assume that it does work.
Behind the scenes, what usually happens is that the 'start' function which calls main() does some fixup work (in the case of a C++ program in particular, a lot of fixup work — such as ensuring all the constructors that must be executed before main() starts are in fact executed), but ends with a fixed sequence such as:
exit(main(argc, argv, environ));
Note that environ is a global variable, extern char **environ; (which is unique among the global variables defined by POSIX in that no header declares it) and it contains the pointers to the environment variables. The 'start' code has to ensure that is set; it is trivial to pass environ as an argument to main(), therefore.
This calls main() with a fixed argument list and calls exit() if/when it returns. Indeed, Apple takes it a step further and passes a fourth argument to main(). If the called function was defined as int main(void) { … }, it simply ignores the arguments it was passed; if it was defined as int main(int argc, char **argv) { … }, it can access the command line arguments as usual; if it was defined as int main(int argc, char **argv, char **envp) { … }, then it can access the environment too.
Generally, the systems are set up so that extra arguments don't cause damage. This is a reason why C is unusual in its calling conventions and it's why the called function doesn't clean up the arguments pushed onto the stack — the called function doesn't know how many arguments were actually pushed onto the stack. It assumes that the ones it expects were provided and uses those without problems, but the calling code knows what it pushed so it can clean up properly. The biggest problems occur if the called function expects N arguments but the caller passes M arguments and M < N. (There are also issues of types pushed and the sizes of those types, etc, but that's a second-order problem.)
In C/C++ main takes 2 parameters, typically called argc, and argv. The argv parameter is an array of argc char arrays. Command line arguments are passed to the program in argv. There are variations on this theme with the exact number of parameters, but main's signature is generally
int main(int argc, char **argv);
I interpreted this question to mean: how is it possible that main can take either zero arguments or two arguments?
While the details are obviously implementation-dependent, on most implementations, the default C calling convention is that the caller cleans the stack. Therefore, the code that calls main is at perfect liberty to always push two arguments onto the stack (argc and argv), whatever the declaration of main might be. If main is declared with no arguments, then main simply won't access the values of the arguments it receives. After main returns, the calling code clears the stack.
It should be pointed out that main isn't even special in this sense. Try this:
int printf();
int main() { printf("Hello, world!\n"); }
The C compiler will happily allow you to call printf even though, lacking an #include <stdio.h> directive, it has no idea how many arguments printf actually wants. Presumably, the code that calls main is conceptually something like this:
int main(int argc, char** argv); /* declare "main" */
main(argc, argv); /* call "main" */
If the definition of main actually specifies zero parameters, this still works (although I believe it would technically be undefined behaviour if you actually did this).
In the case of C++, although the linkage of main is left unspecified by the standard, most implementations simply treat it as though it has C linkage, so the name is not mangled and everything above still applies.
It handles it by accepting an array and array length set as variables argc and argv
you may find more data here:
http://crasseux.com/books/ctutorial/argc-and-argv.html
This question already has answers here:
What should main() return in C and C++?
(19 answers)
Closed 8 years ago.
In short, I'm using Microsoft Visual Studio 2012, programming in C++. My main method has a while(1) repeating a bit of code, and never leaves the loop.
Microsoft Visual Studio is allowing me to compile without a return value for the main method, even though it's declared int main(int argc, char** argv). Is this standard for other compilers, or just a "feature" of Microsoft Visual Studio?
I realize I never get to the code that returns a value, but should I just thrown on a return 0; at the end anyway?
By the standard, the main function in C++ implicitly returns 0, even if there is no return statement in it.
The exact reference (from n3797): 3.6.1.5
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 return 0; statement can be omitted from main even though its return type is int. It is defined by C++ standard. In this case it returns 0 by default.
This question already has answers here:
What is the proper declaration of main in C++?
(5 answers)
Closed 9 years ago.
So in my professor's slides he simply gives examples like:
main()
{...
}
Right? But when I put this in visual studio it gives an error and it works when I put int in front of main.
Why would my professor not put int in front of main?
Can main be any other type of variable?
Also I see a lot of int main(void). Why is this necessary? Can anything else be put in as a parameter?
main returns int. In older versions of C you could leave out the int and the compiler would pretend that you had said int. In C++, if 'main' doesn't explicitly return a value, it magically returns 0. You can return three values from main: 0, EXIT_SUCCESS, and EXIT_FAILURE. 0 is equivalent to EXIT_SUCCESS. The two named values are defined in <stdlib.h> and if you're coding in C++ in <cstdlib>.
The void is a C-style declaration that a function takes no arguments. In C++ you don't need it; a function that has no arguments in its declaration takes no arguments.
In general, though, main takes two arguments:
int main(int argc, char *argv[])
Those are the command-line arguments. argc is the number of arguments, and argv is an array of pointers to C-style strings that hold the arguments. The first string (argv[0]) is the name of the program.
Because you are using either: C++ or C99 or C11.
C89 had an implicit int rule that mades main() equivalent to int main(). This does not exist in C++ and no longer exists since C99.
As you mentioned you are using Visual Studio and it does not support C99 and C11, you are probably compiling your program with the C++ compiler and not the C compiler.
The standard form of the main function, traditionally, is
int main(int argc, char **argv)
The int in the front means the main function returns an int, which is the exit code of main. The perimeter passed in by the operating system argc and argv are related to command-line arguments. argc is an int indicating the number of arguments passed in to the program, including the name of the program. And argv is pointed to the individual arguments. You can use argv[index] to access them. There are several handy libraries for parsing arguments, such as getopt.
Here is what my book says:
char *p="Hello"; //pointer is variable, string is constant
*p='M'; // error
p="bye"; // works
Well, in C my second line does not give me any error, Neither in C++.
I am using Turbo C++ on windows 7. Now is the above thing true if i try in gcc or something else.
Also on the similar lines if the above code is correctly interpreted by the book,
#include<iostream.h>
void display(char*);
void display(const char*);
void main()
{
char* ch1="hello";
const char *ch2="bye";
display(ch1);
display(ch2);
}
void display(char* p)
{
cout << p << endl;
}
void display(const char* p)
{
cout << p << endl;
}
Now is my book considering char* and const char* the same because if it is then the above code shall not work, since arguments will be the same?
(Though i get the output Hello bye on turbo +windows.)
Which one is correct?
The language specification is not a promise that compilers make to you, but a mutual contract that you and compilers both sign onto. (Metaphorically speaking, of course. Obviously it's not a literally legally binding contract.) If you violate the contract by writing *p='M';, then you've triggered "undefined behavior", and you can't expect any specific behavior from the compiler: maybe it will be strict about it and give you a compile error, maybe it will just go wonky at run-time . . . you didn't hold up your end of the bargain, and it's allowed to do literally whatever it wants now. See also: http://catb.org/jargon/html/N/nasal-demons.html.
Question:
“Now is my book considering char* and const char* the same because if it is then the above code shall not work, since arguments will be the same?”
Well you’re probably misrepresenting your book.
It probably does not consider those types to be the same, because they are not the same.
Now to your code:
#include<iostream.h>
[iostream.h] is not part of standard C++. C++ was standardized in 1998, and that standardization dispensed with the ARM era's [iostream.h]. So a modern compiler will likely choke on that.
As a workaround, when you get yourself a less antique compiler, you might do …
#include <iostream>
using namespace std;
Next,
void display(char*);
void display(const char*);
Declaring functions at the top of the file generally just yields extra work. It often means maintaining two declarations of the function. When you could have dealt with just one declaration.
void main()
In standard C and standard C++ main is not allowed to have any other result type than int.
Visual C++ is one compiler that, as a language extension, permits void.
However, it’s quite silly to use that possibility since it is more to write and just makes the code non-standard and likely to not compile with other compilers.
{
char* ch1="hello";
By C++11 rules the above will not compile. It was deprecated in C++98 and removed in C++11. However, AFAIK current compilers still allow it, but some have a warning that can be turned on.
const char *ch2="bye";
display(ch1);
display(ch2);
}
The above is OK, although it would not hurt to add an extra const, like
const char* const ch2="bye";
char* ch1="hello";
is deprecated in C++. The correct way is const char*. Because "hello" is stored in a read only region. Also, int main() or int main(int, char**) is the correct way of defining main().
Don't use Turbo C, it's an outdated compiler. Go for gcc or MSVC. Also, don't use books which provides such incorrect information.
char *p="Hello"; //pointer is variable, string is constant
This code is allowed, because it has been valid since long before the C language got a const keyword.
In order not to break old code, the C and C++ standards just documented that this should work like before.
However, if you write new code you should use the proper form const char*.