Conditional preprocessing puzzle - c++

I have a problem where I can't seem to get conditional #define preprocessors to work correctly. For example:
#define WIN32_BUILD
#ifdef WIN32_BUILD
#define PCH "stdafx.h"
#else
#define PCH "xyz.h"
#endif
#include PCH
If I use this form, the compiler tells me that it can't find 'stdafx.h'. OK, that seems odd, so if I change the code to....
#define WIN32_BUILD
#ifdef WIN32_BUILD
#define PCH "xyz.h"
#else
#define PCH "stdafx.h"
#endif
#include PCH
Then the file defined in PCH gets picked up and everything compiles fine. This seems odd to me, almost like the preprocessor is ignoring the #if directives and just using all the #defines that it encounters.
Obviously I am doing something wrong, and I was hoping that someone could help me understand this.

When a project has the precompiled header feature turned on the preprocessor ignores everything that comes before #include "stdafx.h"
So your #define statements are ignored.

TL:DR; #define defines the symbol, #ifdef tests if the symbol is defined not whether it has a value.
#define WIN32_BUILD
This defines a pre-processor token, WIN32_BUILD. The token has no value. Anywhere you use the token 'WIN32_BUILD' the pre-processor will substitute the empty string, i.e. nothing.
#ifdef WIN32_BUILD
This checks if the pre-processor token WIN32_BUILD is defined. It is, you just defined it.
#ifdef WIN32_BUILD
// true - this code is included.
#define PCH "stdafx.h"
This defines the pre-processor token, PCH, and assigns it the value "stdafx.h"
#else
#define PCH "xyz.h"
#endif
This code is ignored, because WIN32_BUILD was defined.
It looks as though you were expecting 'ifdef' to only evaluate to true if the expression was not defined /to/ something.
#define a
#define b SOMETHING
#ifdef a
// you are expecting this to be ignored
#endif
#ifdef b
// and expecting this not to be ignored
#endif
#ifdef and #if defined(...) do the same thing.
#define a
#define b SOMETHING
#if defined(a) && defined(b)
// this code will be evaluated, both tokens are defined.
#endif
This feature of pre-processor tokens is often used to support conditional functionality:
#if HAVE_CPP11_OVERRIDE_KEYWORD
#define OVERRIDE_FN override
#else
#define OVERRIDE_FN
#endif
struct A {
virtual void foo() {}
};
struct B : public A {
void foo() OVERRIDE_FN {}
};
In the above code, the override keyword is only added if the system supports it (determined outside of the code).
So a compiler with override sees
struct B : public A {
void foo() override {}
};
a compiler without it sees
struct B : public A {
void foo() {}
};
Note: The opposite of "ifdef" is "ifndef":
#define a
#define b SOMETHING
#undef c
//#define d // << we didn't define it.
int main() {
#ifdef a
#pramga message("a is defined")
#else
#pramga message("a is UNdefined")
#endif
#ifdef b
#pragma message("b is defined")
#else
#pramga message("b is UNdefined")
#endif
#ifdef c
#pramga message("c is defined")
#endif
#else
#pramga message("c is UNdefined")
#endif
#ifdef d
#pramga message("d is defined")
#endif
#else
#pramga message("d is UNdefined")
#endif
#ifndef d
#pragma message("d is not defined")
#endif
#ifndef a
#pragma message("a is not defined")
#endif
return 0;
}
You can assign a pre-processor token numeric values and test them with #if
#if _MSC_VER
#define WIN32_BUILD 1
#else
#define WIN32_BUILD 0
#endif
#if WIN32_BUILD
#include <Windows.h>
#endif
But, especially when doing cross-platform programming, people tend to use ifdef variants rather than numeric checks, because the value checks require you to explicitly ensure all of the tokens are defined with a value. It's a lot easier just to only define them when you need them.

Related

How to fight external include that always re-define it's stuff

For example assert.h:
...
#ifdef NDEBUG
#define assert(_Expression) ((void)0)
#else /* NDEBUG */
...
This area isn't surrendered by #ifdef, #define, #endif or having #pragma once.
I want to define my own assert function, so I #undef it and creates it, but then when a file includes anything after that includes assert.h it overrides my assert function I made before that include...
For example:
#include "my_assert.hpp"
#include <iostream.h>
My my_assert will lose effect and use assert.h's define.

Make own macros precede libraries macros in c++

I have something like this in header.h:
#ifdef SOME_MACRO
#define MACRO_A
//Some code 1
#else
#define MACRO_A
//Some code 2
#endif
In main.cpp:
#include "header.h"
#define SOME_MACRO
...
MACRO_A; //It should be Some code 1
Is there a way to make SOME_MACRO definition in main.cpp affect header.h?
Putting #define SOME_MACRO before the header doesn't make changes.
First, yes you have to put the definition of your selector before the include statement:
#define SOME_MACRO // <<<<<<<<<<<<<<<<<<<<<<<
#include "header.h"
Second, if I take your sample literally, you probably missed that all code in a macro definition needs to go in a single line:
#ifdef SOME_MACRO
// Note the escaped line endings below: \
#define MACRO_A \
//Some code 1
#else
#define MACRO_A \
//Some code 2
#endif

Cross-platform code label macro?

