Anyone having this issue with VS 2017?

Hey guys!

I'm currently using Visual Studio 2017 and I've run into a bug of some sort. For some reason when I change some values in header files, they don't recompile. I have to manually create an error in the file for the compiler to pay attention to that file and then fix it to get the intended change.

Anyone has an idea why it does that and how to fix it?

Thanks in advance,

Regards,

Hugo.
What do you mean "don't recompile"? What does it tell you or what did you observe that led you to believe what you are saying?
Header files aren't compiled, only cpp files are.

Anyways: https://visualstudio.microsoft.com/vs/support/
Visual Studio contact us page

There's also a community page
https://developercommunity.visualstudio.com/spaces/8/index.html
I mean when I define private variabled in a class in a header file for instance, and I change its value, when I rebuild the solution, the variable hasn't changed
That's very awkward. And we're talking about header-files. Could this be a pre-processor error? Maybe.
If it is then you must definitely write to Visual Studio.

But you have to be really unlucky for such a thing.

Still though there are chances (even if very minute) that it may not be a fault with the IDE. It might just be really hard to spot.

Do you get this error with other projects as well? Can you try including a header-file that has a print statement in it and try to recreate the error with that?
Do you get this error with other projects as well?

Yes. I remember an older project of mine, which I user VS 2017 for and I already encountered that issue.

Can you try including a header-file that has a print statement in it and try to recreate the error with that?
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
#ifndef SLD_CONSOLE_H
#define SDL_CONSOLE_H

#include "Ltimer.h"
#include "ConsoleSettings.h"
#undef main;

using namespace std;

enum ConsoleState { blank, input };


class SDL_Console
{
	private:
		SDL_Window *window = NULL;
		SDL_Renderer *renderer = NULL;

		SDL_Texture *backgroundTexture = NULL;
		SDL_Texture *consoleOverlayTexture = NULL;
		SDL_Texture *consoleCursorTexture = NULL;
		SDL_Texture *consoleNoCursorTexture = NULL;

		SDL_Rect backGroundTextureRect = { 0, 0, GlobalConsoleSettings::WIN_W, GlobalConsoleSettings::WIN_H };
		SDL_Rect consoleOverlayTextureRect = { 0, 0, GlobalConsoleSettings::WIN_W, GlobalConsoleSettings::WIN_H };
		SDL_Rect consoleCursorTextureRect = { 0, 0, GlobalConsoleSettings::CURSOR_W, GlobalConsoleSettings::CURSOR_H };
		SDL_Rect consoleNoCursorTextureRect = { 0, 0, GlobalConsoleSettings::CURSOR_W, GlobalConsoleSettings::CURSOR_H };

		ConsoleState stateOfConsole;
		bool consoleIsRunning;
		bool cursorShown;

		TTF_Font *consoleFont = NULL;
		SDL_Colour consoleFontColour = /*{ 255,255,255,255 };*/{ 255, 252, 214, 255 };
		SDL_Rect fontPositionRect = { 28, 28, 0, 0 };
		SDL_Texture *fontTexture = NULL;

		string test = "test";   //TEST STRING HERE

	public:
		SDL_Console();
		~SDL_Console();

		void pause();
		bool isRunning();

		//initialise sdl images, main, and ttf
		bool initialiseSDL(const char* title, int xpos, int ypos, int width, int height);

		//runs command
		void runWithCappedFrames();

		void handleConsoleEvents();

		//makes the cursor blink
		void cursorBlink(int);

		//renders different elements to screen
		void render(int);

		//Renderer functions
		SDL_Texture* loadTexture(const char*);
		void drawTexture(SDL_Texture*, SDL_Rect, SDL_Rect);

		//output a string to console
		SDL_Texture* consoleOutput(string, SDL_Rect&);
		void renderConsoleOutput(SDL_Texture*, SDL_Rect);
};

#endif 

This is my header file (class definition using SDL_2).

