C/C++ #define Macro inside macro? - c++

I would like something like:
#define C_OR_CPP(C__, CPP__) #ifdef __cplusplus\
CPP__\
#else\
C__\
#endif
Is it possible?
Maybe some dirty hack with #include ?
Reason:
I make a header where a struct uses a member variable of type vector<stuff>*, but in C i want it to simply be void*, you know.
TIA

What's the problem with
#ifdef __cplusplus
#define C_OR_CPP(C, CPP) CPP
#else
#define C_OR_CPP(C, CPP) C
#endif
(Leaving names with double underscore to the implementation per phresnel remark)

My English is poor, and I'm sorry for language mistakes and typos if any.
If #ifdef must not wrap the macro invocation, there is a solution not so graceful.
g++ only:
You may try this in selective occasions. But if there are commas in a or b, workarounds are still needed.
It's simply based on the fact that __cplusplus is defined to "1" when in a C++ environment and remains itself while not.
#define SELECT1(a, b) a
#define SELECT__cplusplus(a, b) b
#define xcat(a,b) a##b
#define concat(...) xcat(__VA_ARGS__)
#define C_OR_CPP(C, CPP) concat(SELECT, __cplusplus)(C, CPP)
C_OR_CPP(1, 2)
Other Environments
Check the __cplusplus macro, a compiler that comforming to standard C++ should generate
#define __cplusplus value
and value should >= 199711L

Not in C++. But you can
#ifdef __cplusplus
# define CPP
#else
# define C
#endif
I assume this is just a pathological example by you. Note also that double underscore is reserved to library implementors (see 17.6.4.3.2 Global names).
vector, but in C i want it to simply be void, you know.
So, what speaks against a solution like
struct Foo {
#ifdef __cplusplus
...
#else
...
#endif
};
or what speaks against providing different APIs for different programming languages?

AProgrammer already given you the right answer, but the answer to the "is it possible" part of the question is no. Macro expansion doesn't occur until after all preprocessor directives have been handled, so any macro that expands into a #define or #ifdef will be passed to the compiler as regular source text, which will cause the compiler to yak.

Related

undefine and redefine the __cplusplus macro

