10

I sometimes see coders that use NULL as return value of main() in C and C++ programs, for example something like that:

#include <stdio.h>

int main()
{
    printf("HelloWorld!");

    return NULL;
} 

When I compile this `code with gcc I get the warning of:

warning: return makes integer from pointer without a cast [-Wint-conversion]

which is reasonable because the macro NULL shall be expanded to (void*) 0 and the return value of main shall be of type int.

When I make a short C++ program of:

#include <iostream>
using namespace std;

int main()
{
    cout << "HelloWorld!";

    return NULL;
}

And compile it with g++, I do get an equivalent warning:

warning: converting to non-pointer type ‘int’ from NULL [-Wconversion-null]

But why do they use NULL as return value of main() when it throws a warning? Is it just bad coding style?


  • What is the reason to use NULL instead of 0 as return value of main() despite the warning?
  • Is it implementation-defined if this is appropriate or not and if so why shall any implementation would want to get a pointer value back?
  • 4
    You should ask them directly. – juanchopanza Jan 31 '20 at 10:33
  • 5
    "why do they use NULL as return value of main()" - we don't. The author of that code does. I'd be interested in hearing *their* attempt at justifying why. – WhozCraig Jan 31 '20 at 10:34
  • @juanchopanza I´ve already asked one, he said: "I´ve seen it anywhere else." – RobertS supports Monica Cellio Jan 31 '20 at 10:35
  • @kiranBiradar What is EXIT_SUCCESS? – Vlad from Moscow Jan 31 '20 at 10:36
  • `The value of EXIT_SUCCESS is defined in stdlib.h as 0` says the [doc](https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.4.0/com.ibm.zos.v2r4.bpxbd00/exit.htm) – Waelmio Jan 31 '20 at 10:37
  • @WhozCraig I´ve said "they" - meaning the ones who code in this way. I did not suppose that everyone does it that way, which is definitely not the case. I´ve already asked one, he said: "I´ve seen it anywhere else." – RobertS supports Monica Cellio Jan 31 '20 at 10:38
  • @Waelmio And moreover EXIT_SUCCESS is a macro.:) – Vlad from Moscow Jan 31 '20 at 10:39
  • @Waelmio That's IBM's implementation. The actual value of EXIT_SUCCESS is implementation-defined. Its one reason why the standard calls out that *either* EXIT_SUCCESS *or* zero are valid success indicators on program exit. (7.22.4.4) – WhozCraig Jan 31 '20 at 10:41
  • 1
    @Vlad from Moscow yes but I had to check if it was really 0. ^^ - `EXIT_FAILURE` is 8, and it seems using 1 is not good for a failure since it's sometime used as a success in some programs. – Waelmio Jan 31 '20 at 10:42
  • 2
    @RobertSsupportsMonicaCellio if that was really the response you got, that's kind of sad. First, it doesn't make sense (would make more sense if it were *everywhere* rather than *anywhere*). Second, it is a sell out. If you're writing code, you'd better have a good compass on whether it is correct; not just go with it because that's the way it seems to be done by... someone. You seem to have that needle pointing the right direction (thus why you're asking); not so much the person that wrote that code, then fed you that answer as the reason why. – WhozCraig Jan 31 '20 at 10:46
  • 2
    In c, it is perfectly valid to define the `NULL` pointer as `0` (without a cast to `void *`). In this case, the flaw goes unnoticed and does not generate a warning. It still is not what NULL should be used for. – Ctx Jan 31 '20 at 10:48
  • @WhozCraig Yes, agree. But I´d just want to ask if there is any reason to code in this weird kind of way, I may have missed. But it seems that it isn´t and I´m glad that it is so. Thank you very much. – RobertS supports Monica Cellio Jan 31 '20 at 10:50
  • I've been coding for quite a while. I've never seen any code that used `return NULL;` in main. "_Is it just bad coding style?_" Yes, very. – Eljay Jan 31 '20 at 13:12
  • @machine_1 My intention is not to blame anyone specifically, especially because this is such a deprecated coding style (assuming it is valid/ warnings keep warnings, not migrate to errors by relative compiler flags). I think, it is just because of pure confusion based on the wrong assumption that `NULL` shall be equivalent to the integral value of `0` which isn´t the case. – RobertS supports Monica Cellio Jan 31 '20 at 16:56

4 Answers4

14

which is reasonable

Yes.

because the macro NULL shall be expanded to (void*) 0

No. In C++ the macro NULL must not expand to (void*) 0 [support.types.nullptr]. It may only do so in C.

Either way, writing code like this is misleading since NULL is supposed to refer to the null pointer constant, regardless of how it’s implemented. Using it in place of an int is a logical error.

  • What is the reason to use NULL instead of 0 as return value of main() despite the warning?

Ignorance. There is no good reason to do this.

  • Is it implementation-defined if this is appropriate or not and if so why shall any implementation would want to get a pointer value back?

No, it is never appropriate. It is up to the implementation whether the compiler allows it. A conforming C++ compiler may well allow it without warning.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 1
    My usual thump: it is not **implementaiton-defined** whether the compiler allows it; it is **implemenation-specific**. In the standard, "implemenation-defined" means that the implementation must document what it does. – Pete Becker Jan 31 '20 at 14:27
  • @PeteBecker I did pause when writing it but went ahead anyway (because “implementation-specific” and similar phrases just sound unnatural). But you’re correct, I’ll change it. – Konrad Rudolph Jan 31 '20 at 14:29
  • Seems to me that the only reason "implementation-defined" sounds natural is that people are used to seeing it misused. – Pete Becker Jan 31 '20 at 14:30
8

When I compile this `code with gcc I get the warning of:

warning: return makes integer from pointer without a cast

This is because you compile with lax compiler options. Use strict C standard settings -std=c11 -pedantic-errors and you will get the expected compiler error, on implementations where NULL expands to the null pointer constant (void*)0. See “Pointer from integer/integer from pointer without a cast” issues.

On implementations where NULL expands to 0, the code is strictly speaking standard compliant, but very bad style, non-portable and worst of all: complete nonsense.

And compile it with g++, I do get an equivalent warning:

warning: converting to non-pointer type ‘int’ from NULL [-Wconversion-null]

On C++11 and beyond, NULL shouldn't be used - instead use nullptr. To return it from main() is incorrect regardless. NULL always expands to 0 in C++ so strictly speaking it will work, but it is very bad style and worst of all: complete nonsense.

Is it just bad coding style?

Not just bad, but nonsense coding style without any rationale. The programmer who wrote it was incompetent.

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
3

Is it just bad coding style?

Worse. The correct way to indicate that the program finished fine is

#include <stdlib.h>

int main (void)
{
    return EXIT_SUCCESS;
}
emacs drives me nuts
  • 2,785
  • 13
  • 23
  • 2
    That's pure pedantry. According to the C standard, a 0 argument to `exit()` (or a 0 return value from main) means the same as `EXIT_SUCCESS`. –  Jan 31 '20 at 16:00
  • 1
    And since c99 you can just omit the `return` from `main`. So, a more "correct" version of your program is `int main(void){}` ;-) –  Jan 31 '20 at 16:05
1

In ?some/many/all? C++ implementations NULL is a macro expanded to 0.

This when expanded in effect gives return 0. Which is a valid return value.

Is it just bad coding style?

Yes.

Robert Andrzejuk
  • 5,076
  • 2
  • 22
  • 31