1ts question:In the program Why you used 0 in return 0 ; and 2nd question : if you use a in return a; then it also print the correct output but why ?

This function, main, is called by a different function. A function you don't know about, and you don't need to know about. That function, calling main, is expecting an int to be returned. So you return an int.

When you understand how to code in C, and you understand what the compiler does and what the linker does, you'll be ready to understand what function calls main.

The value of that int makes no difference. People often use zero to mean "no errors". But that's just convention. It doesn't have to be that way.

Your second question makes no sense. You can return any int you like from main. a is an int, so you can return a. The output on screen gets done by the printf; the printf is executed before the return, so why would it make any difference?

The return value of main is the program's exit code. If it is 0, that means that the program terminated successfully. A different return value means that the program failed. This distinction matters most in shell scripts:

if my_c_program bla
then
echo "main() returned 0"
else
echo "main() returned something other than 0"
fi
# Or:
my_c_program && echo "This will only get printed if main() returned 0"
my_c_program || echo "This will only get printed if main() returned something other than 0"

The exit code will also be available in the variable $?, which a shell script (or a normal user) can use to see the exact value that was returned, which might tell what went wrong (assuming the program has multiple meaningful error values that are explained in the documentation).

When your program is invoked by another program, that program can also see your exit code. For example most IDEs will inform you that your program has exitted abnormally if you run it from the IDE and it returns a non-zero value.

if you use a in return a; then it also print the correct output but why ?

The return value does not affect the output of the program in any way.

The value of that int makes no difference.

As I explained above it makes a lot of difference to shell scripts and any tool that queries a program's exit code.

People often use zero to mean "no errors". But that's just convention

0 is defined to represent successful termination by the standard, not convention.

As I explained above it makes a lot of difference to shell scripts and any tool that queries a program's exit code.

That's like saying that the colour of your shoes matter because there might be someone out there who likes shooting people wearing green shoes. If a shell script is relying on the return value of a program, the person who wrote that shell script should read the documentation and learn what the returned values mean.

0 is defined to represent successful termination by the standard, not convention.

I'll give you that one; you can use anything you like to indicate success, but zero is namechecked in the standard as meaning success (as the input value to the function exit()). This is no guarantee that what you'll get back at the operating system is the number zero, though - that's completely up to the implementation.

If a shell script is relying on the return value of a program, the person who wrote that shell script should read the documentation and learn what the returned values mean.

If it relies on the exact numeric value, sure. But if a shell script does something like the_program && some_other_program or if the_program; then; ...; else; error_handling_code; fi, that should not require consulting the documentation.

Not to mention that there are various tools (like most IDEs, build tools, test tools etc) that work with arbitrary programs and will treat non-zero exit codes as failures. In that case consulting the documentation would of course be impossible.

This is no guarantee that what you'll get back at the operating system is the number zero, though - that's completely up to the implementation.

However it is a guarantee that what we give back to the operating system indicates success. If we have a compiler+OS combination where a program with return value 0 is treated as false in a shell script, that'd be a violation of the standard.

If we have a compiler+OS combination where a program with return value 0 is treated as false in a shell script, that'd be a violation of the standard.

