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.
Related
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).
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
if in the beginning of my file i do
#define dbg_kprintf \
if (x_var) kprintf
I late on do statements using
dbg_kprintf ("blablabla");
My question is that will dbg_kprintf be only defined if xvar is defined somewhere else? If it is not then will dbg_kprintf statements not be used at compile time?
Thanks.
No, that will either compile into a run-time check of the variable, or nothing (if the variable is in fact compile-time constant with a false value and the optimizer feels like eliminating the dead code) or a call always (if it's a compile-time constant with a true value). So, now you know.
The typical way to ensure that debug code is excluded from non-debugging builds is to use a preprocessor symbol to guard the code. Note that it might require you to manage the arguments differently.
No, in that example, x_var has to exist somewhere or it will fail to compile. You are looking for something like
#if (x_var)
#define dbg_kprintf kprintf
#else
#define dbg_kprintf
#endif
In C/C++ Macros can take arguments. It will be defined either way, as it's just a pre-processing directive but the compile will fail if it's not defined. To pass an argument to a macro use this syntax
#define foo(X) ((X))
dbg_kprintf will be used before complie time. The preprocessor will substitute in its place the contents you defined: if (x_var) kprintf. Then it will try to compile your code normally.
I was wondering if it was possible to define a macro in C++ that defines another macro that can be used in later code. Is this possible, or is the preprocessor used by g++ too limited for this?
No, you cannot define a macro within the expansion of another macro.
Nope, you can't define a macro as a macro.
The preprocessor makes only one pass over the source code, so this is not possible. However, you could use an external tool to perform some preprocessing ahead of compilation, like m4.
You can do something like this, its not exactly what you are looking for, but it might help.
#ifdef ENABLE_MACRO_1
#define PRINT_MACRO(varName) \
std::cout<<varName<<std::endl;
#else
#define PRINT_MACRO(varName) \
//do nothing
#endif
So you can define a macro depending on another preprecursor condition which was defined defined.
What is the role of the #define directive?
#define is used to create macros in C and in C++. You can read more about it in the C preprocessor documentation. The quick answer is that it does a few things:
Simple Macros - basically just text replacement. Compile time constants are a good example:
#define SOME_CONSTANT 12
simply replaces the text SOME_CONSTANT with 12 wherever it appears in your code. This sort of macro is often used to provide conditional compilation of code blocks. For example, there might be a header included by each source file in a project with a list of options for the project:
#define OPTION_1
#define OPTION_2
#undef OPTION_3
And then code blocks in the project would be wrapped with matching #ifdef/#endif# blocks to enable and disable those options in the finished project. Using the -D gcc flag would provide similar behaviour. There are strong opinions as to whether or not this method is really a good way to provide configuration for an application, however.
Macros with arguments - allows you to make 'function-like' macros that can take arguments and manipulate them. For example:
#define SQUARE(x) ((x) * (x))
would return the square of the argument as its result; be careful about potential order-of-operations or side-effect problems! The following example:
int x = SQUARE(3); // becomes int x = ((3) * (3));
will works fine, but something like:
int y = SQUARE(f()); // becomes int y = ((f()) * (f()));
will call f() twice, or even worse:
int z = SQUARE(x++); // becomes int z = ((x++) * (x++));
results in undefined behaviour!
With some tools, macros with arguments can also be variadic, which can come in handy.
As mentioned below in the comments, overuse of macros, or the development of overly complicated or confusing macros is considered bad style by many - as always, put the readability, maintainability, and debuggability of your code above 'clever' technical tricks.
#define (and it's opposite, #undef) can be used to set compiler directives which can then be tested against using #ifndef or #ifdef. This allows for custom behaviors to be defined within the source file. It's used commonly to compile for different environments or debug code.
An example:
#define DEBUG
#ifdef DEBUG
//perform debug code
#endif
The most common use (by far) of #define is for include guards:
// header.hh
#ifndef HEADER_HH_
#define HEADER_HH_
namespace pony {
// ...
}
#endif
Another common use of #define is in creating a configuration file, commonly a config.h file, where we #define macros based on various states and conditions. Then, in our code we test these macros with #ifdef, #elif defined() etc. to support different compiles for different situations. This is not as solid as the include-guard idiom and you need to be careful here because if the branching is wrong then you can get very obscure compiler errors, or worse, runtime behavior.
In general, other than for include guards you need to think through (twice, preferably) about the problem, and see if you can use the compiler rather than the preprocessor to solve it. The compiler is just smarter than the preprocessor. Not only that, but the compiler can't possibly confuse the preprocessor, whereas the preprocessor most definitely can confuse and mislead the compiler.
The #define directive has two common uses.
The first one, is control how the compiler will act. To do this, we also need #undef, #ifdef and #ifndef. (and #endif too...)
You can make "compiler logic" this way. A common use is to activate or not a debug portion of the code, like that:
#ifdef DEBUG
//debug code here
#endif
And you would be able to for example compile the debug code, by writing a #define DEBUG
Another use of this logic stuff, is to avoid double includes...
Example, file A, #includes file B and C. But file B also includes C. This likely will result in a compilation error, because "C" exists twice.
The solution is write:
#ifndef C_FILE_INCLUDED
#define C_FILE_INCLUDED
//the contents of header "c" go here.
#endif
The other use of #define, is make macros.
The most simple ones, consist of simple substitutions, like:
#define PI 3.14159265
float perimeter(float radius) {
return radius*2*PI;
}
or
#define SHOW_ERROR_MESSAGE printf("An serious error happened");
if ( 1 != 1 ) { SHOW_ERROR_MESSAGE }
Then you can also make macros that accept arguments, printf itself usually is a macro, created with a #define in a header file.
But this should not be done, for two reaons:
first, the speed os macros, is the same of using inline, and second, we have c++ templates, that allow more control over functions with variable type. So, the only reason to use macros with arguments, is make strange constructs, that will be hard to understand later, like metaprogrammed stuff...
In C++, #define has very narrow, specialized roles:
Header guards, described in other answers
Interacting with the standard libraries. For instance, #defining WINDOWS_LEAN_AND_MEAN before including windows.h turns off certain often-problematic macros like MAX.
Advanced macros involving stringization (ie, macros that print debugging messages) or token-pasting.
You should avoid using #define for the following purposes. The reasons are many; see for instace this FAQ entry.
Compile-time constants. Use const instead.
Simple macro functions. Use inline functions and templates instead.
in C or C++ #define allows you to create preprocessor Macros.
In the normal C or C++ build process the first thing that happens is that the PreProcessor runs, the preprocessor looks though the source files for preprocessor directives like #define or #include and then performs simple operations with them.
in the case of a #define directive the preprocessor does simple text based substitution.
For example if you had the code
#define PI 3.14159f
float circum = diameter*PI;
the preprocessor would turn it into:
float circum = diameter* 3.14159;
by simply replacing the instances of PI with the corresponding text. This is only the simplest form of a #define statement for more advanced uses check out this article from MSDN
inCorrectUseOfHashDefine()
{
The role of #define is to baffle people who inherit your code with out of the blue statements like:
foreverandever
because of:
#define foreverandever for(;;)
}
Please favour constants over #define.
It also for setting compiler directives...
Most things about #defines have been already told, but it's not clear that C++ has better replacements for most of their uses:
#define to define numerical constants can be easily replaced by a const "variable", that, as a #define, doesn't really exist in the compiled executable. AFAIK it can be used in almost all the situations where you could use a #defined numerical constant, including array bounds. The main advantage for me is that such constants are clearly typed, so there's no need to add casts in the macros "just to be sure", and are scoped, so they can be kept in namespaces/classes/functions, without polluting all the application.
const int max_array_size=50;
int an_array[max_array_size];
#define to create macros: macros can often be replaced by templates; for example, the dreaded MAX macro
#define MAX(a,b) ((a)<(b)?(b):(a))
, which has several downsides (e.g. repeated arguments evaluation, inevitable inline expansion), can be replaced by the max function
template<typename T> T & max(T & a, T & b)
{
return a<b?b:a;
}
which can be type-safe (in this version the two arguments are forced to be of the same type), can be expanded inline as well as not (it's compiler decision), evaluates the arguments just once (when it's called), and is scoped. A more detailed explanation can be found here.
Still, macros must still be used for include guards, to create some kind of strange language extensions that expand to more line of code, that have unbalanced parenthesis, etc.