How to make warnings persist in visual studio - c++

Suppose I have files a.cpp and b.cpp and I get warnings in a.cpp and an error in b.cpp. I fix the error in b.cpp and recompile -- since Visual Studio doesn't have to recompile a.cpp, it doesn't remind me of the warnings it found before.
I'd like to somehow have the warnings persist; however, I don't want it to treat warnings as errors (I'd like it to still compile/run even with warnings). Is this possible?

You could go into the project settings and set all warnings as errors in the C/C++ tab (category: General).

Essentially, you're out of luck. The C++ compilation will discard all of the errors and warnings. Because it only recompiles .CPP files that have a missing .OBJ file (i.e. the ones that had errors and failed last time), you'll only see the errors.
You have a few options. Off the top of my head:
Write a macro that responds to the build complete event. If it sees any warnings, it could delete the .OBJ file. The .CPP file would be compiled again next time. Unfortunately, this means that your program may not run without recompilation.
You could write a macro that works the other way: on build start, look to see if there are any warnings, and then delete the .OBJ file.
Write a VS addin that remembers warnings until the .CPP file is compiled again.

As Hernan already said, add a custom build step that makes a copy of the intermediate file that contains the build results (warnings). Not sure how to do naming for this, but you could create a bat file that gets called as a custom build step.
Why you would want to save warnings is beyond me. Treat them as errors, or ignore them or pragma/disable them.

Rebuild your project or recompile only the a.cpp file. Warnings are output by the compiler, so you won't get warnings for files not included in the current compilation.
You can save your current build output going to the Output pane and pressing Ctrl+S (defaults to output-build.txt if I don't remember bad.)
In your project settings I think build output messages can be saved on files. Check it and tell your results.
Cheers

Given that you don't want to recompile the files that cause the warning, one option you might have is to write a small utility that filters the output of the compiler for warnings and writes them to the .cpp file as a //TODO comment.
Then the IDE will place them in the todo list.
I'm not aware of anything that does this out of the box, but it probably wouldn't be too difficult to whip up.
If you don't want the utility mucking around with the actual source files (and I'm not sure I would), you might want to have it write the //TODO comments to a dummy 'todo.cpp' file and have that file in the project. Then they'll show up in the todo list and since the file is nothing but comments, it won't affect the build. Just make sure the utility is smart about not adding duplicates to the list. A macro could be written to take you from the todo.cpp line to the corresponding actual location of the warning.

I'd strongly recommend running with warnings as errors as much as possible, and certainly in all the code you're writing yourself. It is way eaiser to fix the warnings here and now, than wait until later and try to do them all in one pass.
There are several reasons why you want to run with warnings as errors:
The majority of warnings actually indicate that there is a problem with your code.
If you have a lot of warnings, you won't notice if a new one appears in the middle. I've seen this happen a lot.
If there is a warning which you think is bogus or you for some reason just can't fix it right away, you can switch it off. Use the /w option or suitable #pragma. Note that you can switch it of for only a particular file, or even in a particular place in your code. If you still want a notice when compiling, but a #pragma message there.
If there is code which is outside of your control, but you just have to compile it into your program, switch of warnings for that particular module or source file, or even run it without /WX. Chances are you aren't modifying the code anyway, so point 2 is probably not so relevant.
I really cannot see any valid reasons for not running with /WX (or -Werror).

Related

About updating C++ header files

This question is about something that after more than a year with C++ I can't solve or find any solution about it.
I got used to using separate files for headers and code in C, but I have a problem with it on C++: whenever I edit a header file and try to compile the code that uses it again, the compiler doesn't notice the change on the header.
What I do to solve this is "compiling" the header (.hpp) alone. Sometimes I just add it to the list of source files for g++ along with the rest of the code, but what happens then is that I have to execute the command twice (the first time it gives me errors, but not the second time). It also warns me that I'm using the "pragma once" option in a main file.
I know this is very wrong, so I've searched for a correct way to do this, without success. I have noticed that g++ generates ".gch" files but I don't really know what's their purpose, although they may be related.
I suspect that the problem is caused because of the code in the ".hpp". I know (I think) that the good way to do it is to define prototypes only inside the header and writing the body of the methods in a separate file, but sometimes (specially when using templates) this generates even more problems.
The .gch is a precompiled header and it is created if you explicitly compile a header file.
The compiler will then use that file instead of the actual header (the compiler does not care about modification timestamps).
Do rm *.gch and leave all headers out of the compilation command forever.
(And don't put template implementations in .cpp files.)

How to ignore warnings from 3rd party packages?

I'm using boost for a project I'm working on. Some of my files include one or more of the boost headers which in turn include other boost headers, which in one of them there is a variable which is set but not used. This prints an ugly warning to my screen which makes it hard to read the output especially when I have a real compilation error but I need to look carefully in the output to distinguish which text belongs to the set but not used warning and which is related to the real compilation error I want to solve.
I don't want to disable this warning to the entire project or even to some specific files in my project because I want to see this warning if I set a variable in my code but I don't use it. I want only the warning which happens in a specific line and specific file to be ignored.
Is there an option for gcc to suppress specific warnings in specific location in the code?
gcc offers diagnostic pragmas. See http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html.
Use these in your code before and after you #include those third party headers. Do not modify those the third party code to suit your compilation flags.

How can I get the compiler tell me what file #define a value?

My code is linking against several other libraries that are also developed at my company, one of these libraries is redefining several values from errno.h, I would like to be able to fix this, however I am having trouble finding the exact file that is redefining these values, I am want to know if there is a way to make the compiler tell me when a file has defined a particular value.
You can probably do it by adding -include errno.h to the command line that builds the library in question. Here's a quick example. I have a C program called "file.c":
#define ESRCH 8
That's it - then I compile with:
cc -c -include errno.h file.c
And presto, a compiler warning:
file.c:1:1: warning: "ESRCH" redefined
In file included from /usr/include/errno.h:23,
from <command-line>:0:
/usr/include/sys/errno.h:84:1: warning: this is the location of the previous definition
That will tell you where your bad definitions are.
Have you tried searching with grep?
If you don't want to search through all your headers for the particular #define, you could use
#undef YOUR_MANIFEST_CONSTANT
after each #include in your source module and then start removing them from the bottom up and see where your definitions come from.
Also, your compiler may tell you that a #define has been redefined. Turn all your warnings on.
With GCC I did something similar with:
g++ input.cc -dD -E > cpp.out
-dD tells cpp to print all defines where they were defined. And in the cpp output there are also markers for the include file names and the line numbers.
It is possible that some environments, I'm thinking IDE's here, have configuration options tied into the "project settings" rather than using a configuration header. If you work with a lot of other developers in a place where this behavior is NOT frowned on then you might also check your tool settings.
Most compilers will tell you where the problem is, you have to look and think about what the diagnostic notification is telling you.
Short of that, grep/findstr on *nix/Windows is your friend.
If that yields nothing then check for tool settings in your build system.
Some IDE's will jump to the correct location if you right click on the usage and select 'go to definition'.
Another option if you're really stuck is a command line option on the compiler. Most compilers have an option to output the assembler they generate when compiling C++ code.
You can view this assembler (which has comments letting you know the relative line number in the C++ source file). You don't have to understand the assembler but you can see what value was used and what files and definitions were included when the compiler ran. Check your compiler's documentation for the exact option to use

What is a .h.gch file?

I recently had a class project where I had to make a program with G++.
I used a makefile and for some reason it occasionally left a .h.gch file behind.
Sometimes, this didn't affect the compilation, but every so often it would result in the compiler issuing an error for an issue which had been fixed or which did not make sense.
I have two questions:
1) What is a .h.gch file and what is one used for? and
2) Why would it cause such problems when it wasn't cleaned up?
A .gch file is a precompiled header.
If a .gch is not found then the normal header files will be used.
However, if your project is set to generate pre-compiled headers it will make them if they don’t exist and use them in the next build.
Sometimes the *.h.gch will get corrupted or contain outdated information, so deleting that file and compiling it again should fix it.
If you want to know about a file, simply type on terminal
file filename
file a.h.gch gives:
GCC precompiled header (version 013) for C
Its a GCC precompiled header.
Wikipedia has a half decent explanation, http://en.wikipedia.org/wiki/Precompiled_header
Other answers are completely accurate with regard to what a gch file is. However, context (in this case, a beginner using g++) is everything. In this context, there are two rules:
Never, ever, ever put a .h file on a g++ compile line. Only .cpp files. If a .h file is ever compiled accidentally, remove any *.gch files
Never, ever, ever put a .cpp file in an #include statement.
If rule one is broken, at some point the problem described in the question will occur.
If rule two is broken, at some point the linker will complain about multiply-defined symbols.
a) They're precompiled headers:
http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html
b) They contain "cached" information from .h files and should be updated every time you change respective .h file. If it doesn't happen - you have wrong dependencies set in your project

How to get IntelliSense to reliably work in Visual Studio 2008

Does anyone know how to get IntelliSense to work reliably when working in C/C++ projects? It seems to work for about 1 in 10 files. Visual Studio 2005 seems to be a lot better than 2008.
Edit: Whilst not necessarily a solution, the work-around provided here:
How to get IntelliSense to reliably work in Visual Studio 2008
Is probably the best bet if I want a decent IntelliSense system.
Native C++ intellisense does not work reliably in any version of Visual Studio. I find there are two common problems:
1) Header file paths are not set-up correctly. When you find a type where intellisense is not working, use the IDE to click through each header file to find the one containing the type. (Right click on #include and select Open Document...). If this fails before you get to the file which declares the type then this is your problem. Make sure header file search paths are set-up correctly.
And,
2) The intellisense database is corrupt. This happens ALL The time. You need to close the solution, delete the .ncb file, and then reopen the solution. I posted the macro I use for this in answer to another question here.
The preprocessor can also confuse intellisense - so make sure any #defines during build are also available to intellisense. Other than that, I don't know what else can break it. I've not seen any particular issues with forward declarations.
I've also realized than Intellisense is sometime 'lost', on some big project. Why? No idea.
This is why we have bought Visual Assist (from Tomato software) and disabled Intellisense by deleting the dll feacp.dll in the Visual studio subdirectory (C:\Program Files\Microsoft Visual Studio 8\VC\vcpackages)
This is not a solution, just a workaround.
It looks like there's hope on the horizon for those of us unable to obtain Visual Assist:
Rebuilding Intellisense
Do you have any add-ins installed (or uninstalled)? I find that effects my intellisense.
Besides that just making sure your Tools->Options->Text Editor->All Languages "Auto List Members" and "Parameter Information" are checked off.
I don't use VS2008 for C++, only VB & C#, but I find that when intellisense stops working (true for VS2003/2005/2008) it's because something in the project/file is broken - usually a bad reference or code.
VB and C# have much better intellisense support due to the ability to reflect on the referenced assemblies to build the intellisense tree.
C++ has to walk the include files for function prototypes, and if the paths are not correct it will not find all the prototype headers.
My fix to itellisense was required after that awful refactor utility minced my code. The problem was a class header file that included an #include of itself. The recursive reference destroys itellisense. A symptom of this is if itellisense can see other classes but not the current one. Also:
Use #pragma once to eliminate duplicate header loads
If the project now takes a very much longer time to load, that itellisense trying to make sense of the conflict that is causing then lack of completion support.
Often it is only one class object that is affected, This shows you what files (usually headers) to look at.
#John Richardson / #Jonathan Holland
My includes are setup correctly, no problems there. I've also tried the NCB rebuild several times but it never fixes it 100%.
I have a feeling it may be to do with forward declarations of classes. e.g. to reduce the complexity of includes in header files we normally do something like:
class MyPredeclared;
class SomeOtherClass
{
private:
MyPredeclared* m_pPointer;
}
I wonder if that screws it up? Any other ideas? It definitely gets worse the larger your project gets.
I had a very annoying problem, intellisense was working only in some files, without any evident reason... it took me a couple of hours of digging through google, but I finally understood that the reason was indeed recursive reference!
I was using the:
#ifndef CLASS_H
#define CLASS_H
...
#endif
to avoid redefinition of symbols, and this sometimes breaks intellisense in big projects.
But it is enough to comment the ifndef-define-endif and put a:
#pragma once
at the beginning of the header files to still avoid redefinitions and have Intellisense working again =)=)
At least, this worked for me, hope it's useful...
Cheers
Francesco
I have recently studied Intellisense in VS2008, as I'm developing a rather large C++ numerical linear algebra library where templates and such are used extensively. Intellisense stopped working shortly into the project and I sort of gave up, but now it became really annoying without it so I set to investigate. This is what I found out:
Assuming there is a file(s), containing code that "breaks" Intellisense,
if header files that break Intellisense are in the project, but are not #included, it still works in the rest of the files
if they are included, but no type declared inside is used, it still works
if they are included and a type declared inside is used, it might still work a bit (no Intellisense for members, no Intellisense after occurrence of given type, but at least global names and argument info before)
if Intellisense is broken in one .cpp file, it can still work in the others where the problematic code is not included or used (but i imagine if it crashes bad, it will get disabled for the whole project, although that did not happen to me)
Intellisense seems to be updated after successful compilation (sometimes not before)
putting broken code inside any of #if 0, /* .. */ or // seems to put Intellisense at ease
From the C++ features I used, actually only a few break Intellisense:
comparison with '>' or '>=' in template parameter (e.g. static_assert<(size > 0)>)
not solved by using double parentheses (static_assert<((size > 0))> does not help)
solved by using '<' or '<=' instead (static_assert<0 < size> works)
solved by storing the value in enum and using that to specialize the template
explicit function template specialization disables argument info (e.g. function<type>(args))
probably unable to solve (maybe wrap in a macro), but I can live with it being broken
instantiation of template member type, such as Matrix::MakeMatrixType<3, 3>::Result r;
kind of hard to figure out exactly why this happens (likely because of use of Eigen)
workaround by moving such code in a separate .cpp where IS won't work (not always possible)
It would seem that some of those problems are due to some "simplified" parsing, which is less strong than a proper C++ parser. With the above information at hand, a "reliable" method of making Intellisense work in an existing code:
Set up an empty project (a console app), create Main.cpp with dummy void main() {} in it.
Include one of your broken header files, and math.h
Build (it must compile, in order for Intellisense to update reliably)
Test whether Intellisense is working by typing e.g. sin( and seeing if argument help pops up. Sometimes, this would work, but member help wouldn't - so try that as well.
Make an instance of something in the header file, build, see if that manages to kill IS.
Remove code from the culprit file and go to step 3
After finding and fixing problematic code, put back code removed in step 5, try again
After making a whole class work well, make an instance of the next class, and so on ...
I found it easy this way to pinpoint locations of code that made problems (I realize that this might be unfeasible for really large projects, in my case only a single file out of 97 made problems). Note that 'Build' here refers to compiling, the linking stage does not need to finish, so unresolved externals are ok, the IS should update regardless.
Another method of updating IS (other than building) is to save everything, close workspace, delete .ncb file and reopen it. Then wait for 'Updating Intellisense ... (N)' to disappear from the status bar (N counts towards zero, if it doesn't go all the way, it kind of shows progress where problems occurred). I found this rather tedious.
About this problem i've notice something interesting (on Visual Studio 2010):
to solve this problem i've changed #include sintax in my header files, before was (old project done with VS 2005 and reopened using VS 2010):
#include <myfile.h>
and i fix this with:
#include "myfile.h"
After intellisense start working correctly!
I hope this can help!
I had to reset the settings...
C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE>devenv.exe /ResetSettings
thread on this here
The problem is with the .vcproj files.
You will find if you switch to release mode from debug mode, build, then try intellisense it often works.
Close Visual Studio. If you search for the .vcproj files in your project, edit them and search for the first two instances of AdditionalIncludeDirectories. The value for this should look something like "..\,....\" rather than "../..".
Reopen your project, let the Intellisense finish building, then it should be fixed.