C++ - errors after changing .h file fixed only by recompilation - c++

I have a header file called gui.h where I keep all my gui stuff. Because of this I often change its contents. The problem is: every time I do this I get a runtime error usually related to memory. However, when I recompile all the project, everything works properly. The error occurs always after changing the .h file contents and it's always fixed by recompilation. Why is this happening? Is there any way I can fix it or I'll have to recompile entire project after every gui change?
EDIT:
I'm using Visual Studio IDE, normal project, not CMake
The files
gui.h
globals.h
Game.cpp
gui.cpp
Includes
gui.cpp has #include "gui.h"
globals.h has #include "gui.h"
Game.cpp has #include "globals.h"
The story
I make a change in gui.h
I hit F5
I see globals.h getting recompiled
I see gui.cpp getting recompiled
I see "Generating code" message in Build log
The project runs
I immediately get a runtime error related to memory (access violation)
The solution:
Recompile all the files that require gui.h to work manually (in this case Game.cpp)
The problem:
Why isn't Game.cpp recompiled automatically?

You haven't specified what tool you use to build your program. What is probably happening is that the tool you're using doesn't realize that a change to that particular h file requires anyone including it (directly or indirectly) needs to be recompiled.
For instance, if you're using "make", your Makefile may have a line that looks like this:
foo.o: foo.cpp foo.h
But it really would need to be:
foo.o: foo.cpp foo.h gui.h
In other words -- foo.o requires not only the corresponding .cpp and .h file, but also this huge gui.h file.
Any .cpp that directly or indirection includes gui.h probably needs recompiling when gui.h changes. That is:
#include "gui.h"
-or-
#include "foo.h"
and foo.h has an include of gui.h.

Since the content of the header file is pasted into the source files that include it by the compiler preprocessor, whenever you change the header, the program will remain the same, since it has been compiled from a source file that contained the content of the old header file.

I suggest that you could try to set incremental compilation.
Project->Properties->Configuration Properties->C/C++-Code Generation->Enable Minimal Regbuild: Yes(/Gm)
Project->Properties->Configuration Properties->C/C++->General->Debugging Information Format: Program Database (/Zi)
Project->Properties->Configuration Properties->Linker->General->Enable incremental linking: select "Yes"
Tools->Options->Projects and Solutions->Build and Run->On Run, when projects are out of date: select "Prompt to generate"
Tools->Options->Projects and Solutions->Build and Run->Check Only build startup projects and dependencies on Run
Tools->Options->Projects and Solutions->Build and Run->MSBuild project build output verbosity: select "Minimal"

Related

VS Code editor does not recognise variable defined in other files in workspace

