4

So I have this code for these Constructors of the Weapon class:

Weapon(const WeaponsDB * wepDB);
Weapon(const WeaponsDB * wepDB_, int * weaponlist);
~Weapon(void);  

And I keep getting an error:

1>c:\users\owner\desktop\bosconian\code\bosconian\weapon.h(20) : error C2062: type 'int' unexpected

and ensuing errors (more than listed):

1>c:\users\owner\desktop\bosconian\code\bosconian\weapon.h(21) : error C2059: syntax error : '('
1>c:\users\owner\desktop\bosconian\code\bosconian\weapon.h(21) : error C2238: unexpected token(s) preceding ';'
1>c:\users\owner\desktop\bosconian\code\bosconian\weapon.h(33) : error C2327: '<unnamed-tag>::maxWeapons' : is not a type name, static, or enumerator
1>c:\users\owner\desktop\bosconian\code\bosconian\weapon.h(33) : error C2065: 'maxWeapons' : undeclared identifier
1>c:\users\owner\desktop\bosconian\code\bosconian\weapon.h(38) : warning C4094: untagged 'class' declared no symbols

I'm a semi-newbie and I haven't been able to figure it out.

Line 21 is the second constructor, the first one doesn't cause an error. Also, if I comment out this constructor I still get all the errors listed after that constructors. Any idea what the problem might be?

Here is the preceding code for reference:

#ifndef Weapon
#define Weapon
#include <allegro.h>
#include <stdio.h>
#include <iostream>

using namespace std;

class WeaponsDB;
class MenuDriver;
class Ammo;

class Weapon
{
public:
.....
Chad
  • 2,335
  • 8
  • 29
  • 45

8 Answers8

19
#ifndef Weapon
#define Weapon

This is almost certainly going to cause weirdness; call the constant WEAPON_H instead.

Ana Betts
  • 73,868
  • 16
  • 141
  • 209
  • @Paul Betts: I changed _WEAPON_H to WEAPON_H_ in your answer. See http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier – e.James Dec 16 '08 at 21:25
  • If your compiler supports #pragma once you might consider using that instead, as it's potentially faster, and definitely cleaner to read. – mackenir Dec 16 '08 at 21:43
  • @mackenir, I feel like the #ifndef/#define/#endif thing has turned into an idiom by now, so it's not really a matter of being easier to read. I would look askance at any header that didn't have it because it's become so ubiquitous. – Josh Matthews Dec 16 '08 at 21:49
  • @mackenir: Herb Sutter and Andrei Alexandrescu write in their books that 'most compilers' nowadays recognize macro guards and offer the same performance advantage as using _#pragma once_ – David Rodríguez - dribeas Dec 16 '08 at 22:27
  • Standing back (and shaking off the habits of years) I think a single-line #pragma at the top of the file is cleaner than bracketing the entire header in a bunch of preprocessor boilerplate. I've screwed up the old style way of doing things in the past (wrong symbol copy-n-pasted to a new hdr). – mackenir Dec 16 '08 at 22:30
  • @dribeas: interesting. Still, it's messy and old-fashioned. Everyone just agree with me. ;) – mackenir Dec 16 '08 at 22:31
  • mackenir, i disagree with you too. #pragma once isn't standard and should be avoided since c++ provides the same in a guaranteed working way. and i find it easier to read – Johannes Schaub - litb Dec 16 '08 at 23:07
7

So you named your class the same as a preprocessor directive? That is something I would avoid.

Try changing your preprocessor Weapon or making a different class name. I think it will work better.

Tim
  • 20,184
  • 24
  • 117
  • 214
5

I think the problem is in the #define Weapon - any occurence of "Weapon" later on in the code will be removed or replaced by something you didn't intend.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
4

To anplify Tim's answer. You see the code like this:

#ifndef Weapon
#define Weapon
#include <allegro.h>
#include <stdio.h>
#include <iostream>

using namespace std;

class WeaponsDB;
class MenuDriver;
class Ammo;

class Weapon
{
public:
   Weapon(const WeaponsDB * wepDB);
   Weapon(const WeaponsDB * wepDB_, int * weaponlist);
   ~Weapon(void);
}

But you've defined the preprocessor macro Weapon as an empty string, so the compiler sees this:

#ifndef Weapon
#define Weapon
#include <allegro.h>
#include <stdio.h>
#include <iostream>

using namespace std;

class sDB;
class MenuDriver;
class Ammo;

class 
{
public:
   (const sDB * wepDB);
   (const sDB * wepDB_, int * weaponlist);
   ~(void);
}

Just change the include guard to use a string that doesn't occur as a name (e.g. WEAPON_H_INCLUDED).

Stephen C. Steel
  • 4,380
  • 1
  • 20
  • 21
  • The preprocessor wouldn't munge the WeaponsDB entries though since it goes by whole words. Otherwise if someone were to #define C they'd be in a whole world of strife. – Dominik Grabiec Dec 17 '08 at 01:36
2

Like other answers already made available, I also suspect the preprocessor directive.

To confirm, say on GCC, you can request it to only run the preprocessor and save that output somewhere. There's probably similar features for the compiler that you use.

Calyth
  • 1,673
  • 3
  • 16
  • 26
0

I don't know if this is Microsoft-specific (I have only used VS2005 recently), but this works. I start all my header files with:

#pragma once
isekaijin
  • 19,076
  • 18
  • 85
  • 153
0

GCC also supports "#pragma once" but it's not standard and code will be more portable if you use the traditional include guard #ifndef _MYFILE_H_ or some variant.

-1

Just a quick note: in C++, unlike C, when a function (or destructor, in this case) doesn't have any parameter, you don't need to use (void), you just use ().

Marc
  • 1,356
  • 2
  • 10
  • 15