Jump to content
  • Advertisement
Sign in to follow this  
zoner7

undefined type compiler errors

This topic is 2862 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I am getting a typical error that is presenting itself in a very weird way.
The compiler is complaining about the following file, particularly regarding the declaration of the MenuItem variables and of the the vector of MenuItems.


#pragma once

#include "MenuItem.h"
#include "Headers.h"
#include "Game.h"
#include "GameState.h"
#include "PlayGameState.h"
#include "MapEditorState.h"

class Game;

class MenuState : public GameState
{
public:
MenuState();

public:
void Start();
void HandleEvents();
void Render();
void Update();
void End();

private:
std::vector<MenuItem> MenuItems;

sf::Sprite sprite_titleScreen;

MenuItem play;
MenuItem options;
MenuItem editor;
MenuItem quit;
};







here are the compiler errors:

c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(26): error C2065: 'MenuItem' : undeclared identifier
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(30): error C2146: syntax error : missing ';' before identifier 'play'
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(30): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(30): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(31): error C2146: syntax error : missing ';' before identifier 'options'
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(31): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(31): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(32): error C2146: syntax error : missing ';' before identifier 'editor'
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(33): error C2146: syntax error : missing ';' before identifier 'quit'
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(33): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(33): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

My initial thought was that I misspelled something, used the wrong case, or didn't properly include the declaration of the MenuItem class.

MenuItem.h is indeed included, though. Here is its contents:


#pragma once

#include "Headers.h"
#include "Game.h"

class MenuItem
{

public:
MenuItem();
MenuItem(const sf::Vector2f& position, const std::string& name, const std::string& path);
void Initialize(const sf::Vector2f& position, const std::string& name, const std::string& path);
const std::string GetName() const
{return name; }
bool IsColliding(int mouseX, int mouseY) const;
void Render(sf::RenderWindow& gameWindow);

private:
sf::Vector2f position;
std::string name;
std::string path;
sf::Sprite sprite;
};





So I did a little experimenting and discovered that if I comment out the entire MenuItem.cpp file, I no longer receive the aforementioned compiler errors (but instead a bunch of linker errors, likely because the MenuItem functions aren't implemented). Why in the world would commenting out the .cpp file cause the compiler to change its mind about whether or not the MenuItem class was declared?

Does anyone have any clue what's going on here? I can post the MenuItem.cpp file if I need to.

EDIT:
Cleand up some of the source code

Share this post


Link to post
Share on other sites
Advertisement
Do Game.h or Headers.h #include "MenuState.h"? If so, you've given yourself a circular #include issues (one of the common drawbacks of having something like Headers.h which, presumibly, does little more than #include a whole bunch of headers -- the other big drawback being bloated compile times due to unnecessary headers being #included in a translation unit and tons of files needing to be rebuilt every time you touch headers.h)

Share this post


Link to post
Share on other sites
What is in "Headers.h"? What do you need it for, when every .cpp apparently already has its corresponding .h (as it should be)?

"Global headers" of this sort have this habit of causing nothing but pain.

Share this post


Link to post
Share on other sites
hmm. I think MaulingMonkey's guess of circular dependency is spot on. Game.h does include MenuState.h. If I do a forward declaration of class MenuItem in the MenuState.h file, I just end up with a new compiler error, unfortunately:

1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(31): error C2079: 'MenuState::play' uses undefined class 'MenuItem'
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(32): error C2079: 'MenuState::options' uses undefined class 'MenuItem'
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(33): error C2079: 'MenuState::editor' uses undefined class 'MenuItem'
1>c:\users\nick\desktop\castle defense\castle defense\castle defense\menustate.h(34): error C2079: 'MenuState::quit' uses undefined class 'MenuItem'

This time the compiler's complaint is a tad more straightforward. It's complaining because I'm attempting to declare an object on the stack whose forward declaration is only in scope. How the heck can I fix this?

Also, what is the general recommendation when it comes to #include files? I suppose that I'll remove the "Headers.h" file from the program. For a given class, should I include every file that both that class's .h and .cpp files need inside the class's .h file and then only include the class's .h files inside its .cpp file, or should I only include a file inside another file if it is absolutely needed inside that file? In the former scenario, it is possible that a class's .h file would contain several other files it does not need simply because it's .cpp file requires them.

Share this post


Link to post
Share on other sites
This covers everything (it might seem basic, but all rules are covered).

The rule is: a header should include as little as possible, just enough to quiet the compiler. Each source file should include its header as the very first thing it does, doing this will guarantee that your header does not require any other files to be included to compile correctly.

In some cases, you can forward declare and wait until the source file to include the header. If you can do this, then do it.

In this case, your MenuItem.h need only include <string> and "sf" headers. It should not need to include "Game.h". If sf::RenderWindow lives in a separate header from sf::Vector2 and sf::Sprite, then it can be forward declared and its header's include statement moved to the MenuItem.cpp file.

Sometimes it is practical to make a list of external headers that are frequently included. This is generally safe as the dependency is only one way, plus you can pre-compile this header to speed up compile time.

Share this post


Link to post
Share on other sites
Quote:
Original post by zoner7
Also, what is the general recommendation when it comes to #include files? I suppose that I'll remove the "Headers.h" file from the program. For a given class, should I include every file that both that class's .h and .cpp files need inside the class's .h file and then only include the class's .h files inside its .cpp file, or should I only include a file inside another file if it is absolutely needed inside that file? In the former scenario, it is possible that a class's .h file would contain several other files it does not need simply because it's .cpp file requires them.
The later. Include only in a header file what is necessary to allow that header file to compile when #included in a cpp file that does nothing more than declare an instance of your class(es).
Where your header does not need the entire definition of a class, such as where it only ever declares a pointer to some type rather than an actual instance, just use a forward declaration instead. Don't put a using namespare std etc in them either, do that only in cpp files. Keep your header files as lean as possible!

Add to your cpp file only what is additionally needed to get that cpp file to compile.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!