void func() {assert(0);}
int main () {void func();}
上面的代码不调用func(),或者至少没有达到断言。不是我真的需要知道,但我只是好奇,这里发生了什么?
答案 0 :(得分: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); }
它只会产生语法错误。
答案 1 :(得分:5)
正如其他人所指出的,行
void func();
main
内的被视为函数原型,而不是对函数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>
作为参数的对象。要解决这个问题,在C ++中你必须编写
set<int> mySet(istream_iterator<int>(cin), (istream_iterator<int>()));
如上所述,额外的括号强制消除语句从函数原型到声明的歧义。
希望这有帮助!
答案 2 :(得分:4)
即使不需要,您也可以声明功能。这就是你所做的,重新宣布了这个功能。
答案 3 :(得分:0)
您在void func()
内声明了一个本地函数main()
。
void
语句指示编译器它是声明而不是函数调用。因此,删除void
,您的函数将被调用。