The "main.cpp" can be compiled and run successfully, but the VS Code editor shows lots of annoying squiggles.
In the workspace, I include files: main.cpp, a.h, b.cpp.
In "main.cpp", I have included all library and
#include "a.h"
#include "b.cpp"
In "a.h", I define a variable 'xyz'. However, when I edit "b.cpp", the VS Code editor keeps showing squiggle under the variable 'xyz' and rising up problems "use of undeclared identifier 'xyz'".
How can I configure VS Code to avoid the annoying squiggles in editor?
Update:
As suggested in the answer below, including "b.cpp" is not a good way to organise multiple files cpp project.
A step-by-step tutorial on structuring larger project: http://staffwww.fullcoll.edu/aclifton/cs123/lecture-projects-and-files.html.
In brief, the "b.cpp" should include all libraries needed itself, not depending on the libraries defined in "main.cpp". Then create a "b.h" including function names defined in "b.cpp". Finally, include the "b.h" in "main.cpp".
I believe in order to have multiple files in VSCode you have to edit you tasks.json to compile not only your active file, but all the other files along with it.
My Tasks.json's "-g" looks like this:
"-g" //remember not to have multiple -g's
"${fileDirname}/**.cpp",
The /** means to also compile every other cpp in any other directory in that and so on.
You cannot include a .cpp file in C++. You must compile it along with your other CPP files.

Visual Studio 2017 keeps recompiling stdafx.h needlessly?

I have a Visual Studio 2017 C++ project which uses precompiled headers (stdafx.h).
My (simplified) file structure is as follows:
header1.hpp
header2.hpp
stdafx.h -> includes header1.hpp
code1.cpp -> includes stdafx.h
code2.cpp -> includes stdafx.h and header2.hpp
To avoid any ambiguity, by saying includes header1.hpp, I mean there is a line #include <header1.hpp> in the file.
After I modify stdafx.h, all three files stdafx.h, code1.cpp and code2.cpp are recompiled (as expected).
After I modify code1.cpp, only code1.cpp is recompiled (as expected).
After I modify header2.cpp, all three files stdafx.h, code1.cpp and code2.cpp are recompiled (not expected!).
I would have expected item 3 to compile only code2.cpp, and not everything else.
A possible reason for this behavior would be that the build manager can't inspect and follow #include directives, so it simply recompiles everything if any header file is modified.
Since my project is quite large, recompiling all the files like code1.cpp takes up a significant amount of time. I purposely did not include header2.hpp from stdafx.h because I know I would modify header2.hpp often and only code2.cpp needs to use it. (header2.hpp is a template library that has functions only code2.cpp needs.)
Is this behavior expected, and what can I do to get Visual Studio to recognize that the other files need not be recompiled?
Turns out I had disabled precompiled headers a year ago (but left stdafx.h and stdafx.cpp in the project), and when I wanted to use them again I forgot to turn on the /Yc and Yu options.
No errors were given, and Visual Studio had been compiling stdafx.cpp like a regular .cpp file.
Also, I had the wrong idea of how precompiled headers worked. I thought stdafx.h gets compiled by itself (then dumped into those .cpp files that #include "stdafx.h" via some intermediate representation), but actually the file that gets compiled is stdafx.cpp (and while compiling produces the .pch file). (As per this question.)
After turning on the precompiled header options, when I modify header2.cpp, only code2.cpp gets recompiled, as I would like.
Also, compilation times are now significantly faster.

unit test - recompile only around "int main()" to reduce compilation time

A project in my Visual Studio solution can be divided into :-
Library.h, Library.cpp
User.h, User.cpp (#include Library.h)
Main.h, Main.cpp (#include User.h) has "int main()"
(The real project is far bigger than this.)
Whenever I edit any Library.h file and press F5, it will recompile the whole project. It makes sense.
Now I want to code/debug Library and test it alone, and I don't want to recompile everything because it costs more time.
Therefore :-
I created Main2.cpp that #include only Library.h, and have no code involving User at all.
I commented out the whole main.cpp.
Here is my main2.cpp :-
#include "Library.h"
int main(){ .... some code about library ....}
When I press F5, it compiled all .cpp and run fine. That still makes sense.
Problem
If I edited Library.h, and press F5 again, it will recompile :-
library.cpp
User.cpp <--- no!
main.cpp <--- no!
main2.cpp
Question
How to make Visual Studio recompile only necessary files to save compilation time?
(compile only library.cpp and main2.cpp in this case)
I guess the need to recompile a lot of files is that there may be some static function inside User that do something about library.
What if I know for sure that there are not?
Even if there is something, I want to (risk) ignore it.
Separate your solution into 3 projects:
Library
LibraryTests
Main
When you don't want to re-compile 'Main', just right-click it and unload the project.
You should probably look to break up Library.h into smaller pieces, so that the dependencies are more self-contained.
I'd recommend instead of suffering headache with visual studio to download the MinGW c++ compiler for Windows and just compile a smaller unit-test instance of the files which you need as a sort of different project all together in with the console.

CodeBlocks files not recognized in project

I've been using code blocks for a long time, but never really made my programs into actual code blocks projects. I tried to do it today, and I kept getting errors due to code blocks not recognizing my files. Here is what I have : ---->
CodeBlocks Include Error
When I try to buiild my project I get that cout,cin and my class objects are not defined in my menu.cpp file. So I can only guess code blocks is not properly handling the files.
I would love if someone could help me out as to why this is happening.
Thanks a ton in advance :)
When I try to buiild my project I get that cout,cin and my class objects are not defined in my menu.cpp file.
That's because they're not. You #included neither iostream nor class.h in menu.cpp, so you can't access the declarations therein.
Note that Code Blocks (just like any properly set up build tools) will compile each cpp file separately. This means that not only will it compile menu.cpp as part of the compilation of main.cpp (because you include it), it will also compile it on its own. In the latter case the includes from main.cpp will not be available, so menu.cpp needs its own includes.
This also means that once it does compile (i.e. once you added the includes), you'll get a linker error because the definitions from menu.cpp are now defined twice (once in main.o -- because you included menu.cpp in main.cpp -- and once in menu.o). That's the reason why you should never include cpp files into each other.
PS: This is unrelated to your problem, but it's considered bad practice to use using namespace in a header file. You should put that in your cpp files instead (if you want to use it at all). You should also put the #include <iostream> in those files where you actually need it, rather than the header file.

Why does Visual Studio error when linking having files included?

I don't really understand the why behind this, but I think I've figured out the what.
My brother is working on a homework project and they're using Visual Studio. He was having issues getting his project to compile. The project in question consisted of:
main.cpp
classes.h
class_functions.cpp
general_functions.cpp
They had the following import structure:
main.cpp
#include "classes.h"
#include "class_functions.cpp"
#include "general_functions.cpp"
class_functions.cpp
#include "classes.h"
general_functions.cpp
#include "classes.h"
He kept getting link errors when trying to compile, even though g++ would compile it just fine. So I tried via Visual Studio command prompt and cl. This compiled just fine, so I tried msbuild which (obviously?) failed. I went into the vxproj file, because hey, what is it telling cl that I'm not?
In the proj file it was including classes.h, general_functions.cpp and class_functions.cpp, as well as main.cpp. When I removed general and class functions, msbuild ran just fine. Put either of them back and boom. classes.h contains
#ifndef myclasses
#define myclasses
/* Code here */
#endif
And the other .cpp files contain similar directives.
I finally figured out how to eliminate the problem - eliminate
#include "general_functions.cpp"
#include "class_functions.cpp"
from the code base, and now Visual Studio compiles this just fine.
The question is why? What is the justification or possible benefits from doing this?
the difference between .cpp and .h files is that the .h files are usually included with the #include directive while .cpp files are included in the linking process.
The #include instruction will insert a copy of the included file in the code you are compiling, so by including the .cpp files you will compile a single source file that contains all your .cpp files. It's very bad practice but still could work.
But if you are then adding the .cpp files also in the linking step then you are adding those files a second time creating probably duplicate definitions of your functions, e.g. linker error. I think that's probably the main error (without the linker error codes I'm just guessing).