Expected class-name before { token

Dec 31, 2010 at 1:30pm
I've encountered another problem whilst trying to compile a fairly large codebase(about 20 classes). I'm getting the following compiler-error:


/path/to/Sphere.h|9|error: expected class-name before ‘{’ token


This is the problematic code:

1
2
3
#include "GeometricObject.h"

class Sphere : public GeometricObject {


Since there are quite a lot of files, I'm not expecting there to be a straight forward solution to this, but how would I go about finding a solution to this? If someone could point me in the right direction, I would be very grateful;)
Dec 31, 2010 at 1:57pm
It looks like the compiler does not know what GeometricObject is. Find the definition (grep) and verify that it (and its header) is spelled correctly, available in Sphere's namespace, and public.
Dec 31, 2010 at 2:16pm
I think all that should be covered, but if you would care to take a look, here's the GeometricObject class

GeometricObject.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

#ifndef __GEOMETRICOBJECT__
#define __GEOMETRICOBJECT__

class RGBColor;
class ShadeRec;

#include "Ray.h"
#include "ShadeRec.h"
#include "RGBColor.h"

class GeometricObject {
	public:
		GeometricObject(void);
        	GeometricObject(const GeometricObject& g);
		virtual ~GeometricObject(void);

		virtual bool hit(const Ray& ray, double& tmin, ShadeRec& sr) const = 0;
	protected:
		RGBColor color;	//to be replaced

        GeometricObject& operator =(const GeometricObject& rhs);
};

#endif 


GeometricObject.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

#include "GeometricObject.h"

GeometricObject::GeometricObject(void) : color(0.0, 0.0, 0.0) {
}

GeometricObject::GeometricObject(const GeometricObject& g) {
}

GeometricObject::~GeometricObject(void) {
}

GeometricObject& GeometricObject::operator =(const GeometricObject& rhs) {
        if (this == &rhs) {
            return (*this);
        }
        color = rhs.color;
        return (*this);
}
Dec 31, 2010 at 4:29pm
1
2
3
4
5
6
#ifndef __GEOMETRICOBJECT__
#define __GEOMETRICOBJECT__

...

#endif 


You might want to check to make sure you have not defined __GEOMETRICOBJECT__ in another file by accident (copy/paste?) since doing so would skip your definition of GeometricObject. The compiler doesn't seem to think GeometricObject is a class name. Your declaration of Sphere looks correct, so I would guess that the problem is with the base class.
Jan 2, 2011 at 1:25pm
Ok, I checked that now, and it seems fine, I cant see any definitions of __GEOMETRICOBJECT__ anywhere else. I realize now that I forgot to include the full compiler error, maybe that could help:


In file included from World.h:11:0,
                 from ShadeRec.h:9,
                 from GeometricObject.h:9,
                 from GeometricObject.cpp:2:
Sphere.h:9:39: error: expected class-name before ‘{’ token
Jan 2, 2011 at 2:51pm
Ok, here is what happens:
* GeometricObject.cpp includes GeometricObject.h in order to get the definition for class GeometricObject
* GeometricObject.h includes ShadeRec.h in order to get the definition of ShadeRec. Notice that at this point GeometricObject is not defined yet.
* some other include stuff along the chain
* Sphere.h tries to include GeometricObject.h, but the guarding token __GEOMETRICOBJECT__ has been already defined and nothing happens
* class Sphere tries to derive from Geometric object, but it still has no definition. It will later, after the preprocessor returns from the ShadeRec.h include inside GeometricObject.h, but this is no use at this point

What can you do?
You can use forward declaration as you have used already in some places. Such declaration tells the compiler that you know a certain class is defined somewhere, but you disclose nothing yet about its interface and members.

You can not do this:
1
2
3
4
5
6
// remove #include "GeometricObject.h"

class GeometricObject; // the fore-mentioned forward declaration

class Sphere : public GeometricObject {
...
, because this is inheritance, and the forward declaration provides no information on the size of the GeometricObject class, nor on the interface.

But you can do this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef __GEOMETRICOBJECT__
#define __GEOMETRICOBJECT__

class RGBColor;
class ShadeRec; // you already have forward declaration

#include "Ray.h"
// optionally remove #include "ShadeRec.h"
#include "RGBColor.h"

class GeometricObject {
	public:
		GeometricObject(void);
        	GeometricObject(const GeometricObject& g);
		virtual ~GeometricObject(void);

		virtual bool hit(const Ray& ray, double& tmin, ShadeRec& sr) const = 0;
	protected:
		RGBColor color;	//to be replaced

        GeometricObject& operator =(const GeometricObject& rhs);
};

#endif 
, because GeometricObject only refers to ShadeRec, it does not contain ShadeRec objects as member variables and doesn't inherit from the ShadeRec class.

It is impossible to have mutual containment, like A contains/derives from B, and B contains/derives from A. This would create infinite recursion between the definitions of those two classes.

Regards
Jan 3, 2011 at 5:53am
You, my good Sir, are a genius! That solves the issue! Thanks so much for taking the time:)
Jan 3, 2011 at 7:25am
Actually, I made a mistake :) I wrote that you should optionally remove #include "ShadeRec.h". You should definitely remove it. Nonetheless, I'm glad you worked it out.

Regards
Topic archived. No new replies allowed.