In MSVC & C#, #pragma region can be used to label a code section.
Similarly, in GCC/Clang, #pragma mark can accomplish the same thing.
Is it possible to define a single macro such as CODELABEL(label) which will work for both compilers?
Basically, I'd like to avoid having to do the following:
#ifdef _WIN32
#pragma region Variables
#else
#pragma mark Variables
#endif
bool MyBool;
int MyInt;
#ifdef _WIN32
#pragma region Methods
#else
#pragma mark Methods
#endif
void MyMethod();
void AnotherMethod();
... and instead, do something like this:
CODELABEL( Variables )
bool MyBool;
int MyInt;
CODELABEL( Functions )
void MyMethod();
void AnotherMethod();
Is something like this possible?
Yes, in C++11, you can use _Pragma, since using #pragma in a macro definition is not allowed:
#ifdef _WIN32
#define PRAGMA(x) __pragma(x) //it seems like _Pragma isn't supported in MSVC
#else
#define PRAGMA(x) _Pragma(#x)
#endif
#ifdef _WIN32
#define CODELABEL(label) PRAGMA(region label)
#else
#define CODELABEL(label) PRAGMA(mark label)
#endif
The dance with PRAGMA is to satisfy _Pragma requiring a string literal, where side-by-side concatenation of two string literals (e.g., "mark" "section label") doesn't work.
According to this topic, the following should work.
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
#ifdef _WIN32
#define LABEL region
#else
#define LABEL mark
#endif
and then
#pragma STR(LABEL) Variables
bool MyBool;
int MyInt;
#pragma STR(LABEL) Functions
void MyMethod();
void AnotherMethod();
As far as Windows and macOS are concerned, since Xcode 12 and Visual Studio 2019, you can easily use this syntax that works ok on both platforms:
#pragma region mark -
#pragma region mark Whathever Your Label
Xcode silently ignores the 'region' token while VS takes the 'mark' token as part of the label, which is a minor cosmetic issue, IMHO.

What is the difference between VERIFY and ATLVERIFY

What is the difference between the C++ macro VERIFY() and ATLVERIFY() ? And which one is better to use for COM objects?
There is some difference in how the errors are reported. ATLVERIFY is defined as
#ifndef ATLVERIFY
#ifdef _DEBUG
#define ATLVERIFY(expr) ATLASSERT(expr)
#else
#define ATLVERIFY(expr) (expr)
#endif // DEBUG
#endif // ATLVERIFY
And ATLASSERT is
#ifndef ATLASSERT
#define ATLASSERT(expr) _ASSERTE(expr)
#endif // ATLASSERT
So it ends up in _ASSERTE (see https://msdn.microsoft.com/en-us/library/ezb1wyez.aspx )
While VERIFY is
#ifdef _DEBUG
#define VERIFY(f) ASSERT(f)
#else // _DEBUG
#define VERIFY(f) ((void)(f))
#endif // !_DEBUG
So it ends up in ASSERT (see https://msdn.microsoft.com/en-us/library/aa297139(v=vs.60).aspx )

Confusing nesting of numerous #ifndef statements (with no values) in C++

Maybe I'm missing something, but could some please explain the "logic" behind the following code?
#ifndef _PTRDIFF_T
#ifndef _T_PTRDIFF_
#ifndef _T_PTRDIFF
#ifndef __PTRDIFF_T
#ifndef _PTRDIFF_T_
#ifndef _BSD_PTRDIFF_T_
#ifndef ___int_ptrdiff_t_h
#ifndef _GCC_PTRDIFF_T
#define _PTRDIFF_T
#define _T_PTRDIFF_
#define _T_PTRDIFF
#define __PTRDIFF_T
#define _PTRDIFF_T_
#define _BSD_PTRDIFF_T_
#define ___int_ptrdiff_t_h
#define _GCC_PTRDIFF_T
#ifndef __PTRDIFF_TYPE__
#define __PTRDIFF_TYPE__ long int
#endif
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#endif /* _GCC_PTRDIFF_T */
#endif /* ___int_ptrdiff_t_h */
#endif /* _BSD_PTRDIFF_T_ */
#endif /* _PTRDIFF_T_ */
#endif /* __PTRDIFF_T */
#endif /* _T_PTRDIFF */
#endif /* _T_PTRDIFF_ */
#endif /* _PTRDIFF_T */
Why is this preferred over a simple:
#ifndef xyz
#define xyz
#endif
???
I can see they are nested, but it is very confusing. ...and btw, just what are they defining, as there are no values after the identifiers???
The logic is to only define the macros if none of them is defiend. However, I would certainly refactor it into:
#if !defined(_PTRDIFF_T) && !defined(_T_PTRDIFF_) && //... well, you get the idea
#define _PTRDIFF_T
#define _T_PTRDIFF_
//...
#ifndef __PTRDIFF_TYPE__
#define __PTRDIFF_TYPE__ long int
#endif
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#endif
As to the second question: you can define a macro without a replacement text (it would just expand to nothing if used). Such macros are often used for conditional inclusion of code based on #ifdef or #ifndef.
They're checking that all these identifiers have been defined which would be in other already included headers. If they're all defined then we define a few new identifiers.
You don't need to give a value to the identifier, for example you wouldn't give a value to your #include guards.