I have included a test string in the private members of the class and the string is "test" when I first define it. In the class constructor I added cout << "\n\n " << test << "\n"; which successfully displays "test" on the console. However, after closing the program, I change the string to "test_000" and rebuild the solution. Compiler gives me this
1>------ Build started: Project: MemoDesktopProgram, Configuration: Debug x64 ------
1>Main.cpp
1>c:\/*link*/\sdl_console.h(7): warning C4067: unexpected tokens following preprocessor directive - expected a newline // -> points to #undef main line 7
1>Generating Code...
1>Skipping... (no relevant changes detected)
1>SDL_console.cpp
1>MemoDesktopProgram.vcxproj -> C:\/*link*/\MemoDesktopProgram\x64\Debug\MemoDesktopProgram.exe
1>Done building project "MemoDesktopProgram.vcxproj".
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========


Then I rerun the program, and what's displayed for the test string is still "test"

Constructor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "SDL_console.h"

SDL_Console::SDL_Console()
{
	if (consoleIsRunning = initialiseSDL("Program", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
		GlobalConsoleSettings::WIN_W, GlobalConsoleSettings::WIN_H))
	{
		stateOfConsole = blank;

		backgroundTexture = loadTexture("Console_images//background.png");
		consoleOverlayTexture = loadTexture("Console_images//console_overlay_dark.png");
		consoleCursorTexture = loadTexture("Console_images//console_cursor_light.png");
		consoleNoCursorTexture = loadTexture("Console_images//console_no_cursor_light.png");
	}
	else
		cout << "\nFailed to initialise console!\n";

	cursorShown = true;

	cout << "\n\n" << test << "\n";
}


To answer the question before it's asked, all the SDL headers are included in the ConsoleSettings.h file which follows:
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 CONSOLESETTINGS_H
#define CONSOLESETTINGS_H

#include <iostream>
#include <string>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>

using namespace std;

struct GlobalConsoleSettings
{
	static const int WIN_H = 420;
	static const int WIN_W = 896;
	static constexpr SDL_Rect SCREEN_SIZE = {0, 0, WIN_W, WIN_H};
	static constexpr SDL_Rect CONSOLE_POS_SIZE = { 0, 0, WIN_W, WIN_H };
	static const int SCREEN_FPS = 30;
	static const int SCREEN_TICK_PER_FRAME = 1000 / SCREEN_FPS;
	static const int CURSOR_H = 49;
	static const int CURSOR_W = 42;
};

#endif; 



EDIT: I just created a new project and tried the same thing, declare a class private variable in the class header, display it thanks to the constructor defined in the class' cpp file. Changing the value works as intended and changes after each rebuild of the program..

I've tried to do the same thing from another header file and the bug doesn't happen. I'm starting to think it's linked to the warning about #undef main from that particular file...
Last edited on
1. Your include guard SDL_CONSOLE_H is ill-formed. Check the spelling.
2. You should not have a semicolon at the end of an #undef directive. #undef main is the correct syntax.
3. You should not undefine the main macro in SDL projects. SDL provides its own main() function where it performs some internal initialization. Your main() is then rewritten to SDL_main() by the preprocessor and called from SDL's own main().
When looking for included files, the compiler or IDE will look in SEVERAL places, including current folder, installation folder, other nominated folders.

Are you very sure that you don't accidentally have multiple files of the same name in different folders, each potentially in the include search path? The compiler will just use the first one it finds and may ignore the version that you have been updating in some other folder.
1. Done. I have a terrible habit of writing "sld" instead of "sdl" when typing fast.
2. Corrected.
3.
You should not undefine the main macro in SDL projects. SDL provides its own main() function where it performs some internal initialization.

I did so because I was getting the following error:
1>SDL2main.lib(SDL_windows_main.obj) : error LNK2019: unresolved external symbol SDL_main referenced in function main_getcmdline

And didn't know how to fix it. After all the research I did on the matter I only found that solution.

Your main() is then rewritten to SDL_main() by the preprocessor and called from SDL's own main().

Does that mean that the SDL header has to be included in the cpp file where int main() is defined?

Also after doing the corrections you mentioned, the bug still persists, thanks for pointing them out though!


