error: "invalid use of incomplete type"

Started by
8 comments, last by louie999 8 years, 3 months ago

Whenever I try to compile/build my game then I get these 2 errors:


||=== Build: Debug in TotalWar (compiler: GNU GCC Compiler) ===|
C:\|25|error: invalid use of incomplete type 'class Scene'|
C:\|2|error: forward declaration of 'class Scene'|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 2 second(s)) ===|

Here's my code:

Where I forward declared Scene class:


// App.hpp
#pragma once
class Scene;

class App
{
    public:
        enum States
        {
            STATE_INTRO,
            STATE_QUIT,
            STATE_MAIN_MENU,
            STATE_PLAYING
        };
        const int Width = 800;
        const int Height = 600;
        static States CurrentState;
        static Scene* CurrentScene;
        sf::RenderWindow Window;
        sf::Clock* Clock;
        float Dt;

        App(std::string &title);
        ~App();
        void SetScene(Scene& scene);
        void Clear();
        void Display();
        void Close();
        sf::RenderWindow* GetWindow();
        float GetDt();
        void ChangeState(States newState);
};

And in Scene.cpp(Where the error happens)


void Gui::Scene::DrawCurrentScene(float dt)
{
    App::CurrentScene->Draw(dt);
}

When I try to call App::CurrentScene->Draw then the error happens, help please.

Advertisement

#include "Scene.h"
You only forward-declared it. You never included the class definition.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Without knowing what namespace App is in, it looks to me like Scene is forward-declared in the same namespace as App, but defined in namespace Gui. If I understand what you're doing correctly, the compiler doesn't understand that you intended Scene to mean Gui::Scene.

Try forward-declaring Scene like this:


namespace Gui
{
    class Scene;
} 

#include "Scene.h"
You only forward-declared it. You never included the class definition.


L. Spiro

I did include it.

Edit: Woops, I didn't complete my message when I posted it(Probably 'cause of net problems)

Without knowing what namespace App is in, it looks to me like Scene is forward-declared in the same namespace as App, but defined in namespace Gui. If I understand what you're doing correctly, the compiler doesn't understand that you intended Scene to mean Gui::Scene.

Try forward-declaring Scene like this:


namespace Gui
{
    class Scene;
} 

Thanks, it compiles/builds fine now biggrin.png, though I got a new problem:


void Gui::Scene::Draw(float dt)
{
    for (auto &gui : GuiList)
    {
        app->GetWindow()->draw(gui->TextDisplay);
    }
}

That function in scene.cpp file causes my game to hang and have a white screen, I don't get why it happens, app->GetWindow()->draw causing the problem but I have no idea how to fix it sad.png

I did include it.


Then you have some kind of circular inclusion which prevents Scene from being a complete type where you need it. Types depending on each other can always get tricky if you don't pay attention. Inclusion guards or '#pragma once' are part of the puzzle but not the complete solution.

*From my last edit:


void Gui::Scene::Draw(float dt)
{
    for (auto &gui : GuiList)
    {
        app->GetWindow()->draw(gui->TextDisplay);
    }
}

That function in scene.cpp file causes my game to hang and have a white screen, I don't get why it happens, app->GetWindow()->draw causing the problem but I have no idea how to fix it sad.png

I ran the debugger of Code::Blocks, the app->GetWindow()->draw thing really was causing the problem.

I also got an "Program received signal SIGSEGV, Segmentation fault." from the debugger, how can I fix that?

GMZ9O8j.png

My guess would be the pointer returned by app->GetWindow() is uninitialized. An address of 0xbaadf00d sounds like an obvious pattern inserted by the debug runtime for that purpose.

Well here's my code:

app.hpp


#pragma once
namespace Gui
{
    class Scene;
}

class App
{
    public:
        enum States
        {
            STATE_INTRO,
            STATE_QUIT,
            STATE_MAIN_MENU,
            STATE_PLAYING
        };
        const int Width = 800;
        const int Height = 600;
        States CurrentState;
        Gui::Scene* CurrentScene;
        sf::RenderWindow Window;
        sf::Clock* Clock;
        float Dt;

        App(std::string &title);
        ~App();
        void SetScene(Gui::Scene& scene);
        void Clear();
        void Display();
        void Close();
        void DrawScene(float dt);
        sf::RenderWindow* GetWindow();
        float GetDt();
        void ChangeState(States newState);
        const App& operator=(App& app);
};

GetWindow() function:


sf::RenderWindow* App::GetWindow()
{
    return &Window;
}

Isn't the "sf::RenderWindow Window;" enough to make it initialized? Or Am I missing something?

Then I suggest you do the legwork everyone else does in these cases and inspect the value of variables at the crash site and/or step through the program with your debugger before the crash happens and check when things don't look as expected. Something there is uninitialized. Either you hope for some kind soul to find it for you or you learn to do it yourself. Since problems like this are a very common problem in our field, the second path is going to be more useful in the future.

Edit: You are also not helping yourself by posting the wrong code. Your stack trace clearly show App::DrawScene is calling a Gui::Scene::Draw which is most likely uninitialized pointer. When you reach the code you posted it's already too late, things are broken.

I fixed the problem :D, apparently the Gui::Scene* CurrentScene line(in app.hpp) was the one that is uninitialized, I forgot to call the function SetScene in my main function that's why CurrentScene was left uninitialized.

This topic is closed to new replies.

Advertisement