7

I am new to C++ and just try out stuff. I stuck with the following code:

#include<iostream>  

void t(){
    std::cout << "func t()" << std::endl;
}

int main(int argc, char **argv) {
    int t(); //declaration of function
    std::cout << t() << std::endl;
}

The output is "func t()\n6295712". My concern is the random(?) number printed by t().

My question is: Why is it allowed to declare a function of another return-type (here: int instead of void) without any error? Is this not a violation of type safety because I never defined a function with a return-type "int"?

Used compiler: gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4

no_use123
  • 294
  • 3
  • 12
  • My output here is `func t()\n6295680`, which is different from **only** `6295712`. Is your program really only printing that number? – Marcus Müller Mar 25 '16 at 16:43
  • You're right, I edited it - I was just concerned with the number and forgot the other output. Thanks – no_use123 Mar 25 '16 at 16:48
  • can confirm wtf http://coliru.stacked-crooked.com/a/f9b957636b731736 – Lightness Races in Orbit Mar 25 '16 at 16:49
  • 1
    I think this is a gcc bug, clang doesn't compile it. Looking for the right part of the standard... – Barry Mar 25 '16 at 16:50
  • I agree with Barry (lol). Having skimmed the standard, this is not a viable overload _and_ the function declarations don't agree with each other in param-list and return type. There's no way I can see that this program is well-formed. Arguably this is UB rather than ill-formed but I'd still expect a diagnostic from a mainstream compiler. – Lightness Races in Orbit Mar 25 '16 at 16:51
  • @BarryTheHatchet Best I can find is a note. – Barry Mar 25 '16 at 17:11

1 Answers1

4

The only relevant thing I can find is a note in [basic.scope.pdecl]:

Function declarations at block scope and variable declarations with the extern specifier at block scope refer to declarations that are members of an enclosing namespace, but they do not introduce new names into that scope.

So when you write:

void t();

int main() {
    int t();  // *
}

That inner declaration refers to a member of the enclosing namespace. So it's equivalent to having written:

void t();
int t();

int main() {}

But functions cannot overload solely in return type, so this code is ill-formed. Clang rejects both programs, gcc only rejects the latter. I believe this is a gcc bug.

Barry
  • 286,269
  • 29
  • 621
  • 977