If by "false" you mean "was not successful", I disagree. The standard does not say what the OS should receive to indicate success. My main function could return zero to indicate success, as mandated in the standard, but the end of my main function is not necessarily the end of the program (especially on a modern OS, where it's pretty much guaranteed not to be the end of the program) and the value returned by main has more layers to go through. The OS might ultimately get back the string "Beans on toast" from the program to indicate success, or nothing at all, or a light might turn on somewhere on some piece of hardware; it's up to the implementation. The C standard makes no such mandate.

By false I meant that it'd go into the else of an if, the alternative of an || or that it wouldn't go into the right side of an &&. That is if your main returns 0 and your-program || echo "Error" prints "Error", your compiler is non-complying.

The OS might ultimately get back the string "Beans on toast" from the program to indicate success. The C standard makes no such mandate.

Sure, that's all fine as long as it ultimately causes the if to go into the then-branch and not the else-branch.

No, it's not. The C standard says that if main returns 0, the program should indicate to the OS that it was successful. But if it did that your-program || echo "Error" would not print "Error" as the shell asks the OS whether your-program exitted successfully and only executes echo "Error" if that was not the case.

Therefore if "Error" is printed, the program must not have done what the C standard said it should do.

No, it's not because the C standard says that if main returns 0, the program should indicate to the OS that it was successful.

Sure. How that is indicated is up to the implementation. Could return anything at all it likes. So it could return "true" to indicate success. It could return "false" to indicate success. The C standard doesn't madate anything.

your-program || echo "Error" will (under a typical interpretation) output "Error" if "your-program" evaluates to false. "false" could mean "success", or it could mean "failure". So your-program || echo "Error" could output "Error" when everything was successful, and could output "Error" when it wasn't; all depends on what the program returns to indicate success or failuire. The C standard does not mandate what that should be. How a given shell script chooses to interpret that is also nothing to do with C.

Wait I totally confused myself. The way I originally wrote it was correct.

your-program || echo "Error"
So if your-program evaluates to zero, this will output "Error" on the screen?

No, if your-program does not evaluate to zero, this will output "Error" to the screen (assuming that your-program was compiled with a compliant C compiler).

The C standard does not mandate what a program should return in the event of success. It could return 0. It could return true. It could return false.

All that's true, but the C standard does mandate that the value returned should signify successful termination. As long as that's the case, the shell will get back the answer "yes" when it asks the OS "Did the program terminate successfully?". And if the shell does get that answer, it will not execute echo Error.

This is an irrelevant diversion; if you want to go this way, you need to define carefully what this shell script language you're using does. Why bother?

My point is that the returned value meaning "success" from a given program is not mandated by the C standard to be the value zero. That's my point. Is that what you disagree with? I don't care what a given interpreter or given shell script chooses to do with that returned value; that's nothing to do with it.

if you want to go this way, you need to define carefully what this shell script language you're using does.

Fair enough. I was assuming a POSIX compliant shell (or presumably the windows command prompt, which I assume has the same semantics here).

Why bother?

Because shell scripts are the most obvious example of a case where it makes a huge difference whether an application exitted successfully or not.

My point is that the returned value meaning "success" from a given program is not mandated by the C standard to be the value zero. That's my point.

No, in fact I explicitly agreed with it at least once. I just don't see why that would matter when deciding whether to return 0; or return something_else; in main.

My point was that the main function that you define in your C code should always return 0 when it finished successfully because otherwise shell scripts and other applications will not work properly with your application. Is that what you disagree with?

Note that this discussion started with you saying that it did not matter which value was returned from main and me disagreeing with that statement. I never disagreed with your later statement that the value returned from main was not necessarily the same as the one returned to the OS, but the latter statement does not imply the former (because the value returned to the OS, even it is different from the one returned by main, still has to indicate success if main's value was 0).

Well that's the issue here then. I said it didn't matter because, in my opinion, anything at all could come back from a given program and it's up to whoever chooses to interpret that to do it correctly.

My point was that the main function that you define in your C code should always return 0 when it finished successfully because otherwise shell scripts and other applications will not work properly with your application. Is that what you disagree with?

Yes. I'm under no obligation to make sure that some other program I don't know about or claim to support can interpret whatever the OS tells it about anything that comes back from some program I create. It's just an opinion; the C standard does not mandate either way whether or not I should make sure shell scripts and other applications will understand anything my program returns.

If the shell is POSIX compliant, it will be able to correctly interpret what it gets back from the OS. So given that and given the fact that the OS will have gotten a value representing successful termination if main returned 0, returning 0 from main on success will cause shell scripts (running on POSIX compliant shells).

So I see no practical reason why you should not do that. Even if you do not personally care about that, I'd still say that "it makes no difference" is a gross overstatement at the very least.