Odd syntax errror

Started by
13 comments, last by Drakkcon 16 years, 3 months ago
I really thought that syntax errors were behind me, but Visual Studio 2008 just served me a cold plate of humble pie. I am getting the errors:

videosystem.h(27) : error C2065: 's' : undeclared identifier
videosystem.h(27) : error C3867: 'lichen::VideoSystem::Screen': function call missing argument list; use '&lichen::VideoSystem::Screen' to create a pointer to member.
And here is the offending code:

ScreenPtr SetVideoMode(int width, int height, int bpp, 
								bool useHw = false, bool fs = false) {
			unsigned flags = 0;
			if(useHw)
				flags |= SDL_HWSURFACE;
			else
				flags |= SDL_SWSURFACE;
			
			if(fs)
				flags |= SDL_FULLSCREEN;
				
			flags |= SDL_DOUBLEBUF;
				
			SDL_Surface* scr = SDL_SetVideoMode(width, height, bpp, flags);
			ScreenPtr temp (new Screen(scr));
			screen = temp;
			
			
			
			return screen;			
		}


And here are the Screen and Surface classes:

class Screen : public Surface {
	public:
		~Screen() {} //a screen doesn't release its backbuffer when it's destroyed
		Screen() {}
		Screen(SDL_Surface* screen) { this->sdlSurface = screen; this->created = true; }
		
		void Flip() { SDL_Flip(sdlSurface); }
		void Clear() { SDL_FillRect(sdlSurface, NULL, 0); }
	};
	
	typedef boost::shared_ptr <Screen> ScreenPtr;



class Surface {
	public:
		Surface() {}
		Surface(SDL_Surface* toWrap) : sdlSurface(toWrap), created(true) {}
		Surface(int width, int height, int bpp) { Create(width, height, bpp); }
		
		virtual ~Surface() { Destroy(); }
		
		void Create(int width, int height, int bpp)
			{ SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, bpp, 
											RMASK, GMASK, BMASK, AMASK);
			  created = true; }
		void Destroy() { if(created) SDL_FreeSurface(sdlSurface); }
		
		const SDL_Surface* SdlSurface() const { return sdlSurface; }
		
		void BlitFrom(SDL_Surface* src, const SDL_Rect& srcRect, 
										const SDL_Rect& dstRect);
		void BlitTo(Surface& surface, const BlitRect& blitRect) const;
		void BlitTo(Surface& surface) const;
		void Magnify(int magFactor);
		
		//assumes 32-bits. Other depths will be added later if needed
		void SetPixel(int pixRow, int pixCol, const Pixel& pix);
		Pixel GetPixel(int row, int col) const;
		void FillRect(int row, int col, int rows, int cols, const Pixel& pix);
		
		int BitsPerPixel() const { return sdlSurface->format->BitsPerPixel; }
		int Width() const { return sdlSurface->w; }
		int Height() const { return sdlSurface->h; }
		
		void Copy(const SDL_Surface* other) 
			{ SDL_BlitSurface((SDL_Surface*)other, NULL, sdlSurface, NULL);
			  created = true; }
		void Copy(const Surface& other) { Copy(other.SdlSurface()); created = true; }
		Surface& operator = (const Surface& other) { Copy(other); return *this; }
		
	protected:
		SDL_Surface* sdlSurface;
		
		bool created;
	};
	
	typedef boost::shared_ptr <Surface> SurfacePtr;


This has me confused. I can't even use Screen* s = new Screen(), I get the same error. I have no problem creating surfaces, just screens. Also, why is it that when I change the Screen constructor from

Screen(SDL_Surface* screen) { this->sdlSurface = screen; this->created = true; }
to

Screen(SDL_Surface* scr) sdlSurface(scr), created(true) {}
I get a ton of errors, the top of which is: screen.h(14) : error C3646: 'sdlSurface' : unknown override specifier When sdlSurface is clearly an inherited member. Thanks for any help! Edit: Also, I meant to put this in General Programming. Sorry about that.
Advertisement
Screen(SDL_Surface* scr) sdlSurface(scr), created(true) {}

Is missing the :.

Also, which is the offending line, I don't see it marked.

Moved to General Programming.
Yes, thanks for that, but now I'm getting the real error that I got originally (I accidentally removed that colon for some reason, but even with it I was having a problem).

Now I get this:
error C2614: 'lichen::Screen' : illegal member initialization: 'created' is not a base or member
error C2614: 'lichen::Screen' : illegal member initialization: 'sdlSurface' is not a base or member

Is what I am doing legal?

Oh, and here's the offending line in the VideoSystem definition:

ScreenPtr temp (new Screen(scr));
Quote:Original post by Drakkcon
Yes, thanks for that, but now I'm getting the real error that I got originally (I accidentally removed that colon for some reason, but even with it I was having a problem).

Now I get this:
error C2614: 'lichen::Screen' : illegal member initialization: 'created' is not a base or member
error C2614: 'lichen::Screen' : illegal member initialization: 'sdlSurface' is not a base or member

Is what I am doing legal?

Oh, and here's the offending line in the VideoSystem definition:

ScreenPtr temp (new Screen(scr));


Hard to say, but there's no reason for your current approach. You have constructor in surface, so use it:

Screen(SDL_Surface* screen) : Surface( screen ) {}


Why do you need Screen anyway, you could have all the functionality in the Surface anyway.
I've actually had this same problem. For some reason, I am unable to have a member variable of a base class in the constructor initialization list of a derived class. I get the exact same error as you do.
error C2614: 'GUI::DialogWindow' : illegal member initialization: 'm_WidgetType' is not a base or member
I ended up having to simply assign the member variable its value in the body of the constructor and not in the initialization list.