I want to undefine and redefine the __cplusplus macro am getting however compilation error:__cplusplus was not declared in this scope
#define TEMP_VERSION __cplusplus // temporary macro to hold the __cplusplus containt
#undef __cplusplus
#define __cplusplus TEMP_VERSION // redefine __cplusplus
#define AA 111
#undef AA
#define AA 111
int main()
{
cout << "__cplusplus = "<<__cplusplus<<endl; // It doesn't work
cout << "AA = "<<AA<<endl; // It works
return 0;
}
Question 1: Why it is not working with the __cplusplus but works with AA
I know that this is really ugly but the reason why am undefining the macro is that I am using a third party Software where they are missusing the #ifdef __cplusplus, I mean the content of the #ifdef __cplusplus ... #endif is wrong. So instead of changing their software I choosed to do the following
#define TEMP_VERSION __cplusplus
#undef __cplusplus
#include <third_party_sw.h>
#define __cplusplus TEMP_VERSION
Question 2: What do you think is it a good approach ?
From the C++ standard ([cpp.predefined, 3-4]):
The values of the predefined macros (except for __FILE__ and __LINE__)
remain constant throughout the translation unit. If any of the
pre-defined macro names in this subclause, or the identifier defined,
is the subject of a #define or a #undef preprocessing directive, the
behavior is undefined.
In other words, the __cplusplus macro isn't just something that the compiler starts out by defining before handing control over to you; it is an immutable constant, which cannot be changed and is an error to attempt to change.
As for whether it would be a good approach if it were possible: Depends on the context, but probably not. These sorts of "fool the header" hacks (#define private public, anyone?) are seldom effective and never safe.
EDIT: Oh, also incidentally, even if you did have a macro it was legal to save/restore, that wouldn't be the right way to do it. See Can I redefine a C++ macro then define it back?.
Question 1: Why it is not working with the __cplusplus but works with AA
Because __cplusplus is a pre-defined macro, and behaviour of (un-)defining it is undefined:
stadard draft [cpp.predefined]
If any of the pre-defined macro names in this subclause, or the identifier defined, is the subject of a #define or a #undef preprocessing directive, the behavior is undefined. ...
AA is not a pre-defined macro, nor is the indentifier reserved. It is OK to (re-)define it.
Question 2: What do you think is it a good approach ?
(Re-)defining reserved identifiers is never a good approach. Even redefining user defined macros is a dubious proposition.
Ideal approach might be to fix the third party software, if possible. Alternatively, you could write a custom header for the software which doesn't have the problem.
It's because __cplusplus is pre-defined by the compiler.
Technically, it's the pre-processor that defines them, but depending on which compiler invokes the pre-processor, the output may differ. Try running this:
$ g++ -dM -E - </dev/null
The output is all the pre-processor defines that (in this case) the pre-processor run by this command produces.
Mind you __cplusplus does not appear there. It's built-in for every C++ compilation unit.
(The same works when substituting clang++ for g++.)

What does #define do if you only have an identifer

typically #define would be used to define a constant or a macro. However it is valid code to use #define in the following way.
#define MAX // does this do anything?
#define MAX 10 // I know how to treat this.
So, if I #define MAX 10, I know my pre-processor replaces all instances of MAX with 10. If someone uses #define MAX by itself however with no following replacement value, it's valid. Does this actually DO anything?
My reason for asking is that I am writing a compiler for c in c++ and handling preprocessor directives is required but I haven't been able to find out if there is any functionality I need to have when this occurs or if I just ignore this once my preprocess is done.
My first instinct is that this will create a symbol in my symbol table with no value named MAX, but it is equally possible it will do nothing.
As an add in question which is kind of bad form I know, but I'm really curious. Are there situations in real code where something like this would be used?
Thanks,
Binx
A typical example are header guards:
#ifndef MYHEADER
#define MYHEADER
...
#endif
You can test if something is defined with #ifdef / ifndef.
It creates a symbol with a blank definition, which can later be used in other preprocessor operations. There are a few things it can be used for:
1) Branching.
Consider the following:
#define ARBITRARY_SYMBOL
// ...
#ifdef ARBITRARY_SYMBOL
someCode();
#else /* ARBITRARY_SYMBOL */
someOtherCode();
#endif /* ARBITRARY_SYMBOL */
The existence of a symbol can be used to branch, selectively choosing the proper code for the situation. A good use of this is handling platform-specific equivalent code:
#if defined(_WIN32) || defined(_WIN64)
windowsCode();
#elif defined(__unix__)
unixCode();
#endif /* platform branching */
This can also be used to dummy code out, based on the situation. For example, if you want to have a function that only exists while debugging, you might have something like this:
#ifdef DEBUG
return_type function(parameter_list) {
function_body;
}
#endif /* DEBUG */
1A) Header guards.
Building on the above, header guards are a means of dummying out an entire header if it's already included in a project that spans multiple source files.
#ifndef HEADER_GUARD
#define HEADER_GUARD
// Header...
#endif /* HEADER_GUARD */
2) Dummying out a symbol.
You can also use defines with blank definitions to dummy out a symbol, when combined with branching. Consider the following:
#ifdef _WIN32
#define STDCALL __stdcall
#define CDECL __cdecl
// etc.
#elif defined(__unix__)
#define STDCALL
#define CDECL
#endif /* platform-specific */
// ...
void CDECL cdeclFunc(int, int, char, const std::string&, bool);
// Compiles as void __cdecl cdeclFunc(/* args */) on Windows.
// Compiles as void cdeclFunc(/* args */) on *nix.
Doing something like this allows you to write platform-independent code, but with the ability to specify the calling convention on Windows platforms. [Note that the header windef.h does this, defining CDECL, PASCAL, and WINAPI as blank symbols on platforms that don't support them.] This can also be used in other situations, whenever you need a preprocessor symbol to only expand to something else under certain conditions.
3) Documentation.
Blank macros can also be used to document code, since the preprocessor can strip them out. Microsoft is fond of this approach, using it in windef.h for the IN and OUT symbols often seen in Windows function prototypes.
There are likely other uses as well, but those are the only ones I can think of off the top of my head.
It doesn't "do" anything in the sense that it will not add anything to a line of code
#define MAX
int x = 1 + 2; MAX // here MAX does nothing
but what an empty define does is allow you to conditionally do certain things like
#ifdef DEBUG
// do thing
#endif
Similarly header guards use the existance of a macro to indicate if a file has already been included in a translation unit or not.
The C Preprocessor (CPP) creates a definitions table for all variables defined with the #define macro. As the CPP passes through the code, it does at least two things with this information.
First, it does a token replacement for the defined macro.
#define MAX(a,b) (a > b) ? (a) : (b)
MAX(1,2); // becomes (1 > 2) ? (1) : (2);
Second, it allows for those definitions to be searched for with other preprocessor macros such as #ifdef, #ifndef, #undef, or CPP extensions like #if defined(MACRO_NAME).
This allows for flexibility in using macro definitions in those cases when the value is not important, but the fact that a token is defined is important.
This allows for code like the following:
// DEBUG is never defined, so this code would
// get excluded when it reaches the compiler.
#ifdef DEBUG
// ... debug printing statements
#endif
#define does a character-for-character replacement. If you give no value, then the identifier is replaced by...nothing. Now this may seem strange. We often use this just to create an identifier whose existence can be checked with #ifdef or #ifndef. The most common use is in what are called "inclusion guards".
In your own preprocessor implementation, I see no reason to treat this as a special case. The behavior is the same as any other #define statement:
Add a symbol/value pair to the symbol table.
Whenever there is an occurrence of the symbol, replace it with its value.
Most likely, step 2 will never occur for a symbol with no value. However, if it does, the symbol is simply removed since its value is empty.

Why do people use #ifdef for feature flag tests?

