What main(++i) will return in C - c

I have a program like this.
‪#include<stdio.h>
#include<stdlib.h>
int main(int i) { /* i will start from value 1 */
if(i<10)
printf("\n%d",main(++i)); /* printing the values until i becomes 9 */
}
output :
5
2
2
2
Can anyone explain how the output is coming ?? what main(++i) is returning for each iteration.
Also it is producing output 5111 if i remove the \n in the printf function.
Thanks in advance.

First of all, the declaration of main() is supposed to be int main(int argc, char **argv). You cannot modify that. Even if your code compiles, the system will call main() the way it is supposed to be called, with the first parameter being the number of parameters of your program (1 if no parameter is given). There is no guarantee it will always be 1. If you run your program with additional parameters, this number will increase.
Second, your printf() is attempting to print the return value of main(++i), howover, your main() simply don't return anything at all. You have to give your function a return value if you expect to see any coherence here.
And finally, you are not supposed to call your own program's entrypoint, much less play with recursion with it. Create a separate function for this stuff.

Here's what the C Draft Standard (N1570) says about main:
5.1.2.2.1 Program startup
1 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.
Clearly, the main function in your program is neither of the above forms. Unless your platform supports the form you are using, your program is exhibiting undefined behavior.

This program has undefined behavior (UB) all over the place, and if you have a single instance undefined behavior in your program, you can't safely assume any output or behavior of your program - It legally can happen anything (although in real world the effects often are somewhat localized near the place of UB in the code.
The old C90 standard listed are more than 100 (if i recall right) situations of UB and there is a not known number of UBs on top, which is behavior for situations, the standard do not describe. A set of situations, that are UB exists, for every C and C++ Standard.
In your case (without consulting standards) instances of UB are at least:
not returning an value of a function that is declared with a return value. (exception: calling main the FIRST time - thanks, Jim for the comments)
defining (and calling) main other than with the predefined forms of the standard, or as specified (as implementation defined behavior) by your compiler.
Since you have at least one instance of UB in your program, speculations about the results, are somewhat... speculative and must make assumptions about your compiler, your operating system, hardware, and even software running on parallel, that are normally not documented or can be known.

You are not initializing i, so by default value will be taken from the address where it is stored in RAM.
This code will produce garbage output if you run the code multiple times after restarting your computer.
The output will also depend on compiler.

I'm surprised that even compiles.
When the operating system actually runs the program and main() gets called, two 32 (or 64) bit values are passed to it. You can either ignore them by declaring main(void), or use them by declaring main(int argc, char** args).
As the above prototype suggests, the first value passed is a count of the number of command-line arguments that are being passed to the process, and the second is a pointer to where a list of these arguments is stored in memory, likely on the program's local stack.
The value of argc is always at least 1, because the first item string in args is always the name of the program itself, generated by the OS.
Regarding your unexpected output, I'd say something is not getting pulled off or pushed onto the stack, so variables are getting mixed up. This is either due to the incomplete argument list for main() or the fact that you've declared main to return an int, but haven't returned anything.

I think, the main method is calling itself inside the main method.
to increment the value of a variable, i++ is printing the value of i before it increment while ++i it increment the value of i first before it print the value of i.
you could use this..
int x=0;
main()
{
do
{
printf(x++);
}while (i<10);
}

Related

Can the function main in C return a pointer?

As the heading goes, Is it possible for the main function return a pointer? If yes then where would be useful? Thanks!
Only a return type of int is blessed by the standard:
5.1.2.2.1 Program startup
1 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;10) or in some other implementation-defined manner.
C11 draft, April 12, 2011
Everything else is up to your compiler and therefore not a C-question anymore.
No. main() returns an int in standard C. The interpretation of this return value is a matter for the surrounding runtime environment. If you know exactly what you're doing, in some kind of specialized situation where you know that the environment is going to interpret the value in a certain way, then you can cast a pointer to an int. But that's nasty.
And be aware that a pointer to dynamically-allocated memory is (probably) meaningless after the program exits anyway! It would only make sense to return a pointer to a fixed address, e.g. a hardware register in some embedded environment.
Completing phresnel's answer, and answering whether it would be useful: since each process has its own address-space, even if your main() returns an integer value that you'd use as an address, what would be the point since the returned pointer is only consistent to the just exited process's address-space...

