I have a macro I use for debugging.
#define diagnostic_arg(message,...) fprintf(stderr,message,__VA_ARGS__)
I've found that I need to use wide-chars in my program, so I would like to change just my macro and have everything work:
#define diagnostic_arg(message,...) fwprintf(stderr,message,__VA_ARGS__)
However, I need wide character strings, which are defined by putting an L in front of the string's beginning quote mark:
#define diagnostic_arg(message,...) fprintf(stderr,Lmessage,__VA_ARGS__)
Now obviously, the above line doesn't work. But if I use L message, that won't work either. So how do I write Lmessage and have it do what I would like?
You can use the token pasting operator ##:
#define diagnostic_arg(message,...) fprintf(stderr,L##message,__VA_ARGS__)
However, it might be better to use TEXT macro (if you are in Visual Studio) which will do the right thing whether UNICODE is defined or not:
#define diagnostic_arg(message,...) fprintf(stderr,TEXT(message),__VA_ARGS__)
If you're not, TEXT can be defined like this:
#ifdef UNICODE
#define TEXT(str) L##str
#else
#define TEXT(str) str
#endif
However, if you plan on using other #defines as the first argument to this macro (and really even if you don't plan on it), you will need another layer of indirection in the macro so the definition will be evaluated instead of pasted together with L as text. See Mooing Duck's answer for how to do that, his is actually the correct way to do this, but I'm not deleting this answer because I want to keep my 80 rep.
I vaguely recall the answer being something along the lines of
//glues two symbols together that can't be together
#define glue2(x,y) x##y
#define glue(x,y) glue2(x,y)
//widens a string literal
#define widen(x) glue(L,x)
#define diagnostic_arg(message,...) fprintf(stderr,widen(message),__VA_ARGS__)
Glue sometimes needs to be two macros (as I've shown), for bizzare reasons I don't quite understand, explained at the C++faq
Related
I use a macro in C++ to switch between compiling logging or not:
#define MAYBE_LOG(msg)
#ifdef PRINT_MSGS
ALWAYS_LOG(msg)
#endif
How does the #define know where the ending is? The #endif refers to the #ifdef, not the #define.
#define ends at end of the line (which might be extended with final \)
The code in the question does two separate things: it defines a macro named MAYBE_LOG with no body and, if PRINT_MSGS is defined, it uses a macro named ALWAYS_LOG. If that's not what it's supposed to do, then, yes, it needs to be changed. Since the question doesn't say what the code is supposed to do, this is just a guess:
#ifdef PRINT_MSGS
#define MAYBE_LOG(msg) ALWAYS_LOG(msg)
#else
#define MAYBE_LOG(msg)
#endif
The reason for doing it this way (and not using \ on each line to extend the macro definition is that you can't put #if conditions inside the definition of a macro.
Imagine I have some "assert like" functionality, which declares a macro one way if a specific macro is defined, and a different way if it is not:
// in some header assert2.hpp
#ifdef NO_ASSERT2
#define assert2(x)
#else
#define assert2(x) assert2_handler(x);
#endif
Here, the NO_ASSERT2 macro is very much like the NDEBUG macro in standard assert(3).
What I'd like to do, however is allow the user to override the NO_ASSERT2 check with their own macro, before including the file. E.g., if you included assert2.hpp like this:
#define NO_ASSERT_KEY NO_ASSERT_CUSTOM
#include "assert2.hpp"
Then the macro NO_ASSERT_CUSTOM would be checked instead of the default NO_ASSERT2 for this translation unit.
It doesn't have to work exactly like the above - I just need some way to override the behavior on a per-file basis, without needing more than the 1 line of boilerplate shown above at the location of the include.
This isn't pretty... but this approach may work for you. It assumes that the macro is defined using either #define FOO, #define FOO 1, or -DFOO (assuming as typical that this creates something equivalent to #define FOO 1).
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(A,B,...) B
#define GLUE3(A,B,C) GLUE3_I(A,B,C)
#define GLUE3_I(A,B,C) A##B##C
#define AGLUE3(A,B,C) AGLUE3_I(A,B,C)
#define AGLUE3_I(A,B,C) A##B##C
#define TEST_ASSERT_KEY GLUE3(NO_ASSERT_PROBE,0_,NO_ASSERT_KEY)
#define NO_ASSERT_PROBE0_NO_ASSERT_KEY AGLUE3(NO_ASSERT_PROBE,0_,NO_ASSERT2)
#define NO_ASSERT_PROBE0_ ,1
#define NO_ASSERT_PROBE0_1 ,1
#define NO_ASSERT_TEST SECOND(TEST_ASSERT_KEY,0)
With this, your usage would be:
#if NO_ASSERT_TEST
#define assert2(x)
#else
#define assert2(x) assert2_handler(x);
#endif
Here's a demo at stacked-crooked.
This uses pattern matching in the preprocessor via the indirect SECOND macro. The idea is that it expands to its second argument, but only indirectly... this allows you to construct as the first argument a pattern. Usually that first argument's ignored, but if you want to match something you can set it up to where the first argument would be a macro that expands with a comma; that shifts a new second argument in, replacing the default.
From here it's easier to explain backwards. NO_ASSERT_TEST uses TEST_ASSERT_KEY to construct a pattern with a default of 0. TEST_ASSERT_KEY builds NO_ASSERT_PROBE0_ concatenated with NO_ASSERT_KEY. When NO_ASSERT_KEY is defined, this would build NO_ASSERT_PROBE0_ concatenated with the expansion of what it's defined as. Otherwise it rebuilds the test token using NO_ASSERT_PROBE0_ concatenated with NO_ASSERT2.
Either way this is an indirect paste, so NO_ASSERT_KEY in the former case or NO_ASSERT2 in the latter is expanded first. In the former case, if say NO_ASSERT_KEY is NO_ASSERT_CUSTOM and NO_ASSERT_CUSTOM is not defined, this builds NO_ASSERT_PROBE0_NO_ASSERT_CUSTOM, which is just a normal identifier, which will be ignored, which results in 0 due to the SECOND in NO_ASSERT_TEST. But if NO_ASSERT_CUSTOM is defined per #define NO_ASSERT_CUSTOM, this produces NO_ASSERT_PROBE0_, which expands to ,1, which shifts 1 into the SECOND call in NO_ASSERT_TEST. Likewise if NO_ASSERT_CUSTOM is defined per -DNO_ASSERT_CUSTOM on the command line, that would (typically) make its definition equivalent to #define NO_ASSERT_CUSTOM 1, which would produce NO_ASSERT_PROBE0_1, which expands to ,1.
The cases for when NO_ASSERT_KEY is not defined are similar.
There's probably a prettier way to build this construct, if anyone wants to take a shot.
We have a profiling framework which can be enabled and disabled at compile time.
All the various calls to the framework are done through macros, eg:
PROFILE_START(msg)
PROFILE_END(msg)
The macros then resolve to the actual profiler call when profiling is enabled, and to nothing when disabled
#ifdef PROFILING_ENABLED
# define PROFILE_START(msg) currentProfiler().start(msg)
# define PROFILE_END(msg) currentProfiler().end(msg)
#else
# define PROFILE_START(msg)
# define PROFILE_END(msg)
#endif
We have various different components in our framework, and I want to enable profiling in each component.
I'd like to be able to selectively enable profiling in each component.
My idea is to prefix all the profiler macros with the component's name, eg:
FOO_PROFILE_START(msg)
FOO_PROFILE_END(msg)
BAR_PROFILE_START(msg)
BAR_PROFILE_END(msg)
I could manually create
#ifdef ENABLE_FOO_PROFILING
# define FOO_PROFILE_START(msg) PROFILE_START(msg)
# define FOO_PROFILE_END(msg) PROFILE_END(msg)
#else
# define FOO_PROFILE_START(msg)
# define FOO_PROFILE_END(msg)
#endif
#ifdef ENABLE_BAR_PROFILING
# define BAR_PROFILE_START(msg) PROFILE_START(msg)
# define BAR_PROFILE_END(msg) PROFILE_END(msg)
#else
# define BAR_PROFILE_START(msg)
# define BAR_PROFILE_END(msg)
#endif
However, this is both tedious and error-prone.
Any time a new feature is added to the profiling framework I would have to find all my component specific macros and add a new macro to each of them.
What I'm looking for is a way to automatically generate the component-prefixed macros.
#ifdef ENABLE_FOO_PROFILING
ADD_PREFIX_TO_ENABLED_PROFILING_MACROS(FOO)
#else
ADD_PREFIX_TO_DISABLED_PROFILING_MACROS(FOO)
#endif
The net result of the above would be to create all the FOO_PROFILE_XXX macros I would have done manually.
Questions:
Is such a helper macro possible?
Is there a better way of achieving what I'm looking for?
I'm happy to use BOOST_PP if necessary.
Before posting this question I tried figuring this out myself, and the code I came up with follows, which may serve to show the road I was going down
#include <stdio.h>
#define PROFILE_START(msg) printf("start(%s)\n", msg);
#define PROFILE_END(msg) printf("end(%s)\n", msg);
#define ENABLE(prefix) \
#define prefix ## _PROFILE_START PROFILE_START \
#define prefix ## _PROFILE_END PROFILE_END
#define DISABLE(prefix) \
#define prefix ## _PROFILE_START \
#define prefix ## _PROFILE_END
#define ENABLE_FOO
#ifdef ENABLE_FOO
ENABLE(FOO)
#else
DISABLE(FOO)
#endif
#ifdef ENABLE_BAR
ENABLE(BAR)
#else
DISABLE(BAR)
#endif
int main()
{
FOO_PROFILE_START("foo");
FOO_PROFILE_END("foo");
BAR_PROFILE_START("bar");
BAR_PROFILE_END("bar");
return 0;
}
Is such a helper macro possible?
No. With the exception of pragmas, you cannot execute a preprocessing directive in a macro.
You can do something very similar using pattern matching. By taking the varying parts out of the macro name, and putting it inside the macro itself, you can make a form that allows enabling/disabling for arbitrary names.
This requires a tiny bit of preprocessor metaprogramming (which is a constant overhead; i.e., doesn't vary as you add modules), so bear with me.
Part 1: A C preprocessor solution
Using this set of macros:
#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(_,X,...) X
#define SWITCH(PREFIX_,PATTERN_,DEFAULT_) SECOND(GLUE(PREFIX_,PATTERN_),DEFAULT_)
#define EAT(...)
#define PROFILER_UTILITY(MODULE_) SWITCH(ENABLE_PROFILER_FOR_,MODULE_,DISABLED)
#define PROFILER_IS_DISABLED ,EAT
#define PROFILE_START_FOR(MODULE_, msg) SWITCH(PROFILER_IS_,PROFILER_UTILITY(MODULE_),PROFILE_START)(msg)
#define PROFILE_END_FOR(MODULE_, msg) SWITCH(PROFILER_IS_,PROFILER_UTILITY(MODULE_),PROFILE_END)(msg)
...which you can include in each module, you will gain the ability to do this:
PROFILE_START_FOR(FOO,msg)
PROFILE_END_FOR(FOO,msg)
PROFILE_START_FOR(BAR,msg)
PROFILE_END_FOR(BAR,msg)
PROFILE_START_FOR(BAZ,msg)
PROFILE_END_FOR(BAZ,msg)
All of these macros, by default, expand to nothing; you can change this by defining ENABLE_PROFILER_FOR_xxx for any subset of FOO, BAR, or BAZ to expand to , (or ,ON if that looks better), in which case the corresponding macros will expand (initially, before your own macros come in) to PROFILE_START(msg)/PROFILE_END(msg); and the rest will continue expanding to nothing.
Using the FOO module as an example, you can do this with a "control file": #define ENABLE_PROFILER_FOR_FOO ,ON; the command line: ... -DENABLE_PROFILER_FOR_FOO=,ON; or in a makefile; CFLAGS += -DENABLE_PROFILER_FOR_FOO=,ON.
Part 2a: how it works; the SWITCH macro
#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(_,X,...) X
#define SWITCH(PREFIX_,PATTERN_,DEFAULT_) SECOND(GLUE(PREFIX_,PATTERN_),DEFAULT_)
GLUE here is your typical indirect paste macro (allowing arguments to expand). SECOND is an indirect variadic macro returning the second argument.
SWITCH is the pattern matcher. The first two arguments are pasted together, comprising the pattern. By default, this pattern is discarded; but due to the indirection, if that pattern is an object like macro, and that pattern's expansion contains a comma, it will shift a new second argument in. For example:
#define ORDINAL(N_) GLUE(N_, SWITCH(ORDINAL_SUFFIX_,N_,th))
#define ORDINAL_SUFFIX_1 ,st
#define ORDINAL_SUFFIX_2 ,nd
#define ORDINAL_SUFFIX_3 ,rd
ORDINAL(1) ORDINAL(2) ORDINAL(3) ORDINAL(4) ORDINAL(5) ORDINAL(6)
...will expand to:
1st 2nd 3rd 4th 5th 6th
In this manner, the SWITCH macro behaves analogous to a switch statement; whose "cases" are object-like macros with matching prefixes, and which has a default value.
Note that pattern matching in the preprocessor works with shifting arguments, hence the comma (the main trick being that of discarding unmatched tokens by ignoring an argument, and applying matched tokens by shifting a desired replacement in). Also for the most general case with this SWITCH macro, you need at a minimum to ensure that all PREFIX_/PATTERN_ arguments are pasteable (even if that token isn't seen, it has to be a valid token).
Part 2b: combined switches for safety
A lone switch works like a case statement, allowing you to shove anything in; but when the situation calls for a binary choice (like "enable" or "disable"), it helps to nest one SWITCH in another. That makes the pattern matching a bit less fragile.
In this case, the implementation:
#define PROFILER_UTILITY(MODULE_) SWITCH(ENABLE_PROFILER_FOR_,MODULE_,DISABLED)
#define PROFILER_IS_DISABLED ,EAT
#define PROFILE_START_FOR(MODULE_, msg) SWITCH(PROFILER_IS_,PROFILER_UTILITY(MODULE_),PROFILE_START)(msg)
#define PROFILE_END_FOR(MODULE_, msg) SWITCH(PROFILER_IS_,PROFILER_UTILITY(MODULE_),PROFILE_END)(msg)
...uses PROFILER_UTILITY as the inner switch. By default, this expands to DISABLED. That makes the pattern in SWITCH(PROFILER_IS_,PROFILER_UTILITY(MODULE_),PROFILE_START) by default be PROFILER_IS_DISABLED, which shoves in EAT. In the non-default case of PROFILER_UTILITY, the outer switch kicks in making it expand to PROFILE_START. PROFILE_END_FOR works analogously.
The EAT macro takes (msg) in both cases to nothing; otherwise, the original macro's called.
Is there a better way of achieving what I'm looking for?
Depends on what you're looking for. This approach shows what's possible with the C preprocessor.
I personally would go for something like
#include <stdio.h>
#define FOO_ENABLED 1
#define BAR_ENABLED 0
#define PROFILE_START(FLAG, msg) \
{ if (FLAG) printf("start(%s)\n", msg); }
int main()
{
PROFILE_START(FOO_ENABLED, "foo")
PROFILE_START(BAR_ENABLED, "bar")
return 0;
}
Any decent compiler would not generate any instructions for the if statement anyway.
Is such a helper macro possible?
No. As was covered in comments, you cannot generate macro definitions via macros.*
Is there a better way of achieving what I'm looking for?
Since the macro idea won't work,* any alternative that does work is better. Basically, you're looking for a code generator -- a program that will take as input a list of modules and produce as output C source (maybe a header) containing definitions of all the profiling macros for all the modules. You could write such a program in pretty much any language -- C, python, perl, shell script, whatever. Depending on your technology preferences and project context, you might even go with something like XSLT.
Each source file that wants to get the profiling macros then just #includes the generated header.
*In fact, you could use the C preprocessor, by performing a separate, standalone run on a different, for-purpose input file. But you cannot generate the macros in-place when you compile the source file(s) that wants to use them.
My problem is first of all, understanding #ifndef and #ifdef. I also want to understand the difference between #if, #ifndef , and #ifdef. I understand that #if is basically an if statement. For example:
#include<iostream>
#define LINUX_GRAPHICS 011x101
int main(){
long Compare = LINUX_GRAPHICS;
#if Compare == LINUX_GRAPHICS
std::cout << "True" << std::endl;
#endif
}
But the others, although I read about them I can't comprehend. They also seem like very similar terms, but I doubt they work similarly. Help would be greatly appreciated.
Macros are expanded by the preprocessor who doesn't know anything about values of variables during runtime. It is only about textual replacement (or comparing symbols known to the preprocessor). Your line
#if Compare == LINUX_GRAPHICS
will expand to
#if Compare == 011x101
and as "Compare" is different from "011x101", it evaluates to false. Actually I am not even 100% sure about that, but the point is: you are mixing preprocessor directives with variables that are evaluated at runtime. That is non-sense. Preprocessor directives are not there to replace C++ statements.
For most traditional use cases of macros there are better way nowadays. If you don't really need to use macros, it is better not to use them. It makes it extremely hard to read the code (eg. I don't understand how that macros in your code work and unless I really need it honestly I don't want to know :P) and there are other problems with macros that can lead to very hard to find bugs in your program. Before using macros I would advice you to first consider if there isn't a more natural C++ way of achieving the same.
PS:
#ifdef SYMBOL
ifdef = "if defined"
this part of the code is excluded before the compiler even sees it
if SYMBOL is not defined (via #define)
#endif
#ifndef SYMBOL
ifndef = "if not defined"
this part of the code is excluded before the compiler even sees it
if SYMBOL is defined (via #define)
#endif
I wrote "excluded" on purpose to emphasize the bad impact it has on readability of your code. If you overuse #ifdef or #ifndef inside normal blocks of code, it will be extremely hard to read.
#if doesn't have any notion about Compare or the value it contains, so it probably doesn't do what you intend.
Remember the preprocessor does plain text replacement.
The statement will expand as seen from #if as
#if Compare == 011x101
and being expanded as
#if 0 == 011x101
which certainly won't yield true at the preprocessing stage.
The #ifdef and #ifndef directives check if a preprocessor symbol was #define'd at all, either using that (<--) preprocessor directive, or your compilers preprocessor option (most commonly -D<preprocessor-symbol>).
These don't care if the preprocessor symbol carries an empty value or something. A simple
#define MY_CONDITION
or
-DMY_CONDITION
is enough to satisfy
#ifdef MY_CONDITION
to expand the text coming afterwards (or hide it with #ifndef).
The Compare declaration isn't a preprocessor symbol and can't be used reasonably with #ifdef or #ifndef either.
#if is preprocessor if. It can only deal with with preprocessor stuff which is basically preprocessor macros (which are either function like or constant-like) and C tokens with some simple integer-literal arithmetic.
#ifdef SOMETHING is the same as #if defined(SOMETHING) and
#ifndef SOMETHING is the same as #if !defined(SOMETHING). defined is a special preprocessor operator that allows you to test whether SOMETHING is a defined macro. These are basically shortcuts for the most common uses or preprocessor conditionals -- testing whether some macros are defined or not.
You can find a detailed manual (~80 pages) on the gcc preprocessor at
https://gcc.gnu.org/onlinedocs/ .
Well the preprocessors #ifdef and #ifndef mean the followind: In your example you used #define to set a constant variable named LINUX_GRAPHICS to be equal to 011x101. So later in your program you migth want to check if this variable is defined. Then you use #ifdef, when you want to check if this variable is defined and #ifndef if not. I wish I helped you.
Basicaly, preprocessor does text substitution. Then the compiler compiles program into machine code. And then CPU executes machine instructions. This means you can't use preprocessor #if instead of operator if: one does text substitution, while second generates branching code for CPU.
So preprocessor directives such as #if, #ifdef, #ifndef serve for "semi-automatic mode" of generating (a little) different programs based on some "meta-input". Actually you can always do these substitutions yourself and get working C/C++ program without any preprocessor directives. Also compilers often have a command-line switch which outputs just preprocessed program, i.e. without any #if directives. Try to play with it, and you should get what these directives do.
#ifdef XXX is just the same as #if defined(XXX) where defined(XXX) is builtin preprocessor-only function which is true when identifier XXX is defined in program text by another preprocessor directive #define. And #ifndef XXX is just #if !defined(XXX).
Is it possible to put a macro in a macro in c++?
Something like:
#define Something\
#ifdef SomethingElse\ //do stuff \
#endif\
I tried and it didn't work so my guess is it doesn't work, unless there's some sort of syntax that can fix it?
Macros, yes. Preprocessor directives, which are what you posted, no
No, but you can simply refactor this by pulling the #ifdef out as the toplevel, and using two different #define Something ... versions for the true and false branches of the #ifdef.
You can't use preprocessor directives in macros, but if we want to check if SomethingElse is defined and call a different macro, you could accomplish it like this(requires a c99 preprocessor and Boost.Preprocessor library):
#define PP_CHECK_N(x, n, ...) n
#define PP_CHECK(...) PP_CHECK_N(__VA_ARGS__, 0,)
//If we define SomethingElse, it has to be define like this
#define SomethingElse ~, 1,
#define Something \
BOOST_PP_IF(PP_CHECK(SomethingElse), MACRO1, MACRO2)
If SomethingElse is defined it will call MACRO1, otherwise it will call MACRO2. For this to work, SomethingElse has to be defined like this:
#define SomethingElse ~, 1,
By the way, this won't work in Visual Studio, because of a bug in their compiler, there is a workaround here: http://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement
No. I answered this in c++ macros with memory?
If you want to inspect or alter the preprocessing environment, in other words to define a preprocessing subroutine rather than a string-replacement macro, you need to use a header, although the legitimate reasons for doing so are few and far between.