为什么从main()函数返回NULL?

10

有时候我会看到一些程序员将NULL作为C和C++程序中main()函数的返回值,例如:

#include <stdio.h>

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

    return NULL;
} 

使用gcc编译此代码时,出现以下警告:

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

这是合理的,因为宏NULL应该展开为(void*) 0,而main函数的返回值应该是int类型。

当我编写一个简短的C++程序时:

#include <iostream>
using namespace std;

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

    return NULL;
}

我使用g++编译时也收到了等效的警告:

警告:从NULL转换为非指针类型'int'[- Wconversion-null]

但是为什么他们在main()的返回值上使用NULL,尽管这会引发警告?这只是坏的编码风格吗?


  • 使用NULL而不是0作为main()的返回值有什么原因,尽管会出现警告?
  • 如果这样做是否是实现定义的,如果是,为什么任何实现都希望获得指针值?

4
你应该直接询问他们。 - juanchopanza
5
为什么他们将NULL用作main()函数的返回值? - 我们并不这样做。代码的作者这样做。我很想听听他们为此辩解的尝试。 - WhozCraig
1
@来自莫斯科的Vlad 是的,但我必须检查它是否真的是0。^^ - EXIT_FAILURE是8,使用1作为失败并不好,因为在某些程序中它有时被用作成功。 - Waelmio
2
@RobertSsupportsMonicaCellio 如果你真的得到了这样的回答,那有点可悲。首先,它没有意义(如果是“到处”而不是“任何地方”,会更有意义)。其次,这是一种妥协。如果你在编写代码,最好要有一个良好的指南针来判断它是否正确;不要只是因为某个人似乎是这样做的就跟着去做。你似乎已经把指针指向了正确的方向(这就是为什么你在问);但那个编写代码并把这个答案作为原因告诉你的人,却没有那么多的指引。 - WhozCraig
2
在 C 语言中,将 NULL 指针定义为 0(无需转换为 void *)是完全有效的。在这种情况下,缺陷不会被注意到,也不会生成警告。但这仍然不是 NULL 应该用于的情况。 - Ctx
显示剩余9条评论
4个回答

14

这很合理。

是的。

因为宏NULL应该扩展为(void*) 0

不对。在C++中,宏NULL 不能 扩展为(void*) 0 [support.types.nullptr],只有在C中才可以。

无论哪种情况,编写这样的代码都是具有误导性的,因为NULL应该引用空指针常量,而不管它是如何实现的。将其用作int的替代品是一种逻辑错误。

  • 尽管有警告,使用NULL而不是0作为main()的返回值的原因是什么?

无知。没有好的理由这样做。

  • 如果这样做是适当的,那是否是实现定义的?如果是,任何实现为什么要返回一个指针值?

不,它从来都不是适当的。这取决于实现是否允许编译器这样做。符合C++标准的编译器可能会允许它而不发出警告。


1
我的惯常观点是:编译器是否允许它并不是“实现定义”,而是“实现特定”。在标准中,“实现定义”意味着实现必须记录其所做的事情。 - Pete Becker
@PeteBecker 我写这句话的时候确实犹豫了一下,但最终还是决定前进(因为“特定于实现”的类似短语听起来有些不自然)。但是你说得对,我会改正。 - Konrad Rudolph
在我看来,“实现定义”听起来自然的唯一原因是人们习惯于看到它被误用。<g> - Pete Becker

8

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

warning: return makes integer from pointer without a cast
这是因为您使用了宽松的编译器选项进行编译。 使用严格的C标准设置-std=c11 -pedantic-errors,您将获得预期的编译器错误(对于实现中NULL扩展为空指针常量 (void*)0的情况)。请参见“Pointer from integer/integer from pointer without a cast” issues
NULL扩展为0的实现中,代码严格遵守标准,但风格非常糟糕,不可移植,并且最糟糕的是:完全是无意义的。

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

warning: converting to non-pointer type ‘int’ from NULL [-Wconversion-null]
在C++11及其以后的版本中,不应使用NULL,而应该使用nullptr。无论如何都不能从main()函数中返回NULL,严格来说虽然会起作用,但这是非常糟糕的编程风格,最糟糕的是:完全没有意义。

这只是糟糕的编码风格吗?

不仅是糟糕的编码风格,而且是没有任何理由的荒谬编码风格。编写此代码的程序员是不称职的。

3

这只是糟糕的编码风格吗?

更糟糕的是,正确的表明程序正常结束的方式是

#include <stdlib.h>

int main (void)
{
    return EXIT_SUCCESS;
}

2
这纯粹是迂腐。根据C标准,对于exit()的0参数(或从main函数返回值为0),意味着与EXIT_SUCCESS相同。 - user10678532
1
自从c99以来,您可以在main函数中省略return语句。因此,您的程序的更“正确”的版本是int main(void){} ;-) - user10678532

1
在一些/许多/所有的C++实现中,NULL是一个宏,被扩展为0。这样扩展后,相当于给出了return 0,这是一个有效的返回值。

这只是糟糕的编码风格吗?

是的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接