简体   繁体   English

C ++ void前缀为函数调用。 例如。 `main(){void func();}`

[英]C++ void prefixed to a function call. eg. `main() {void func();}`

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

The above code does not call func(), or at least does not reach the assertion. 上面的代码不调用func(),或者至少没有达到断言。 Not that I really need to know, but I'm just curious, what is going on here? 不是我真的需要知道,但我只是好奇,这里发生了什么?

You're declaring a prototype for a function named func which returns nothing and takes no arguments. 您正在声明一个名为func的函数的原型,该函数不返回任何内容并且不带参数。 That's (one of) the subtle difference between function calls and function prototypes. 这是(一个)函数调用和函数原型之间的细微差别。 Notice that the line above main , the void func() {assert(0);} , has no effect on whether this is a prototype or a call. 请注意, main上面的行, void func() {assert(0);} ,对这是原型还是调用没有影响。 You could remove it and the code would do the same thing - that is, nothing. 你可以删除它,代码会做同样的事情 - 也就是说,没有。

This also tells you that you can redeclare function prototypes. 这也告诉您可以重新声明函数原型。 You could even have this: 你甚至可以这样:

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

And the code would still do what it did before - nothing. 代码仍然可以做它以前做过的事 - 没有。

If you leave off the void , it would call the function. 如果你忽略了void ,它会调用该函数。

Also, notice that in the case of a function which takes parameters, this: 另外,请注意,在带参数的函数的情况下,这个:

int main() { func(4); }

would not turn into a prototype if you added void before it like this: 如果您在此之前添加了void ,则不会变成原型:

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

it would just produce a syntax error. 它只会产生语法错误。

As others have pointed out, the line 正如其他人所指出的那样

void func();

inside of main is treated as a function prototype rather than a call to the function func . main内部被视为函数原型,而不是函数func的调用。 In C and C++, you can declare function prototypes inside of functions if you wish, though it's rarely done in practice. 在C和C ++中,如果您愿意,可以在函数内部声明函数原型,尽管在实践中很少这样做。

The fact that this is legal causes all sorts of headaches for programmers. 这是合法的事实会给程序员带来各种麻烦。 For example, if you rewrote the code as 例如,如果您将代码重写为

(void) func();

Then this would compile as a call to func whose return type is explicitly casted to void to indicate "I don't care about this return value." 然后这将编译为对func的调用,其返回类型显式地转换为void以指示“我不关心此返回值”。 In other words, this set of parentheses changes the declaration into a statement. 换句话说,这组括号将声明更改为语句。

In C++, this problem can be compounded by the fact that this code below is a function prototype, not a variable declaration invoking the default constructor: 在C ++中,这个问题可能因以下代码是函数原型而不是调用默认构造函数的变量声明而变得复杂:

Object myObject();

Though 虽然

Object myObject(137);

does create the object and pass 137 into its constructor, and 确实创建了对象并将137传递给它的构造函数,并且

Object myObject;

creates the object without calling the constructor. 在不调用构造函数的情况下创建对象。

There is an awful edge case of the language called the "most vexing parse" that arises when trying to declare an object while calling its constructor. 在调用其构造函数时尝试声明对象时,会出现一种称为“最令人烦恼的解析”的语言边缘情况。 For example, this code is legal C++, but it's a function declaration rather than a variable declaration: 例如,这段代码是合法的C ++,但它是一个函数声明而不是一个变量声明:

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

The problem is that this could be parsed as a function declaration rather than a creation of an object that accepts two temporary istream_iterator<int> s as parameters. 问题是,这可以解析为函数声明,而不是创建一个接受两个临时istream_iterator<int>作为参数的对象。 To fix this, in C++ you'd have to write 要解决这个问题,在C ++中你必须写

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

Where, as above, the extra parentheses forcibly disambiguate the statement from being a function prototype to being a declaration. 如上所述,额外括号强制将语句从函数原型消除歧义为声明。

Hope this helps! 希望这可以帮助!

You can declare functions, even when it's unnecessary. 即使没有必要,您也可以声明功能。 That's what you've done, re-declared the function. 这就是你所做的,重新宣布了这个功能。

You are declaring a local function void func() inside main() . 你在main()中声明一个局部函数void func() main() The void statement indicates the compiler that it is a declaration and not a function call. void语句指示编译器它是声明而不是函数调用。 So, remove the void , your function will be called. 因此,删除void ,将调用您的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM