I'm working with a program, full of compiler directives, programmed in Visual Studio.
I've made some changes and now I'm stuck with an unresolved external compiler/linker error.
I believe this is caused by the compiler directives, which seem not to detect the implementation of that particular function, and in order to investigate this, I'd like to follow the #ifdef compiler directives throughout the compilation process.
I've already tried using the /P configuration, but I don't see any compiler directive in the Output window.
Does anybody know how to do this?
I think you're on the right track with the /P option, but the doc states that the output will go to files with a .i extension (so probably not to your Output window).
Further, you may be able to find some help on any linker errors by generating a map file; see /MAP (Generate Mapfile).
Related
So I have a CMake project which I open in Visual Studio 2019 with the "Open Folder" option. From here I can build and compile it without any errors (CMake is using the IAR Compiler (iccarm.exe) as specified in the toolchain file). So far so good.
The problem is that IntelliSense, despite finding all necessary header files, shows lots of errors mainly related to "undefined __INTxx_T_TYPE__".
As far as i know thouse double underscores indicate that it's a compiler internal data type, which is not defined in any header file, which would also explain why IntelliSense reports that it's not defined (even if the compiler knows the type). I guess to counter this problem, IntelliSense does support different modes like "windows-msvc-x86" or "linux-gcc-arm". But there is no option for IAR compiler.
So my question: How can I get IntelliSense running in this project ? Is there a way to add a custom IntelliSense mode for the IAR compiler ? Can i add header files only for IntelliSense in which the missing types are defined ? Is there a way to tell IntelliSense not to worry about those types / ignore the types ?
Ok just for the unlikely case someone has the same problem, here is my "solution" (sort of):
I created a header file with all the internal types used by IAR and called it "intellisenseHeader.h". You can find the internals here (https://www.gaio.co.jp/support/user/faq/winams/docs/sample_predef.pdf), but in my case i had to add some definitions by myself. The problem is now, that it won't compile anymore, because the IAR compiler, now finds 2 definitions (the internal definition and the one in the header file). So we need to fix this again:
I put the include inside a #ifdef USE_INTELLISENSE_HEADER.
I created two Visual Studio configurations. In the first one, CMake will set the preprocessor directive and the intellisenseHeader file will get included. In the other one i didn't set it.
So what's the effect of this ? If you are in the configuration, where the header is included, IntelliSense works but you can't compile. And if you are in the other one you can compile, but IntelliSense doesn't work anymore. So now i need to switch between the configurations, everytime i want to compile or write some code... Not the best solution but still better than nothing.
EDIT: Ok just realized you can use __INTELLISENSE__ as mentioned in # Richard Critten comment, and therefore don't need to use multiple configs.
My Visual Studio 2013 (on Windows 7) stops the C++ build when there are errors without attempting to compile all the files. It will report errors from multiple files, but seems to stop after compiling files in the same project folder if there are errors in those files. (I can't say for sure that that's what it's doing.) After I correct those errors and build again, it will continue on until it finds errors in another batch of files and then quit again. I can't seem to find any setting that controls this, and I'm pretty sure it's not supposed to be the default behavior.
I am well aware that a final build product cannot be produced when there are errors. The goal is not to avoid fixing errors. The goal is to be able to start a build, do something else for a while, come back, and have all errors in the entire project waiting in a list to get fixed at once.
The termination of the build process depends on the severity of the defect and the confusion within the compiler.
Some errors are either so severe that the compiler can't continue or there are so many repetitive issues that the compiler gives up. The GNU compilers will usually summarize and only issue one notification for repetitive errors or warnings.
Some errors will cause the compiler to get confused. The error interfere with how the language is parsed and so the compiler gives up. Many examples are the omission of semicolons, closing braces or closing comments.
Other factors may break the build such as missing files, old object files, confused symbol files (many times in Visual Studio).
With Visual Studio you need remove all errors in the project before you can compile. If you separate the non-compilable files from the project that will allow you to compile as long as you don't need them. If you do need them Then you MUST fix the errors. Compiler errors are there for a reason. Fix the errors or comment the bad code out.
Running cppcheck on my project gives me about 80% ouput about library files instead of my code.
Is there a way to tell cppcheck to only search library(-headers) for definitions and such but not actually perform checks?
Or at least to supress the output for those files?
Or, even better, save the gathered information somewhere for re-use, as the library code is not likely to change for the next run?
I am a Cppcheck dev. Not currently. But I do believe that we should not warn about library headers.
Feel free to write some comments here if you want:
http://sourceforge.net/apps/trac/cppcheck/ticket/3390
I know that you can provide a command line or add switches in your project properties but can you do that from source file? I need to set certain switches for certain source files without going into project properties and manually doing it everytime. So maybe you can do it with preprocessors from C++ source file?
There're some #pragma's that can, for example, alter code generation/optimization for a block of code, but I think that's pretty limited thing.
First: Compilation/linking do not execute your C++ code. So you can't write a C++ piece'o code and make decision (to change some project settings of THIS project) based on some C++ conditions (like if/else/...).
#pragma and #defines are pre-processor directives as you already know. Though compiler understands #pragmas, programming capability is limited and usually compiler specific.
A common use of these is to make the code platform independent.
To answer your original question "how do I modify the project properties progrmatically (not manuall)?": You can write "code" using #pragmas & #defines (even conditional ones) in your code to control various settings. Usually support is compiler-vendor specific, so your code will most probably not be portable (across compilers) unless you're careful.
On my GCC, I always found c++config.h a good example of various cpp directive. On my windows PC it's installed in X:\MinGW\lib\gcc\mingw32\4.5.2\include\c++\mingw32\bits\c++config.h
To find out supported cpp directives, RTM of your compiler.
The other option obviously is to write shell/perl/... script to make modifications to the project settings/Makefiles. I recommend that compared to getting yourself tangled in cpp directives. :)
Of course this option would change the settings before compilation and not during. But if that's not a prob for you, go with this rather than cpp directives.
As has been mentioned, #pragma statements are very vendor specific. For Visual Studio 2005, take a look here for the supported #pragma statements: Pragma Directives
I would also with thekashyap regarding writing a script to modify the project settings for each file for the following reasons:
In the event that you have to add or change a setting, there is a *single* place to modify.
Because there is only one place to look, future maintainers know where to find special settings for a given file. They won't be surprised by something set manually that is hidden deep within the project settings dialogs.
I have just come across a Visual C++ option that allows you to force file(s) to be included - this came about when I was looking at some code that was missing a #include "StdAfx.h" on each .cpp file, but was actually doing so via this option.
The option can be found on the Advanced C/C++ Configuration Properties page and equates to the /FI compiler option.
This option could prove really useful but before I rush off and start using it I thought I'd ask if there are any gotchas?
I would say the opposite to litb above if you're using precompiled headers. If you use "stdafx.h" as your precompiled header and have code like this:
#include "afile.h"
#include "stdafx.h"
then you'll be spending an age trying to figure out why "afile.h" isn't being included. When using precompiled headers, all the includes and #defines are ignored up to the "stdafx.h". So, if you force include the "stdafx.h" then the above will never happen and you'll get a project that uses the precompiled option efficiently.
As for litb's comment about finding macros, good IDE's usually have an option to jump to the definition of a symbol, whether it be a #define, function, class, etc.
I would discourage from /FI (MSDN says it's called /FI . Not sure whether i looked at the right page though), simply because people or yourself reading the files don't notice a header is magically included anyway.
You can be sure this will cause much debugging time for someone that wants to figure out where specific macros come from, even though there are no #include lines at the top of the file.
Force includes is also helpful for automatically generated source files. Our system uses a tool that generates many source files but they don't include our pre-compiled header file. With "force includes" compilation of these files is now faster.
Optionally, it would be possible to write a script to insert the #include line in those files after generation and before compilation. But why go to that trouble?
I'd side with litb: don't do the forced includes. Having the code be explicit makes it easier to know what's going on for a new user. It also makes it easier to know what's going on if you ever need to port the code to a new platform.
Note that if the code uses templates, Visual Studio usually can't track down the definitions correctly. Perhaps 2010 will be better, but even VS 2008 is problematic on this front.
I wouldn't use it that often but it has its uses. I have used it to add a header that suppressed some warnings to all cpp files so that I could turn on /W4 or /Wall for the project and not have to edit all of the cpp files to include the warning suppression header first. Once eveything was working I DID go back and edit all the cpp files but for a proof of concept /FI was useful.
Likewise you can use it to force a precompiled header into cpp files in some build configurations but not in all (in case you want to have a build configuration that DOESNT use precompiled headers and that makes sure that each cpp only includes exactly what it needs to). However using #pragma hdrstop is, IMHO, a better way to achieve this.
I've talked about all of this on my blog here: http://www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop.html in a little more detail.
Save this function for when something weird comes up - like if you want to include a header in a generated source file. Even then there are likely better ways.