My first hunch was that you couldn't have the same member variable in two different initialization lists (once in a base class and once in a derived class) so I tried removing it from the initialization list of the base class, but I got the same error.

I'm using VS2008.

EDIT: This makes sense to me (somewhat). The base class constructor, in your case 'Surface', is the only place where the base class member variables, in your case 'created', are created and can be initialized upon creation. A derived class won't be able to initialize a member variable because it's already been created by the base class, so even if you tried to initialize it in the derived class initialization list it would have to boil down to an assignment which you might as well do in the body of the constructor.

The best way I see to do things is to make any member variables of a base class that you want to initialize in a derived class be parameters in the constructor of the base class.

In your case, instead of trying to initialize 'sdlSurface' and 'created' in the 'Surface' class, pass the values to want them to have as constructor parameters to the 'Screen' class and have the 'Screen' class do the member initialization.

[Edited by - Mantear on January 21, 2008 9:41:08 AM]
Quote:Original post by Antheus
Quote:Original post by Drakkcon
Yes, thanks for that, but now I'm getting the real error that I got originally (I accidentally removed that colon for some reason, but even with it I was having a problem).

Now I get this:
error C2614: 'lichen::Screen' : illegal member initialization: 'created' is not a base or member
error C2614: 'lichen::Screen' : illegal member initialization: 'sdlSurface' is not a base or member

Is what I am doing legal?

Oh, and here's the offending line in the VideoSystem definition:

ScreenPtr temp (new Screen(scr));


Hard to say, but there's no reason for your current approach. You have constructor in surface, so use it:

Screen(SDL_Surface* screen) : Surface( screen ) {}


Why do you need Screen anyway, you could have all the functionality in the Surface anyway.


Because screens can do certain things that plain old surfaces can't. Like "Flip" for instance. Also, a screen can't free it's memory when it's destructed due to peculiarities in the SDL API.

Also, I thought only default constructors were inherited. Oh I see, wow I never even thought about using the base constructor in the initialization list. This is what happens when you're self taught.
Quote:For some reason, I am unable to have a member variable of a base class in the constructor initialization list of a derived class


I was never under the impression that this should be possible. The compiler error message clearly states what I think the standard says as well (though I don't know for sure): You can't initialize a base class member in a derived class. That's why it's pretty common to pass such parameters to the base class constructor (you can use a protected constructor if you don't want anyone else to set these values).
__________________Oregon Ghost---Wenn NULL besonders gross ist, ist es fast schon wie ein bisschen eins ;c)if NULL is very big, it is almost like a little ONE.
Quote:
I was never under the impression that this should be possible. The compiler error message clearly states what I think the standard says as well (though I don't know for sure): You can't initialize a base class member in a derived class. That's why it's pretty common to pass such parameters to the base class constructor (you can use a protected constructor if you don't want anyone else to set these values).


I didn't know that about the standard, but I guess it makes sense. It's cleaner to use the base class constructor anyway. Thanks for explaining that.

Now does anyone know why I can't call the constructor for Screen?
The compiler error generated is, at least to me, misleading and/or confusing. The MSDN explaination for the error is as follows:
Only member or base classes can appear in the initialization list for a class or structure.ExampleThe following sample generates C2614.// C2614.cpp// compile with: /cstruct A {   int i;   A( int ia ) : B( i ) {};   // C2614 B is not a member of A};struct A2 {   int B;   int i;   A2( int ia ) : B( i ) {};   // OK};
I believe my confusion centers around the usage of 'member'. In Drakkcon's case, both 'sdlSurface' and 'created' are members of the derived class 'Surface', but only because they were inherited through 'Screen'. But they are still members. The MSDN example code says you can't initialize something that's not a member, but their example and the text of the error code say nothing about members obtained through inheritance, which they apparently do not consider to be 'members' in this context.
Yes, that's interesting. I appreciate the depth of msdn's documentation but sometimes they don't communicate very well.

In unrelated news I'm still having the problem with Screen being unable to be initialized. I just tried it in "main()" and it compiled fine, but when it's inside any method of VideoSystem it doesn't work.

Perhaps I should show the full source of VideoSystem:
#include "SDL.h"#include "Screen.h"#ifndef LICHEN_VIDEOSYSTEM_H#define LICHEN_VIDEOSYSTEM_Hnamespace lichen {	class VideoSystem {	public:		VideoSystem() : initialized(false) {}		~VideoSystem() { Shutdown(); }			ScreenPtr SetVideoMode(int width, int height, int bpp, 								bool useHw = false, bool fs = false) {			unsigned flags = 0;			if(useHw)				flags |= SDL_HWSURFACE;			else				flags |= SDL_SWSURFACE;						if(fs)				flags |= SDL_FULLSCREEN;							flags |= SDL_DOUBLEBUF;									SDL_Surface* scr = SDL_SetVideoMode(width, height, bpp, flags);			//vv error C2061: syntax error : identifier 'Screen'			ScreenPtr temp (new Screen(scr));			screen = temp;												return screen;					}				void Shutdown() 			{ if(initialized) SDL_QuitSubSystem(SDL_INIT_VIDEO); initialized = false; }				ScreenPtr Screen() { return screen; }			private:		bool initialized;		ScreenPtr screen;	};		typedef boost::shared_ptr <VideoSystem> VideoSystemPtr;	}#endif

This topic is closed to new replies.

Advertisement