Is It Necessary to Return a Value in Main()?

I was just writing a quick program for calculating some things when I came across the return statement/exit statement for the C program.
I declared main() to be of type int, so I would have to put in a return of an integer, or my program would not compile correctly. However, is it acceptable to make main a Boolean or even void?
I know the standard way to create a C program is to return a value so any problems can be sorted out, among other things, but wouldn't a Boolean work the same way? Also, could I get away with declaring it void and not having problems with the operating system still running my program after it has been terminated?
Thanks for any and all help.
The C99 standard says: (§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.
So in a hosted environment, int is the only valid, standard return type. Implementations can define other entry points though.
Note that section §5.1.2.2.3 Program Termination has this:
If the return type of the main function is a type compatible with int, a return from the
initial call to the main function is equivalent to calling the exit function with the value
returned by the main function as its argument; reaching the } that terminates the
main function returns a value of 0. If the return type is not compatible with int, the
termination status returned to the host environment is unspecified.
So you omitting a return from main is legal in C99, as long as your main returns an int.
(But previous versions of the C standard didn't have that exception for main - returning no value (or reaching the final } without a return statement) causes "the termination status returned to the host environment [to be] undefined.".)
Summary: You don't necessarily have to, but you should.
In C90, reaching the end of main() without executing a return statement means "the termination status returned to the host environment is undefined". On at least one system I've used, the status returned is 1, which on that system indicate that the program failed.
C99 added a new rule, saying that reaching the end of main() returns 0. (C++ has the same rule.) Not all compilers fully implement C99, and those that do often don't behave as conforming C99 compilers by default. (Added 10 years later: The conformance situation is better now, and most modern C compilers support at least C99.)
The only portable values you can return from main() are 0, EXIT_SUCCESS, and EXIT_FAILURE (the latter two are defined in <stdlib.h>. 0 and EXIT_SUCCESS indicate that the program succeeded (and EXIT_SUCCESS is usually defined as 0); EXIT_FAILURE indicates that the program failed. return 1; is common, but non-portable; I've worked on a system (VMS), where a termination status of 1 indicates success. If you want your program to be portable, use EXIT_FAILURE to indicate failure; that's what it's for. Some systems and program define other system-specific or application-specific status codes.
For portability (and, IMHO, style), it's best to do an explicit return 0; at the end of main(), though it's not required in all circumstances. It's much easier to add that one line of code (which is, at worst, harmless) than to waste time determining whether you need it.
(Update 10 years later: I no longer think it's important to do an explicit return 0; unless you have a requirement for your code to work with old compilers or with current compilers configured to conform to the old C90 standard.)
Note that the correct definitions for main() are:
int main(void) { /* ... */ }
and
int main(int argc, char *argv[]) { /* ... */ }
or equivalent (for example, you can write char **argv rather than char *argv[]). It's questionable whether int main() { /* ... */ } is valid, for subtle reasons I won't go into here, but I believe all compilers accept it. Again, it's easier to add the void keyword than to waste time determining whether you need it.
A lot of books and tutorials use void main() or void main(void). A particular compiler may choose to permit this, but it's not portable. Seeing void main in a book or tutorial is a good sign that the author doesn't know the C standard very well, and that you should find something else to study.
Here is a link that might be of interest. Seems the answer to your question is not that straight. I've also seen compilers (MS Visual C) accepting void as a return type.
The code that calls main() expects it to return int (or call exit()). You cannot change the code that calls main() (it is part of the OS or runtime), so you'd better return int.
The standard, per ISO, is to return an int. See section 5.1.2.2.1 of this document: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf. Also interesting is Stroustrup's commentary on this matter related to both C and C++: http://www2.research.att.com/~bs/bs_faq2.html#void-main.
The return type must be int, as covered by other answers. However your assumption that you must return a value at all because of this is wrong, main is an exception. The C99 standard provides for this, so it is perfectly fine to implement main without using return.
In ANSI C, main () usually has a return type of int, but it can actually be implementation-defined; this means that different compilers and platforms accept different signatures, but int main () and int main (int, char**) are guaranteed by the standard to be well-formed.
It is unlike other non-void functions, in that it doesn't need a return statement. In the case that none is supplied, and the return type is specified as int, then the program is compiled as if there were an implicit return 0; after the last statement in main ().
The relevant part of the standard:
5.1.2.2.3 Program termination
1 If the return type of the main function is a type compatible with int, a return from the
initial call to the main function is equivalent to calling the exit function with the value
returned by the main function as its argument; reaching the } that terminates the
main function returns a value of 0. If the return type is not compatible with int, the
termination status returned to the host environment is unspecified.
Don't quote me on this, but in K+R, however, things were a little looser, and I think you didn't even need to specify a return type, so main () { } is actually a valid K+R program.

Why does this do whatever it does?

#include <stdio.h>
void littledot(){}//must use C, not C++
int main() {
littledot(568,76,105,84,116,76,101,68,111,84);
printf("%c%c%c%c%c%c%c%c%c\n");
getchar();
return 0;
}
The above code yields the result "LiTtLeDoT". Why does it do that? Why is 568 crucial?
This differs per platform and is UB (the implementation can do anything it wants*), but probably the arguments to littledot() are still on the stack after littledot() returns and printf prints those arguments from the stack.
NEVER RELY ON THIS!
*really anything. Afaik an ancient version of GCC started a videogame when it encountered something that would behave in an undefined way.
You were lucky. This is undefined behaviour, specifically the call to printf. The program could do anything. Your implementation happens to write "LiTtLeDoT".
The really is the nature of undefined behaviour. The compiler can do anything it wants. If you really want to know why it does what it does then you will need to look at the emitted object code. Looking at the C code will yield nothing because of the aforementioned undefined behaviour.
This is what's working reliably for me with Open Watcom 1.9 on Windows:
//must use C, not C++
#include <stdio.h>
#include <stdlib.h>
void
__stdcall // callee cleans up
littledot()
{
}
int main(void)
{
littledot(/*568,*/'L','i','T','t','L','e','D','o','T');
printf("%c%c%c%c%c%c%c%c%c\n");
getchar();
exit(0);
return 0;
}
littledot() is called with a number of parameters that are passed on the stack.
If the calling convention for littledot() is __stdcall (or __fastcall), it will have to remove its parameters from the stack.
If it's __cdecl, then main() will have to remove them, but this won't work for us.
However, littledot() doesn't and can't do anything about the parameters because they're not specified, which is something you can do in C, but not C++.
So, what happens is that not only littledot()'s parameters remain on the stack after the call to it, but also the stack pointer is not restored (because neither littledot() nor main() remove the parameters, which is typically done by adjusting the stack pointer) and the stack pointer points to 'L'. Then there's the call to printf() that first places on the stack the address of the format string "%c%c%c%c%c%c%c%c%c\n" thus forming all expected parameters for the function on the stack. printf() happily prints the text and returns.
After that the stack isn't correctly balanced and doing return in main() is risky as the app may crash. Returning by means of exit(0) fixes that.
As all others have said, none of this is guaranteed to work. It may only work with specific compilers for specific OSes and then only sometimes.
http://codepad.org/tfRLaCB5
I'm sorry, what you claim the program to print is not what happens on my box and not what happens on codepad's box.
And the reason is, the program has undefined behavior. printf expects one additional argument (an int) for every %c you have in the format string. You don't give it those arguments, hence anything can happen.
You are in a situation where with certain implementations of printf, compiler options, certain compilers and certain ABIs, you end up with that output. But you should not think that this output is required by any specification.

calling main() in main() in c

Is it possible to call main() within the main() function in c?
Yes, C allows you to call your main function (while C++ does not )
It is indeed allowable to call main() from itself, even avoiding stack overflow with the same method used for any other recursive code, a terminating condition such as with:
#include <stdio.h>
int main (int argc, char *argv[]) {
printf ("Running main with argc = %d, last = '%s'\n",
argc, argv[argc-1]);
if (argc > 1)
return main(argc - 1, argv);
return 0;
}
which, when run as testprog 1 2 3, outputs:
Running main with argc = 4, last = '3'
Running main with argc = 3, last = '2'
Running main with argc = 2, last = '1'
Running main with argc = 1, last = 'testprog'
However, since that's only anecdotal evidence, we should turn to the standard. ISO C11 section 4 Conformance states:
1/ In this International Standard, "shall" is to be interpreted as a requirement on an implementation or on a program; conversely, "shall not" is to be interpreted as a prohibition.
2/ If a "shall" or "shall not" requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words "undefined behavior" or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe "behavior that is undefined".
3/ A program that is correct in all other aspects, operating on correct data, containing unspecified behavior shall be a correct program and act in accordance with 5.1.2.3.
Now, since there's no explicit prohibition anywhere in the standard on main() calling itself, clause 3 above is the controlling aspect.
Further support can be seen in two places (my bold), first in section 5.1.2.2.3 Program termination:
1/ If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument;
And then in section 7.21.3 Files:
5/ The file may be subsequently reopened, by the same or another program execution, and its contents reclaimed or modified (if it can be repositioned at its start). If the main function returns to its original caller, or if the exit function is called, all open files are closed (hence all output streams are flushed) before program termination.
Both these sub-sections support the possibility that there may be other calls to main() over and above the initial/original one.
Yes, we can call the main() within the main() function.
The process of calling a function by the function itself is known as Recursion.
Well,you can call a main() within the main() function ,but you should have a condition that does not call the main() function to terminate the program.
Otherwise,the program will never return and run infinitely.
Yes you can.
Simple Program:
int main()
{
printf("Anything");
main();
return 0;
}
Explanation:
A call stack or function stack is used for several related purposes, but the main reason for having one is to keep track of the point to which each active subroutine should return control when it finishes executing.
A stack overflow occurs when too much memory is used on the call stack.
Here function main() is called repeatedly and its return address is stored in the stack. After stack memory is full. It shows stack overflow error.

Why would you precede the main() function in C with a data type? [duplicate]

This question already has answers here:
What should main() return in C and C++?
(19 answers)
Closed 8 years ago.
Many are familiar with the hello world program in C:
#include <stdio.h>
main ()
{
printf ("hello world");
return 0;
}
Why do some precede the main() function with int as in:
int main()
Also, I've seen the word void entered inside the () as in:
int main(void)
It seems like extra typing for nothing, but maybe it's a best practice that pays dividends in other situations?
Also, why precede main() with an int if you're returning a character string? If anything, one would expect:
char main(void)
I'm also foggy about why we return 0 at the end of the function.
The main function returns an integer status code that tells the operating system whether the program exited successfully.
return 0 indicates success; returning any other value indicates failure.
Since this is an integer and not a string, it returns int, not char or char*. (Calling printf does not have anything to do with returning from the function)
Older versions of C allow a default return type of int.
However, it's better to explicitly specify the return type.
In C (unlike C++), a function that doesn't take any parameters is declared as int myFunc(void)
The following has been valid in C89
main() {
return 0;
}
But in modern C (C99), this isn't allowed anymore because you need to explicitly tell the type of variables and return type of functions, so it becomes
int main() {
return 0;
}
Also, it's legal to omit the return 0 in modern C, so it is legal to write
int main() {
}
And the behavior is as if it returned 0.
People put void between the parentheses because it ensures proper typechecking for function calls. An empty set of parentheses in C mean that no information about the amount and type of the parameters are exposed outside of the function, and the caller has to exactly know these.
void f();
/* defined as void f(int a) { } later in a different unit */
int main() {
f("foo");
}
The call to f causes undefined behavior, because the compiler can't verify the type of the argument against what f expects in the other modules. If you were to write it with void or with int, the compiler would know
void f(int); /* only int arguments accepted! */
int main(void) {
f("foo"); /* 'char*' isn't 'int'! */
}
So for main it's just a good habit to put void there since it's good to do it elsewhere. In C you are allowed to recursively call main in which case such differences may even matter.
Sadly, only a few compilers support modern C, so on many C compilers you may still get warnings for using modern C features.
Also, you may see programs to declare main to return different things than int. Such programs can do that if they use a freestanding C implementation. Such C implementations do not impose any restrictions on main since they don't even know or require such a function in the first place. But to have a common and portable interface to the program's entry point, the C specification requires strictly conforming programs to declare main with return type int, and require hosted C implementations to accept such programs.
It's called an exit status. When the program finishes, you want to let the callee know how your program exited. If it exited normally, you'll return 0, etc.
Here's where you can learn more about exit statuses.
Why do some precede the main () function with int as in:
In C (C 89 anyway, that's the one you seem to be referring to), functions return int by default when they aren't preceded by any data type. Preceding it with int is ultimately just a matter of preference.
Also, I've seen the word 'void' entered inside the () as in:
This is also a matter of preference mostly, however these two are quite different:
f(void) means the function f accepts zero arguments, while f() means the function f accepts an unspecified number of arguments.
f(void) is the correct way to declare a function that takes no arguments in C.
It seems like extra typing for nothing, but maybe it's a best practice that pays dividends in other situations?
The benefit is clarity. If you're going to argue that less typing is good, then what do you think about naming all of your functions and variables and files and everything with as few characters as possible?
Also, why precede main() with an int if you're returning a character string? If anything, one would expect:
char main(void)
What? why in the world would you return a character string from main? There is absolutely no reason to do this...
Also, your declaration of main return a character, not a character string.
I'm also foggy about why we return 0 at the end of the function.
A program returns a value to the operating system when it ends. That value can be used to inform the OS about certain things. For example, your virus scanner could return 1 if a virus was found, 0 if a virus wasn't found and 2 if some error occurred. Usually, 0 means there was no error and everything went well.
The reasoning behind this was to provide some form of error reporting mechanism. So whenever a program returns a zero value, that typically means that it believes it completed its task successfully. For non-zero values, the program failed for some reason. Every now and then, that number might correspond to a certain error message.
Several system API calls in C return return codes to indicate whether the processing was successful. Since there is no concept of an exception in C, it is the best way to tell if your calls were successful or not.
The "int" before the main function declaration is the return type of the function. That is, the function returns an integer.
From the function, you can return a piece of data. It is typical to return "0" if the function completed successfully. Any other number, up to 255 is returned if the program did not execute successfully, to show the error that happened.
That is, you return 0, with an int data type, to show that the program executed correctly.
It is traditional to use int main(int argc, char * argv[]) because the integer return can indicate how the program executed. Returning a 0 indicates that the program executed successfully, whereas a -1 would indicate that it had a failure of some sort. Usually, the exit codes would be very specific and would be used as a method of debugging since exceptions (in the C++ sense) don't exist in C.
Most operating systems uses exit codes for applications. Typically, 0 is the exit code for success (as in, the application successfully completed). The return value of main() is what gets returned to the OS, which is why main() usually returns an integer (and since 0 is success, most C programs will have a return 0; at the end).

Resources