C2146 and C4430 errors

Hello everyone,
Today I started coding when suddenly these scums of C2146 and C4430 got me in troubles. I tried to avoid them using my powerful Google skills but unfortunately they did not get away, and that's why I'm relying to you now to find where the errors are:
Here's the .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
26
27
28
29
30
31
32
33
34
35
#pragma once

#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include "Namespaces.h"

class LoadingObject : public sf::Drawable
{
public:
	LoadingObject();
	void OpenDoors();
	void CloseDoors();

	bool doorsAreClosed() const;
	bool doorsAreMoving() const;
	bool doorsStillOnScreen() const;
	~LoadingObject();

protected:
	virtual void draw(sf::RenderTarget& target, sf::RenderStates states = sf::RenderStates::Default) const
	{
		target.draw(*rectl, states);
		target.draw(*rectr, states);
	}
	bool doorMoving;
	bool thisExists;

	sf::RectangleShape *rectl;
	sf::RectangleShape *rectr;

	sf::Texture *rectlTex;
	sf::Texture *rectrTex;

	sf::Texture *freezeImage;
};


Q:Wow! what are these sf:: things?
A: It's SFML and everything is included in <SFML/Graphics.hpp>

Part of my .cpp:
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
26
27
28
29
30
31
32
33
34
35
#include "LoadingObject.h"

LoadingObject::LoadingObject()
{
	//things, no return
}

LoadingObject::~LoadingObject()
{
	//no return either

void LoadingObject::CloseDoors()
{
	//Still no return
}

bool LoadingObject::doorsAreClosed() const
{
	//returns a bool
}

void LoadingObject::OpenDoors()
{
	//returns nothing
}

bool LoadingObject::doorsAreMoving() const
{
	return doorMoving;
}

bool LoadingObject::doorsStillOnScreen() const
{
	return thisExists;
}


Most of the times these errors are generated when there is a bad return type.

And somewhere else in my code I have:
1
2
3
4
namespace lol
{
LoadingObject Loading;
}

And this is where the compileer tells me I have an error. (Of course I included the header file)

What is wrong in this code?
Thank you
And somewhere else in my code I have...

Where? That actually makes a difference.

Also, if you could post the content of the error messages instead of their IDs that'd be grand.

-Albatross
Thanks for your reply. First the somewhere else is in global space : I declared the 'lol' namespace in a file called "Namespaces.h" and we usually declare namespaces in global space.

C2146
http://msdn.microsoft.com/en-us/library/9xbcaa9t.aspx

C4430
http://msdn.microsoft.com/en-us/library/ms173696(v=vs.110).aspx


You're still not giving us the information that will help us. Please could you show us the complete error messages, including the line numbers.

And please show us the code that's generating these errors. If there's too much code to post, then try and create a minimal but complete set of code that still generates the error.
Namespaces.h
1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma once
#include "LoadingObject.h"
namespace uV //usefulVars
{
	//0->menu; 1-> game;2->shop;3->options;4->about;
	int unsigned short whatAreYouIn =0U;
	bool menuHasBeenDrawn = false;
	float deltaTime;
	sf::RenderWindow *mainwin = nullptr;
	sf::Event *mainEvent = nullptr;
	musicVolume musVol = HIGH;//This is an enum
	LoadingObject Loading;//The error is on this line
}


main.cpp
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <SFML/Graphics.hpp>
#include "Funcs.h"
#include "Namespaces.h"
#include "Optionsfunc.h"
#include <iostream>

int main()
{
	srand((unsigned)time(NULL));
	//Declare variables up
    sf::RenderWindow window(sf::VideoMode(1000, 600), "MotherBlaster - Best game EVER");
	uV::mainwin = &window;

	sf::Clock clock;
    while (window.isOpen())
    {
        sf::Event event;
		uV::mainEvent = &event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }
		//Main code
		uV::deltaTime = clock.restart().asSeconds();

		switch (uV::whatAreYouIn)
		{
		case 0:
			if(!uV::menuHasBeenDrawn)
			{
			if(!drawMenu())
				return EXIT_FAILURE;

			uV::menuHasBeenDrawn = true;
			}
			//std::cout << "Imma right b4 next statement\n";
			std::cout << "dam: " << uV::Loading.doorsAreMoving() << std::endl;
			if((sf::Keyboard::isKeyPressed(sf::Keyboard::Return) && !uV::Loading.doorsAreMoving()) || uV::Loading.doorsAreMoving())
			{
				//things
			}
			else if(!execMenu())
				return EXIT_FAILURE;
			break;

		case 1:
			if(!playGame())
				return EXIT_FAILURE;
			break;

		case 2:
			break;

		case 3://Options -->
	
			if(!Options::hasBeenDrawn)
			{
			if(!drawOptions())
				return EXIT_FAILURE;
			Options::hasBeenDrawn = true;
			}
			if (uV::Loading.doorsStillOnScreen())
			{
				uV::Loading.OpenDoors();
			}

			execOptions();
			break;

		default:
			break;
		}

        window.display();
    }

    return 0;
}


Here are more specific infos about the error

C2146: syntax error : missing ';' before identifier 'Loading'

C4430: missing type specifier - int assumed. Note: C++ does not support default-int

Both of the errors are where I first declare Loading ( in namespace.h)
Whoa boy.