EDIT: I have now fixed the error I was getting when removing #undef main by replacing my main() by int main(int argc, char* args[]). Bug is still here.

SDL_console.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
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
#ifndef SDL_CONSOLE_H
#define SDL_CONSOLE_H

#include "Ltimer.h"
#include "ConsoleSettings.h"

using namespace std;

enum ConsoleState { blank, input };


class SDL_Console
{
	private:
		SDL_Window *window = NULL;
		SDL_Renderer *renderer = NULL;

		SDL_Texture *backgroundTexture = NULL;
		SDL_Texture *consoleOverlayTexture = NULL;
		SDL_Texture *consoleCursorTexture = NULL;
		SDL_Texture *consoleNoCursorTexture = NULL;

		SDL_Rect backGroundTextureRect = { 0, 0, GlobalConsoleSettings::WIN_W, GlobalConsoleSettings::WIN_H };
		SDL_Rect consoleOverlayTextureRect = { 0, 0, GlobalConsoleSettings::WIN_W, GlobalConsoleSettings::WIN_H };
		SDL_Rect consoleCursorTextureRect = { 0, 0, GlobalConsoleSettings::CURSOR_W, GlobalConsoleSettings::CURSOR_H };
		SDL_Rect consoleNoCursorTextureRect = { 0, 0, GlobalConsoleSettings::CURSOR_W, GlobalConsoleSettings::CURSOR_H };

		ConsoleState stateOfConsole;
		bool consoleIsRunning;
		bool cursorShown;

		TTF_Font *consoleFont = NULL;
		SDL_Colour consoleFontColour = /*{ 255,255,255,255 };*/{ 255, 252, 214, 255 };
		SDL_Rect fontPositionRect = { 28, 28, 0, 0 };
		SDL_Texture *fontTexture = NULL;

		string test = "kjhuktfjhgfjhgfjhgf24687est";

	public:
		SDL_Console();
		~SDL_Console();

		void pause();
		bool isRunning();

		//initialise sdl images, main, and ttf
		bool initialiseSDL(const char* title, int xpos, int ypos, int width, int height);

		//runs command
		void runWithCappedFrames();

		void handleConsoleEvents();

		//makes the cursor blink
		void cursorBlink(int);

		//renders different elements to screen
		void render(int);

		//Renderer functions
		SDL_Texture* loadTexture(const char*);
		void drawTexture(SDL_Texture*, SDL_Rect, SDL_Rect);

		//output a string to console
		SDL_Texture* consoleOutput(string, SDL_Rect&);
		void renderConsoleOutput(SDL_Texture*, SDL_Rect);
};

#endif 


Main.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include "SDL_console.h"

using namespace std;


int main(int argc, char* args[])
{
	SDL_Console console;

	console.runWithCappedFrames();

	console.pause();

	return 0;
}
Last edited on
Are you very sure that you don't accidentally have multiple files of the same name in different folders, each potentially in the include search path? The compiler will just use the first one it finds and may ignore the version that you have been updating in some other folder.
Yes I am. The file names "SDL_console.h" is the only one by this name on my computer. And on my older project which gave me this bug too, the file was also unique. I make sure to name files according to the project to avoid any unnecessary complication.

Thanks for the suggestion though!
New update: Changing the constants in my ConsoleSettings.h file does the exact same. *sigh*
closed account (E0p9LyTq)
Do you Build or Rebuild your full project when changing your header file(s)?

Do you ever just Compile the source/header file(s) after making changes?

Are you using Precompiled Headers?
Do you Build or Rebuild your full project when changing your header file(s)?
I don't I use the "local windows debugger" button which determines which files have changed and which have not, and skip those which haven't which is basically a shortcut to build + run the solution. If I build manually it does the same.

I could rebuild every time, but do I really want to wait 10-20 secs between every small adjustment when my code gets quite long?


Do you ever just Compile the source/header file(s) after making changes?
I don't. And I don't know how to do that actually.


