3

I have this code :

#include <iostream>

class ZombieFetus{
  private:
  public:
  ZombieFetus();
};

ZombieFetus::ZombieFetus(){
  std::cout << "http://www.metal-archives.com/band/view/id/55878" << std::endl;
};

class FaceOfAVirus{
  private:
  public:
  FaceOfAVirus(int);
};

FaceOfAVirus::FaceOfAVirus(int i){
  std::cout << "http://www.metal-archives.com/band/view/id/74239" << std::endl;
};


int main(int argc, char **argv){
  std::cout << "some random bands :" << std::endl;
  ZombieFetus  band1();
  FaceOfAVirus band2(0);
}

to compil :

$  g++ main.cc -Wall

When I run it I got :

some random bands :
http://www.metal-archives.com/band/view/id/74239

what the heck with ZombieFetus band1(); ? what does the program ? it's sound to be a beginner question, if it's already answered on stackoverflow, plz give me the link... I don't find the answer...

thx to everyone who answered and all comentators

(you are a little too numerous to thx one by one)

The Unholy Metal Machine
  • 1,093
  • 2
  • 17
  • 36
  • @chris How is that a function? It's an object of type ZombieFetus – Pepe Nov 27 '13 at 03:45
  • @chris what do you mean? I don't have a type in front of the definition – The Unholy Metal Machine Nov 27 '13 at 03:46
  • possible duplicate of [Most vexing parse(C++)](http://stackoverflow.com/questions/5926103/most-vexing-parsec) – Sergey Kalinichenko Nov 27 '13 at 03:50
  • @Pepe It's not, it's the declaration for a function named `band1` that returns a `ZombieFetus`. Look up vexing parse. – Retired Ninja Nov 27 '13 at 03:51
  • @bobthemightyspellcaster if I showed you **just this**: 1 `ZombieFetus band1();` what you you say it was? The declaration of an object `band1` of type `ZombieFetus` that takes no arguments for its constructor? Or could it be the declaration of a function prototype named `band1` that takes no parameters and *returns* a `ZombieFetus` as its result? The compiler is choosing the latter, though you're intention is the former. – WhozCraig Nov 27 '13 at 03:52
  • @RetiredNinja I stand corrected. I missed the parentheses. – Pepe Nov 27 '13 at 03:56
  • 2
    @dasblinkenlight I didn't think this was an MVP. Its not that convoluted. An MVP usually has a single param with the provided parameter a temp construction, like `MyObject obj(SomeType())`, doesn't it? (I'm always confusing the two myself, so hence the inquisition). – WhozCraig Nov 27 '13 at 03:57
  • first time I hearing about "vexing parse"... I wonder why g++ doesn't say something... – The Unholy Metal Machine Nov 27 '13 at 04:01
  • 1
    @bobthemightyspellcaster A full-on mvp like I described in my prior comment is actually warned by some compilers. Yours isn't that convoluted. its just the compiler deducing your declaring a function prototype (something not-so-well-known that you can do *in* a function) that is causing you grief. Anyway, it looks like you found an answer, so good on that =) gratz. It is a "vexing" parse, to be sure; just not the "most" =P – WhozCraig Nov 27 '13 at 04:05
  • Official definitions aside, I think the most vexing parse is the one currently making you pull your hair out. :) – Retired Ninja Nov 27 '13 at 04:08
  • @WhozCraig now I fear turning paranoiac... seeing «vexing parse» everytime I won't understand something... so if I don't understand why a girl is overreacting, I will tell to my conscious : «don't worry dude, only some kind of vexing parse...» – The Unholy Metal Machine Nov 27 '13 at 04:11
  • @WhozCraig actually rereading that section of *effective STL* and it may actually fall under *MVP*, he refers to it as *another manifestation of this rule* – Shafik Yaghmour Nov 27 '13 at 05:10

4 Answers4

8

The problem is that this:

ZombieFetus  band1();

is a intepreted as a function declaration, you have two possible fixes in C++11:

ZombieFetus  band1{} ;

or pre C++11:

ZombieFetus  band1;

clang is a little more helpful here and warns:

warning: empty parentheses interpreted as a function declaration [-Wvexing-parse]
      ZombieFetus  band1();
                        ^
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • for christmas, I will ask santa to install clang on my computer. Isn't the first time I see that clang gives better errors and warnings messages... – The Unholy Metal Machine Nov 27 '13 at 03:59
  • @bobthemightyspellcaster there are several [online compilers](http://stackoverflow.com/questions/3916000/online-c-compiler-and-evaluator) that you can use and try things out without a local install. – Shafik Yaghmour Nov 27 '13 at 04:01
  • I actually didn't know my clang was sharp enough to catch this with a warning. +1 for teaching me that, sir. – WhozCraig Nov 27 '13 at 04:07
  • well done for the answer - esp the C++ 11 hint which, while probably useless, is interesting. this is a classic newbie mistake that you just won't now about until you hit it the first time... its also a part of the language that helps make writing the compiler hard. – jheriko Nov 27 '13 at 04:08
  • @WhozCraig that is why I am always trying code in different compilers b/c you find all these odds and ends especially with the C++11 stuff. – Shafik Yaghmour Nov 27 '13 at 04:09
  • @jheriko, Not at all. The C++11 version causes value-initialization and the pre-C++11 version causes default-initialization. The equivalent value-initialization in pre-C++11 is `ZombieFetus band1 = ZombieFetus();` – chris Nov 27 '13 at 04:12
  • i don't really get that. so it uses the copy constructor to copy a default in the second example? and the C++11 style {} syntax does this - I'd still argue that is useless when you can already explicitly state that this is what you want (which would suggest to me that something else is 'wrong'...). i guess i am missing something. it is still interesting to learn something new... – jheriko Nov 27 '13 at 04:23
3

The default constructor does not take parameters, so remove the () like

ZombieFetus  band1;

and you get

make -k x; ./x
g++     x.cc   -o x
some random bands :
http://www.metal-archives.com/band/view/id/55878
http://www.metal-archives.com/band/view/id/74239

But this is a "forward" declaration of a function band1 which returns ZombieFetus

ZombieFetus  band1();
Soren
  • 14,402
  • 4
  • 41
  • 67
2

Change:

ZombieFetus band1();

to

ZombieFetus band1;

When instantiating an object with no arguments, you should not use parentheses.

craiglm
  • 326
  • 1
  • 5
  • +1 (and a few others got it as well). You can also do `ZombieFetus band1 = ZombieFetus();` if it makes you feel better about the decl, and any compiler worth its salt will elide the copy. If it doesn't, get a new compiler. – WhozCraig Nov 27 '13 at 04:01
2

ZombieFetus band1(); declares a function named band1, which takes no parameter and returns a value of type ZombieFetus. If you want to used the default constructor, 'ZombieFetus band1;' will be fine. Hope this will help.

Morrissss
  • 324
  • 2
  • 8