Cannot control #if defined(condition) in VSCode source - c++

Our embedded product will now produce two image from one set of source files. VSCode is used for editing but not compiling or debugging. However, intellisense and syntax checking is handy.
When I added
#if defined(ORIGINAL)
// code looked the same
#endif
but when I added
#if defined(ALTERNATE)
// code was dulled and intellisense was inactive
#endif
Is there a way to tell VSCode which definitions may be passed to the compiler so that I can check all of the code?

Related

Macro that is true only when the compiler starts a build [duplicate]

This question already has an answer here:
Hide a C++ code block from Intellisense
(1 answer)
Closed 3 years ago.
Is it possible to have a macro be set to true when building but otherwise is set to false? I realize there are macros to detect build configurations (e.g. debug/release) but I am looking for a macro that is set when the compiler starts building. It's okay if the macro is very specific to a particular compiler.
The use case is to help intellisense with some complex macros by simplifying them. The autocomplete does not work with the complex macros. However the simplified macros are very slow at runtime.
This one would probably work:
#define ONLY_TRUE_AT_COMPILE_TIME true
You can set a macro in your IDE and don't use it in the build process
#ifdef IDE_MACRO
#define SIMPLE_MACROS
#else
#define COMPLEX_MACROS
#endif
In Visual Studio Code you can set
"configurations": [
{
...
"defines":[
"IDE_MACRO"
]
}
]
in
.vscode/c_cpp_properties.json
defines A list of preprocessor definitions for the IntelliSense engine
to use while parsing files. Optionally, use = to set a value, for
example VERSION=1.
This only works if compileCommands is not set
compileCommands (optional) The full path to the compile_commands.json
file for the workspace. The include paths and defines discovered in
this file will be used instead of the values set for includePath and
defines settings. If the compile commands database does not contain an
entry for the translation unit that corresponds to the file you opened
in the editor, then a warning message will appear and the extension
will use the includePath and defines settings instead.
As you can read in the quote you can also use compile_commands.json to set macros and IntelliSense will consider them.
In Eclipse CDT it's in C/C++ Build -> Build Variables. There you can set a Variable IDE_MACRO. Now Eclipse CDT uses SIMPLE_MACROS instead of COMPLEX_MACROS. In the build process the macro IDE_MACRO is not defined and the compiler uses COMPLEX_MACROS.

VS2017 Project configuration preprocessor definitions not working in C++ project?

I have a preprocessor definition called PRIVATE_CODE set in my VS2017 project properties (VS2017 version 15.9.6 on Windows 8.1):
Right-click on solution
Configuration Properties
C/C++
Preprocessor
Preprocessor Definitons (field)
However, when I look at code in any file that looks for it to be defined, the code is not in use. I can tell because in my dark themed IDE, the code is in the IFDEF section is dimmed and the code in the ELSE section is normal brightness.
To be absolutely sure, I put a bad line of code in each section to see which section triggered a compiler error:
#ifdef PRIVATE_CODE
// This should trigger a compiler error.
adadfadsf;
#else
// Instead, I get a compiler error here, indicating that the compiler
// is not paying attention to the preprocessor definitions I set.
asdfadfff;
#endf
Has anybody else had this problem and knows why this is happening?

Is there something for MSVC compiler like "#pragma ignore this sourcefile"?

I'm currently working with some tutorials for opengl and don't want to set up the linker and include directories for each test source file. But from the tutorial each different example has its own main. I'also don't want to exclude all source files I'm currently working on.
I could put each source file into a
#ifndef EXAMPLE_X
/*sourcecode*/
#endif
But when I started typing this for each source file, I was aksing my self: is there some kind of pragma or flag for MSVC (I don't care about portabilty, as I'm just practicing the tutorial of a book) that says "just ignore this file stop compiling this file, and forget all you have parsed untill now in this file" so it is just as it is excluded, but I don't have to exclude and reinclude the files from my solution browser everytime I wan't to check something from older source. And instead just have to comment or uncomment the #pragma ignore flag stuff
No, there isn't.
Either remove the files you don't want from your project, or use macros to conditionally turn on/off their contents.

Macro undefined error while building a plugin

