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

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?

Related

Cannot control #if defined(condition) in VSCode source

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?

Scope of a C++ symbol

AFAIK, symbols are useful to prevent multiple parsing. If both a.h and b.h include c.h, a
#ifndef C_H
#define C_H
...
// c.h definition would go here
...
#endif
will prevent c.h from being "parsed" (I believe it's not the right word) more than once.
However, I have seen something like
#ifdef WIN32
...
in other people's code. That symbol must have been defined somewhere else because a search for
#define WIN32
in the whole project returns empty. My question is: where are these symbols actually defined? Does the OS keep something similar to a pool of symbols that different programs can use to query for OS or other processes properties?
There are two options where those which are not in the code itself can originate from:
The compiler suite itself sets it as a default when you start compiling your code.
You give the compiler (or preprocessor, to be exact) a list of those definitions when you compile the code (or your IDE project preferences do, when you are using an IDE. For example, in Visual Studio 2013 you will find those when you open Project > Properties > Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions).
In general, those definitions are not only used for the reason you describe (as include guards), but also to enable or disable code based on the platform you develop for - for example, you can have code branches only compiled for windows, or only if you are using a 64 bit compiler.
You might want to take a look at some predefined compiler macros
Microsoft
AFAIK this is part of the compiler you use.
The Microsoft C++ compiler internally defines some macros such as WIN32, that's why it's not defined in any particular header. So when you build a source file with VC++ the stuff in inside #ifdef WIN32 gets compiled, but not on say Linux gcc.
Also your nomenclature is a bit off -- these are called preprocessor macros, not symbols. The names of the variables, functions, etc in your code are symbols.
Each compiler has a list of defined macros. MSVC defines WIN32 when compilation target is 32-bit Windows.

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.

Where is DEBUG defined in the code?

I looked at a sample code to create a log system on my server... And I found this
#if DEBUG
printf("something here");
#endif
I know what it does. It prtins something only if DEBUG has been defiend. But where is DEBUG defined? I looked at the all the header files but I could't find DEBUG..
Also, Could you please provide me a good example or tutorial about designing logging system?
Thanks in advance..
Do not use the DEBUG macro it is not defined by C++ standard. C++ Standard defines NDEBUG (No DEBUG), which is used for the standard assert macro and your logging code would go hand in hand with it. DEBUG is compiler dependent. Therefore NDEBUG is ensured by standard to be properly set. Applying it to your example use:
#ifndef NDEBUG
printf("something here");
#endif
But my opinion is: you should not design a logging library around the NDEBUG/DEBUG pair. Logging lib should always be there, just to allow you trace the application's behavior without the need of code recompilation, which in turn involves new deployment of your code and possibility to postpone the bug prone behavior. The following DDJ article by Petru Marginean about design of logging libraries describes how to ensure that fact in a very efficient manner in C++:
Part 1: http://drdobbs.com/cpp/201804215
Part 2: http://drdobbs.com/cpp/221900468
Regarding the logging library take a look at the Boost Logging library at:
http://boost-log.sourceforge.net/libs/log/doc/html/index.html
I was downvoted because NDEBUG is said not to be set without explicit definition of it in the command line. I agree with that fact, but on the other hand here I understand this question so, that compilation in debug mode, should also produce logging output. This fact is going to be better enforced when bundling the behavior to NDEBUG presence.
Compilers, at least those I know of, have an option to define preprossessor macros from "the outside" of compiled files.
For example, to define DEBUG with a microsoft compiler, you'd go with something like
cl -DDEBUG file.cpp ...
Easy way to detect position of first definition, you add #define .
#include "someone.h"
#define DEBUG "dummy" // add this
#if DEBUG
printf("something here");
#endif
You'll get
foo.c:2:0: warning: "DEBUG" redefined
<command-line>:0:0: note: this is the location of the previous definition
Or
foo.c:30:0: warning: "DEBUG" redefined
someone.h.c:2:0: note: this is the location of the previous definition
Another answer, try to use ctags. run ctasg -R on the top of the project directory, run vim /path/to/your/code.c. move cursor to DEBUG, then type CTRL-].
This way, you may find several definitions. You can find all with :tselect on the DEBUG.
In Visual Studio, you can set Preprocessor Symbols in Project Properties. As for logging system, take a look at log4cpp