开发者

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

开发者 https://www.devze.com 2023-03-24 22:17 出处:网络
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 curi
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?


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.


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!


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(). 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消