First off, declaring global variables is considered bad form, and in case of your project you're only going to get errors when you try to link your files. Why? Because you're declaring your global variables in a header file. #include is a glorified copy-paste, unlike Java's import. When your linker tries to link the two files, it'll find duplicate variables in your source files, act all confused about which matters, throw a hissy fit, and then go back to sleeping.

You can declare global variables in a header file, but to do so you'll need to use the extern keyword, and those variables will need to actually exist in exactly one source file in your project.

Second, I see something strangely circular here, even with your #pragma.

LoadingObject.h:
#include "Namespaces.h"

Namespaces.h:
#include "LoadingObject.h"

...why exactly does LoadingObject.h need Namespaces.h to be included if all that's in Namespaces.h are global variables?

-Albatross

Last edited on
Here's the deal:
1
2
3
4
5
6
7
8
void LoadingObject::CloseDoors()
{
//bla bla
	rectl->move(1000.f * uV::deltaTime,0.f);
	rectr->move(-1000.f * uV::deltaTime, 0.f);
	doorMoving = true;
//more bla bla
}


I need uV::deltaTime here. So thanks to you I understood what was wrong ;)
What do you suggest now?
As a starting fix for issue #2, just include Namespaces.h only in places where its globals are used. :D

As for issue #1... weeell, that's a bit more complicated. Ideally, you wouldn't use global variables and would have a class/struct designed primarily to store that data that you'd pass around references/pointers to when you need to access it.

BUT I recognize that restructuring is something that could potentially take a long time depending on how far along your project is. So as a temporary fix only... do some research on the extern keyword. This link might help.
http://bobobobo.wordpress.com/2009/06/04/understanding-extern-variables-in-c/

-Albatross
closed account (3qX21hU5)
You could also use a forward declaration1 to be a temporary fix. As Albatross mentioned you should look into a refractoring of your code because the design isn't really the best. Global variables aren't nessisarily bad but in this case they are unneeded and will cause you many headaches in the future.

Instead of having a global pointer to everything I would just pass a object that holds all that information in as a a parameter. I usually create a context object which holds all the information I might need and pass that into other classes (Usually other game states) through their constructors. For example.

1
2
3
4
5
6
7
8
9
struct Context
{
    Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, Player& player);

    sf::RenderWindow*    window;
    TextureHolder*       textures;
    FontHolder*          fonts;
    Player*              player;
};


This will hold most of the main information that I might need to pass between my different states. It includes the window, my texture manager, font manager and the player controller. You might want to include different things but that is up to you. The point it it makes a object that you can easily pass everything you might need to another class through the ctor.

Here is my constructor from my Main Menu state which shows how it can be used. Most of it you won't be able to understand completely without seeing the different classes but it will give you a general idea.

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
MenuState::MenuState(StateStack& stack, Context context) :
        State(stack, context),
        GUIContainer()
{
        // Gets a texture from my texture holder by going through the context
        sf::Texture& texture = context.textures->get(Textures::MenuScreen);
        backgroundSprite.setTexture(texture);

        auto playButton = std::make_shared<GUI::Button>(*context.fonts, *context.textures);
        playButton->setPosition(100, 250);
        playButton->setText("Play");
        playButton->setCallback([this] ()
        {
                requestStackPop();
                requestStackPush(States::Game);
        });

        auto settingsButton = std::make_shared<GUI::Button>(*context.fonts, *context.textures);
        settingsButton->setPosition(100, 300);
        settingsButton->setText("Settings");
        settingsButton->setCallback([this] ()
        {
                requestStackPop();
                requestStackPush(States::Settings);
                
        });

        auto exitButton = std::make_shared<GUI::Button>(*context.fonts, *context.textures);
        exitButton->setPosition(100, 350);
        exitButton->setText("Exit");
        exitButton->setCallback([this] ()
        {
                requestStackPop();
        });

        GUIContainer.pack(playButton);
        GUIContainer.pack(settingsButton);
        GUIContainer.pack(exitButton);
}



1This should take care of the problem as a temporary fix.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma once

class LoadingObject;

namespace uV //usefulVars
{
	//0->menu; 1-> game;2->shop;3->options;4->about;
	int unsigned short whatAreYouIn =0U;
	bool menuHasBeenDrawn = false;
	float deltaTime;
	sf::RenderWindow *mainwin = nullptr;
	sf::Event *mainEvent = nullptr;
	musicVolume musVol = HIGH;//This is an enum
	LoadingObject Loading;//The error is on this line
}
Last edited on
Wow thanks for this useful piece of advice, I'm new to game programming so any kind of help is really important for me. What i'm actually doing is a kind of test, so of course I do not do everything the right way, I am still lraning. What I just did is creating a method like loaduV(floats, bools and other things)
But yeah you are right I should have used a struct.
Anyway thanks for your help
closed account (3qX21hU5)
No problem and don't worry about making some mistakes or bad designs when you are just starting. Game development can be a very challenging field of programming so everyone makes tons of mistakes when they are doing it (I know I have many many times).

What matters is that you are out there actually programming and trying new things. That is really the only way to learn in my opinion.

Anyways wish you the best of luck with your project and if you need anymore help feel free to ask.
Last edited on
Topic archived. No new replies allowed.