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

发布于 2024-11-27 17:05:13 字数 139 浏览 3 评论 0原文

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

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

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

The above code does not call func(), or at least does not reach the assertion. Not that I really need to know, but I'm just curious, what is going on here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

禾厶谷欠 2024-12-04 17:05:13

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

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

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

代码仍然会做以前所做的事情——什么也不做。

如果您省略 void,它将调用该函数。

另外,请注意,对于采用参数的函数,

int main() { func(4); }

如果您像这样在 this: 之前添加 void ,则 this: 不会变成原型:

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

它只会产生语法错误。

You're declaring a prototype for a function named func which returns nothing and takes no arguments. 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. 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.

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:

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

it would just produce a syntax error.

蓝眼泪 2024-12-04 17:05:13

正如其他人指出的那样,

void func();

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

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

(void) func();

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

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

Object myObject();

尽管

Object myObject(137);

确实创建了对象并将 137 传递到其构造函数中,但

Object myObject;

在不调用构造函数的情况下创建了对象。

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

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

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

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

Where,如上所述,额外的括号强制消除语句从函数原型到声明的歧义。

希望这有帮助!

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. In C and C++, you can declare function prototypes inside of functions if you wish, though it's rarely done in practice.

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." 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:

Object myObject();

Though

Object myObject(137);

does create the object and pass 137 into its constructor, and

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:

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. To fix this, in C++ you'd have to write

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!

倾城花音 2024-12-04 17:05:13

即使没有必要,您也可以声明函数。这就是您所做的,重新声明了该函数。

You can declare functions, even when it's unnecessary. That's what you've done, re-declared the function.

何时共饮酒 2024-12-04 17:05:13

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

You are declaring a local function void func() inside main().
The void statement indicates the compiler that it is a declaration and not a function call. So, remove the void, your function will be called.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文