People recommend #ifdef for conditional compilation by a wide margin. A search for #ifdef substantiates that its use is pervasive.
Yet #ifdef NAME (or equivalently #if defined(NAME) and related #ifndef NAME (and #if !defined(NAME)) have a severe flaw:
header.h
#ifndef IS_SPECIAL
#error You're not special enough
#endif
source.cpp
#include "header.h"
gcc -DIS_SPECIAL source.cpp
will pass, obviously, as will
source1.cpp
#define IS_SPECIAL 1
#include "header.h"
But, so will
source0.cpp
#define IS_SPECIAL 0
#include "header.h"
which is quite the wrong thing to do. And some C++ compilers, passed a file processed in C mode (due to extension or command-line option) effectively do #define __cplusplus 0. I have seen things break when
#ifdef __cplusplus
extern "C" {
#endif
/* ... */
#ifdef __cplusplus
}
#endif
was processed in C mode, where extern "C" is invalid syntax, because __cplusplus was in fact automatically defined to 0.
On the other hand, this behaves correctly for all compilers:
#if __cplusplus
extern "C" {
#endif
/* ... */
#if __cplusplus
}
#endif
Why do people still use #ifdef in this scenario? Are they simply unaware that #if works perfectly fine on undefined names? Or is there an actual disadvantage to #if vs #ifdef for conditional compilation?
Obviously, #ifdef does have valid uses, such as providing default values for configurable parameters:
#ifndef MAX_FILES
#define MAX_FILES 64
#endif
I'm only discussing the case of flag testing.
Why do people still use #ifdef in this scenario?
Personal opinion: it's marginally easier to control from the command line. I prefer -DOPTION over -DOPTION=1.
Also, existence of a name is clearly binary. I don't have to be able to handle {0, non-zero, undefined}.
Are they simply unaware that #if works perfectly fine on undefined names?
I wasn't aware. What are the semantics of this? Is an undefined name assumed to be 0? Do I want to have to explain that to the guy who barely understands the preprocessor to begin with?
Or is there an actual disadvantage to #if vs #ifdef for conditional compilation?
To me, the binary nature of #ifdef/#ifndef of name existence is a clarity benefit.
Also, my primary usage of either construct is for include guards. That pattern is cleanest with #ifndef.
I cannot speak to why people in general prefer #ifdef over #if, but I can at least say why I do. Based on introspection just now (since you asked -- I've never considered it explicitly before), there are 2 reasons:
1) I prefer my macros (which I try to use sparingly) to have the most straightforward semantics as possible, and correspondingly as "type free" as possible. I assume that macros, if they have any type at all, are either "type free functions" (note: here I would strongly prefer templates, but there are times for everything...) or basically just boolean flags. Hence, even assigning a value of 1 to a macro is stretching it for me. (For example, what should it mean if you have #define _cplusplus 2? Should that be different in any way than 1?)
2) This last bit about them being "flags" goes along with the fact that I mostly use these for things I specify on the command line (or in the IDE) as conditional compilation flags. Indeed, on my software team, when we're writing C++, we're basically "prohibited" from using macros for anything else. And even in the conditional compilation case, we try to avoid them if we can solve the problem some other way (such as via modularity).
Both of these reasons relate to that same underlying assumption that macro use is to be avoided as much as possible (in C++) and so should not need the complexities of types or opaque semantics. If you don't make this assumption (and it's less common when programming in C, I know), then that changes things such that I imagine your points about #if might hold more sway.

How to trigger the __cplusplus (C++) #ifdef?

#ifdef __cplusplus
// C++ code
#else
// C code
#endif
The structure is this.
My question is, how to actually trigger the #ifdef on?
I mean, in program? What code I write can turn #ifdef on?
For example, in this case.
is that
#define __cplusplus
will turn it on?
"#define __cplusplus"
will let it on?
Yes, it will "let it on".
__cplusplus should be automatically defined by C++ compiler. C++ uses different name mangling and the macro often used to make C headers compatible with C++:
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
Just compile it with a C++ compiler and __cplusplus is defined automatically in that case.
The C++ Standard enforces that __cplusplus will always be defined in C++ programs. The C Standard obviously does not. This means that the user need go to no effort to enable this machinery.
A C++ compiler defines this automatically.
Since this starts with two consecutive underscores, it is reserved. You are not allowed to define it yourself (i.e., attempting to do so gives undefined behavior).

Multiple #define within #ifdef or #ifndef

This is a simple question, but I have not ran across similar code before to know the answer. Basically, am I allowed to have more than two #define in an #ifdef or #ifndef statement? For a basic example:
#ifdef __GNUC__
#define HELLO(x) x
#define WORLD(y) y
#else
#define __attribute__(x)
#define expect(expression, value) (expression)
#endif
Thank you
Of course you are. This is perfectly valid.
You can have as many C statements or preprocessor directives within a preprocessor block as you want.
Yes, you may have as many preprocessor directives or just normal C++ statements between an #ifdef / #ifndef ... [#else] ... #endif block as you want.
This is a simple enough question that you probably should have tried it before asking though.