4
void func() {assert(0);}
int main () {void func();}

上面的代码没有调用func(),或者至少没有达到断言。不是我真的需要知道,但我只是好奇,这里发生了什么?

4

4 回答 4

10

您正在为一个名为的函数声明一个原型,该函数func不返回任何内容且不接受任何参数。这是函数调用和函数原型之间的细微差别之一。请注意,上面的行main,void func() {assert(0);}对这是原型还是调用没有影响。你可以删除它,代码也会做同样的事情——也就是说,什么都不做。

这也告诉您可以重新声明函数原型。你甚至可以有这个:

int main() {
    void blah();
    void blah();
    void blah();
    void blah();
}

并且代码仍然会像以前那样做 - 什么都没有。

如果您不使用void,它将调用该函数。

另外,请注意,对于带有参数的函数,这是:

int main() { func(4); }

如果您在它之前添加这样的内容,则不会变成原型void

int main() { void func(4); }

它只会产生语法错误。

于 2011-08-04T02:23:28.513 回答
5

正如其他人指出的那样,这条线

void func();

inside ofmain被视为函数原型,而不是对函数的调用func。在 C 和 C++ 中,如果您愿意,可以在函数内部声明函数原型,尽管在实践中很少这样做。

这是合法的事实给程序员带来了各种各样的头痛。例如,如果您将代码重写为

(void) func();

然后这将编译为对其func返回类型显式转换void以指示“我不关心此返回值”的调用。换句话说,这组括号将声明更改为语句。

在 C++ 中,由于以下代码是函数原型,而不是调用默认构造函数的变量声明,这个问题可能会更加复杂:

Object myObject();

尽管

Object myObject(137);

确实创建了对象并将 137 传递给它的构造函数,并且

Object myObject;

创建对象而不调用构造函数。

当试图在调用其构造函数时声明一个对象时,会出现这种语言的一个可怕的边缘情况,称为“最令人烦恼的解析”。例如,这段代码是合法的 C++,但它是函数声明而不是变量声明:

set<int> mySet(istream_iterator<int>(cin), istream_iterator<int>());

问题是这可以被解析为函数声明,而不是创建一个接受两个临时istream_iterator<int>s 作为参数的对象。要解决这个问题,在 C++ 中你必须编写

set<int> mySet(istream_iterator<int>(cin), (istream_iterator<int>()));

如上所述,额外的括号强制将语句从函数原型变为声明。

希望这可以帮助!

于 2011-08-04T02:29:15.113 回答
4

你可以声明函数,即使它是不必要的。这就是你所做的,重新声明了函数。

于 2011-08-04T02:23:56.627 回答
0

你在void func()里面声明一个本地函数main()。该void语句指示编译器它是一个声明而不是函数调用。因此,删除void,您的函数将被调用。

于 2011-08-04T04:38:53.893 回答