7

Why does the following code compile without warnings. Notice that blablabla() is not defined anywhhere.

I tested it in gcc 5.1.0 and clang-3.7.0 (with and without the -std=c++11 flag).

#include <string>

int main()
{
    std::string(blablabla());
}

This questions is not a duplicate of the most vexing parse ambiguity, since related examples declare functions with a parameter.

oo_miguel
  • 2,374
  • 18
  • 30
  • If I were to wager a guess, the statement is optimized out, because you simply aren't using it in any way. You aren't assigning the string to a variable nor are you passing it to a function. As such the compiler may well be 'overlooking' it. But that's a guess. – Refugnic Eternium Oct 22 '15 at 06:36
  • 3
    Warnings should be independent of *any* optimization, in any recent compiler. – Kamajii Oct 22 '15 at 06:36
  • Err, if `blablabla()` were a function that does `cout << "Hello\n";`, how would that optimisation work out then? I'm pretty certain you're not allowed to optimise code in such a way that it fundamentally changes the behaviour. In any case, it's not actually *calling* `blablabla`, there's no difference between that statement and one with the outer parentheses removed. – paxdiablo Oct 22 '15 at 06:37
  • Maybe you simply need to enable more warnings? Try adding `-Wall` when building (something you should do always anyway). – Some programmer dude Oct 22 '15 at 06:37
  • `-Wall` does not make any difference. – oo_miguel Oct 22 '15 at 06:38
  • 11
    Isn't `std::string(blablabla());` the same as `std::string blablabla();`? – Bo Persson Oct 22 '15 at 06:39
  • @Bo Persson: I made some experiments, and it seems you are right. I can even define a function as: `std::string(blablabla()){return "x";}`. But what kind of syntax is this? Never saw this before anywhere. – oo_miguel Oct 22 '15 at 06:53
  • 2
    @oo_miguel - It is standard C declaration syntax. Sometimes the `()` are needed, like when making a pointer to function `int (*f)();` different from a function returning a pointer `int* f();`. Using extra `()` is *allowed* even when not strictly needed, as that made the language description simpler. – Bo Persson Oct 22 '15 at 07:00
  • 1
    Possible duplicate of [Most vexing parse: why doesn't A a(()); work?](http://stackoverflow.com/questions/1424510/most-vexing-parse-why-doesnt-a-a-work) – Jens Oct 22 '15 at 07:04
  • @Bo Persson So in my example the compiler simply ignores the extra parentheses. This makes sense, thank you! – oo_miguel Oct 22 '15 at 07:08
  • `std::string(blablabla()){return "x";}` is a nested function, which is not part of Standard C++, but g++ has them – M.M Nov 03 '15 at 10:29
  • Compare: `std::string (*blablabla(void));` This just don't have the `*` and the `void` is implicit. – David Schwartz Nov 03 '15 at 18:25

1 Answers1

8

Ahhhh I'm dumb.

It's not treated as a call. The compiler just sees it as a declaration...

Try, for comparison:

int main() {
    int(blablabla);
}

This gives:

test.c++: In function ‘int main()’:
test.c++:6:9: warning: unused variable ‘blablabla’ [-Wunused-variable]
     int(blablabla);
         ^

More precisely, your statement std::string(blablabla()) declares blablabla to be a function returning an std::string, the same as

std::string blablabla();

would do. A local function declaration.

Kamajii
  • 1,826
  • 9
  • 21
  • Is int(blablabla); the same as the declaration int blablabla; ? – ramana_k Oct 22 '15 at 06:48
  • 3
    Ramana: Yes, you just parenthesed the identifier. Insert a space and it will be clearer: `int ((((blablabla))));`. Btw, there are also cases where the parentheses are even necessary, namely when declaring funtion pointers (to attach the star to the identifier and not the return type). – Kamajii Oct 22 '15 at 07:04
  • @Ramana Yes, the clue is that it warns that the variable `blablabla` is not being used. – skyking Oct 22 '15 at 07:41