I am working on a plugin in which I need to #include a header file (let's say some_file.h) which in turn includes environ.h. Now, when I build my plugin, the build fails with some errors in the environ.h file and some other dependent files. Here's a code sample from environ.h where the error is occurring:
#ifndef PLATFORM
#ifdef WIN_ENV
#define PLATFORM "winpltfm.h"
#elif __OS2__
#define PLATFORM "os2pltfm.h"
#elif defined(unix) || defined(__unix)
#define PLATFORM "UnixPlatform.h"
#else
#error You must define the PLATFORM macro <------- Error-1
#endif
#endif
#include PLATFORM <------- Error-2
The Error-1 is: #error you must define the platform macro and Error-2 is easy to guess: Expected <filename> or "filename".
The strange thing is that some other plugin where some_file.h is included works fine i.e. builds successfully. This made me think that there must be some build settings which might be different.
Can anyone suggest what should be done in such a case to remove the errors from the environ.h header file?
Note: I am working on MAC OS X in Xcode.
I continued my comments to this answer so it's easier to explain...
First, instead of #elif __OS2__ it should be #elif defined(__OS2__) that's why during your test #define __OS2__ didn't work, but #define __OS2__ 1 did.
EDIT: From your comments you noted that environ.h is a standard file, but it seems odd how they are checking for the OS2 define. They are forcing it to be defined to a value rather than just being defined.
Second, as evident from your test, the compiler isn't defining __OS2__ for you, and there might be another header that is, but isn't currently included in the tranlation unit that picks up some_file.h. If you've confirmed that OS2 isn't defined by another header file in your project you can define a macro for the preprocessor by following these steps given by this SO answer:
The build setting you need to change is called 'Preprocessor Macros'
and it can be found in the 'Build Settings' tab of the Project
Settings pane (use the search box to find it). Select each target in
turn in the left-hand side of the Project Settings pane then modify
the Preprocessor Macros setting.
The setting is specified as a space-separated list of preprocessor
macros in the form 'foo' or 'foo=bar'.
Third, it seems your include path to os2pltfm.h is wrong or missing in your compiler settings.
You can include the file following the instructions given in this SO answer:
All you have to do is add the -I flag to your build setting under
"Other C Flags"
So in your target's build setting search for "Other C Flags" and add
-I/path-to-include/

Source files in Release, header files in Debug

We appear to have developed a strange situation in our application. An ASSERT is being triggered which should only run if _DEBUG is defined, but it is being evaluated when the application is compiled in Release mode.
ASSERT is defined in a header file, and is being triggered from another header file, which is included into a source file.
On further inspection, the source file is indeed running in Release mode (_DEBUG is not defined, and NDEBUG is). However, the header files have _DEBUG defined, and not NDEBUG.
According to conventional wisdom, #including a header file is equal to cutting-and-pasting the lines of code into the source file. This would make the above behaviour impossible.
We are compiling a large, mixed language (Intel FORTRAN and C++) application in VS2010. This problem also occurs on our build server, though, so it doesn't seem to be just a VS2010 'feature'.
We have checked:
All projects are building in Release.
The affected cpp files do not have any unusual properties being set.
There are no files in our solution manually defining or undefining _DEBUG or NDEBUG.
We have established the above behaviour by including clauses such as:
bool is_debug = false;
#ifdef _DEBUG
is_debug = true
#endif
and breaking on the point immediately afterwards.
We are running out of things to test - about the only things that I can even hypothesise are:
Some standard library or external include is redefining _DEGUG and NDEBUG, or
Something has overridden the #include macro (is this possible?).
EDIT ----------------------------------------------------------
Thanks in part to the #error trick (below), we've found the immediate problem: In several of the projects the NDEBUG and _DEBUG are no longer defined. All of these project were meant to have inherited something from the macro $(PreprocessorDefinitions) - but this is not defined anywhere.
This still leaves some awkward questions:
The source file that was causing the above behaviour does have NDEBUG defined in its project settings, and yet the header files they include don't (although VS2010 does grey-out the correct #ifdef blocks).
If the PreprocessorDefinitions macro is inherited by all C++ projects (which it appears to be), then why isn't it defined anywhere?
My usual approach to problems like this is, to look where the symbol is defined or an #ifdef is used and then put `#error Some text´ in it. This way already the compilation process will break, instead of having to wait and run it. Then you can see what really is defined.
You could also add such an #ifdef - #error combination right where the assert occurs, then you can be absolutely sure what the compiler thinks should be valid.
From http://msdn.microsoft.com/en-us/library/9sb57dw4(v=vs.71).aspx:
The assert routine is available in both the release and debug versions of the C run-time libraries. Two other assertion macros, _ASSERT and _ASSERTE, are also available, but they only evaluate the expressions passed to them when the _DEBUG flag has been defined.
In other words: either use _ASSERT(...) or #define NDEBUG, so you don't get asserts in Release builds.
OK, the problem turns out to be because NDEBUG and _DEBUG are missing from the Properties->C/C++->Preprocessor->Preprocessor Definitions on several projects. Whether they were always missing, or whether they had originally been included via the $(PreprocessorDefinitions) macro is unclear.
Thanks to #Lamza, #Devolus and #Werner Henze - all of their input was useful, and the eventual problem was depressingly mundane.