Are you using Precompiled Headers?
I don't know what those are so I suppose I'm not, I'm making my own headers, I don't know if that can answer your question?
Last edited on
closed account (E0p9LyTq)
If you don't know what precompiled headers are chances are you are using them. When starting a project/solution VS defaults to using them unless you purposefully tell the IDE to not use them.

In your project's property pages, under C/C++ there is a Precompiled Headers page.

I could rebuild every time, but do I really want to wait 10-20 secs between every small adjustment when my code gets quite long?

That is where compiling just a single source/header file helps. Make a change in a header or source file, have the source file "highlighted". Under the Build menu is the Compile option. I believe it is defaulted to be CTRL+F7.

One advantage IMO when compiling individual source units is it can make doing a build go a lot quicker. The IDE already has most of the intermediate code precompiled to link together for a build to get the executable.

If you think 10-20 seconds is too long a time to wait get over it. With many real world applications a build/rebuild time frame of several HOURS is considered quick. Building Windows reportedly can take several DAYS.
In your project's property pages, under C/C++ there is a Precompiled Headers page.
I just checked, and I'm not using any.

I can't compile header files and compiling the source file for the header that's giving me a bug doesn't help. Thanks for the tip though, I'll use single file compiling more often.

If you think 10-20 seconds is too long a time to wait get over it. With many real world applications a build/rebuild time frame of several HOURS is considered quick. Building Windows reportedly can take several DAYS.
I know right. I was just saying that it can be quite annoying to wait just for a typo correction. Hence why I'd like to find the solution so this bug rather than use that as a workaround :)
closed account (E0p9LyTq)
Compiling individual source files comes with a caveat:

They may compile successfully, but when you build the executable there may still be errors when linking.

Big projects take time to build, period.

You might be better off going to a Unit Testing protocol. Creating slimmed down tests that stress test your classes individually instead of doing it as part of a monolithic "this is my entire application" approach.

What some call a Class Test Chassis.
You might be better off going to a Unit Testing protocol. Creating slimmed down tests that stress test your classes individually instead of doing it as part of a monolithic "this is my entire application" approach.

Well if by that you mean trying to figure out what classes give me the bug and which doesn't within my project, this is a quite fresh project and it only has 6 files. 2 headers for two classes, one of which gives me the bug (the one above) and one which doesn't, 1 header for globals, general settings which gives me the same bug, so I guess it's not a class issue.

The following diagram shows you how my files interact with one another:

"-->" means "includes"

Main.cpp --> SDL_console.h --> ConsoleSettings.h <-- Ltimer.h <-- Ltimer.cpp

SDL_console.cpp --> SDL_console.h

ConsoleSettings.h --> iostream, string, SDL.h, SDL_image.h, SDL_ttf.h


Headers that give me the issue is SDL_console.h and ConsoleSettings.h

I can provide the whole code if it may help, just say the word
older visual studio had this too.
you had a mix of several things going on...
precompiled headers, which never really worked right when I was using it, would often fail to pick up on changes. I always turned this off.
along with precompiled headers, it had incremental builds that was also buggy, and would sometimes fail to compile a header or cpp file that had been changed but it thought was already correctly compiled from an earlier compile, so it kept the old version.
On top of those two, windows itself had, and may still have, problems keeping last change timestamp on files correct, esp on code that was on a network drive.
Put it all together and rebuild all button was my friend, forcing it to compile everything.

I don't know which of these, if any, are fixed in 2017. All I have to offer is mashing rebuild all may help. A 'touch' batch file/script may help too.
Haha thanks jonnin I guess I'll take your advice then. Too bad it's recurring things and it's not being fixed though...

A 'touch' batch file/script may help too.
What do you mean by that?
you can build a little tool (depends on OS what is needed) to update the 'changed' info on the file which marks it to be recompiled. 'touch' is a unix command line tool to do just that. There are ports of touch to windows, or you can use any of a variety of console commands to make it work.

I am not 100% sure the problem is VS so much as windows. Windows just seems to fail at keeping track of last update flags and such. But that is just a guess.
Topic archived. No new replies allowed.