Escaping a # symbol in a #define macro? - c++

Without going into the gory details I want to use a #define macro that will expand to a #include but the '#' sign is confusing the preprocessor (as it thinks I want to quote an argument.)
For example, I want to do something like this:
#define MACRO(name) #include "name##foo"
And use it thus:
MACRO(Test)
Which will expand to:
#include "Testfoo"
The humble # sign is causing the preprocessor to barf. MinGW gives me the following error:
'#' is not followed by a macro parameter
I guess I need to escape the # sign but I don't if this is even possible.
Yes, macros are indeed evil...

It is possible to insert a hash token into the preprocessed token stream. You can do it as follows:
#define MACRO(hash, name) hash include name
MACRO(#,"hello")
—expands to:
# include "hello"
However, the standard explicitly rules out any further analysis of such line for the existence of preprocessing directives [cpp.rescan]:
The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one.

As far as I remember you cannot use another preprocessor directive in define.

The problem isn't actually getting a # symbol in the output of your preprocessor.
Apparently you want the preprocessor to reparse your file, to deal with newly created #include directives as part of macro expansion. It doesn't work that way. If a line starts with #, it's an instruction for the preprocessor and interpreted. If a line doesn't start with #, it's only subject to preprocessor transformation including macro substitution. This is a once-per-line test.
MACRO(Test)
does not start with #. Therefore it is not interpreted as a preprocessor directive; instead it's subject to macro replacement rules.

This is because the # has special meaning when used in a macro.
# means quote the following token (which should be a macro parameter name)
## means concatenate the preceding and following tokens.
In your situation the # is not followed by a proper token.
So in your situation we need to go through a level of indirection:
#define QUOTE(name) #name
#define TEST(name) QUOTE(name ## foo)
#include TEST(scot)

You can't do that. Preprocessor directives are recognized before macro expansion; if the macro expands into something that looks like a preprocessor directive, that directive will not be recognized. The best you can do is create a macro for the file name:
#define MACRO(name) "name##foo"
...
#include MACRO(Test)

This might work (it works for regular #define macros with no parameters, but I haven't tested it with macros with parameters).
#define MACRO(name) <name##foo>
#include MACRO(Test)

#define HASH_SIGN #
BOOST_PP_CAT(HASH_SIGN, include)

#define PARAM_NAME Param
#define GETNAME_(a) #a
#define GETNAME(a) GETNAME_(a)
int Param;
printf("%s = %i\n", GETNAME(PARAM_NAME), PARAM_NAME);

Related

how to concatenate strings in #include statement [duplicate]

I would like to have include file paths dynamically created by a macro for a target-configuration-dependent part of my program.
for example, I would like to construct a macro that would be invoked like this:
#include TARGET_PATH_OF(header.h)
Which will expand to a something like this:
#include "corefoundation/header.h"
when the source is configured (in this case) for OSX
So far all attempts have failed. I'm hoping someone out there has done this before?
example of what does not work:
#include <iostream>
#include <boost/preprocessor.hpp>
#define Dir directory/
#define File filename.h
#define MakePath(f) BOOST_PP_STRINGIZE(BOOST_PP_CAT(Dir,f))
#define MyPath MakePath(File)
using namespace std;
int main() {
// this is a test - yes I know I could just concatenate strings here
// but that is not the case for #include
cout << MyPath << endl;
}
errors:
./enableif.cpp:31:13: error: pasting formed '/filename', an invalid preprocessing token
cout << MyPath << endl;
^
./enableif.cpp:26:16: note: expanded from macro 'MyPath'
#define MyPath MakePath(File)
^
./enableif.cpp:25:40: note: expanded from macro 'MakePath'
#define MakePath(f) BOOST_PP_STRINGIZE(BOOST_PP_CAT(Dir,f))
^
/usr/local/include/boost/preprocessor/cat.hpp:22:32: note: expanded from macro 'BOOST_PP_CAT'
# define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b)
^
/usr/local/include/boost/preprocessor/cat.hpp:29:36: note: expanded from macro 'BOOST_PP_CAT_I'
# define BOOST_PP_CAT_I(a, b) a ## b
^
1 error generated.
I tend to agree with the comment in utnapistim's answer that you shouldn't do this even though you can. But, in fact, you can, with standard-conformant C compilers. [Note 1]
There are two issues to overcome. The first one is that you cannot use the ## operator to create something which is not a valid preprocessor token, and pathnames do not qualify as valid preprocessor tokens because they include / and . characters. (The . would be ok if the token started with a digit, but the / will never work.)
You don't actually need to concatenate tokens in order to stringify them with the # operator, since that operator will stringify an entire macro argument, and the argument may consist of multiple tokens. However, stringify respects whitespace [Note 2], so STRINGIFY(Dir File) won't work; it will result in "directory/ filename.h" and the extraneous space in the filename will cause the #include to fail. So you need to concate Dir and File without any whitespace.
The following solves the second problem by using a function-like macro which just returns its argument:
#define IDENT(x) x
#define XSTR(x) #x
#define STR(x) XSTR(x)
#define PATH(x,y) STR(IDENT(x)IDENT(y))
#define Dir sys/
#define File socket.h
#include PATH(Dir,File)
Warning: (Thanks to #jed for passing on this issue.) If the strings being concatenated contain identifiers which are defined elsewhere as macros, then unexpected macro substitution will occur here. Caution should be taken to avoid this scenario, particularly if Dir and/or File are not controlled (for example, by being defined as a command-line parameter in the compiler invocation).
You need to also be aware than some implementations may define words which are likely to show up in a token-like fashion in a file path. For example, GCC may define macros with names like unix and linux unless it is invoked with an explicit C standard (which is not the default). That could be triggered by paths like platform/linux/my-header.h or even linux-specific/my-header.h.
To avoid these issues, I'd recommend that if you use this hack:
you use a C (or C11) standards-conformant compiler setting, and
you place the sequence very early in your source file, ideally before including any other header, or at least any header outside of the standard library.
Also, you wouldn't need the complication of the IDENT macro if you could write the concatenation without spaces. For example:
#define XSTR(x) #x
#define STR(x) XSTR(x)
#define Dir sys
#define File socket.h
#include STR(Dir/File)
Notes
I tried it with clang, gcc and icc, as available on godbolt. I don't know if it works with Visual Studio.
More accurately, it semi-respects whitespace: whitespace is converted to a single space character.
I would like to have include file paths dynamically created by a macro for a target-configuration-dependent part of my program.
You should be unable to (and if you are able to do so, you probably shouldn't do this).
You are effectively trying to do the compiler's job in a source file, which does not make much sense. If you want to change include paths based on the machine you compile on, this is a solved problem (but not solved in a header file).
Canonical solution:
Use an IF in your Makefile or CMakeLists.txt, use custom property pages depending on the build configuration in Visual Studio (or simply set the particular settings for your build in the OS environment for your user).
Then, write the include directive as:
#include <filename.h> // no path here
and rely on the environment/build system to make the path available when the compiler is invoked.
This works for VS2013. (It can be done easier, ofcourse.)
#define myIDENT(x) x
#define myXSTR(x) #x
#define mySTR(x) myXSTR(x)
#define myPATH(x,y) mySTR(myIDENT(x)myIDENT(y))
#define myLIBAEdir D:\\Georgy\\myprojects\\LibraryAE\\build\\native\\include\\ //here whitespace!
#define myFile libae.h
#include myPATH(myLIBAEdir,myFile)
From your description, it sound like you discovered that not every "" is a string. In particular, #include "corefoundation/header.h" looks like an ordinary string but it isn't. Grammatically, quoted text outside preprocessor directives are intended for the compiler, and compile to null terminated string literals. Quoted text in preprocessor directives is interpreted by the preprocessor in an implementation-defined way.
That said, the error in your example is because Boost pasted the second and third token : / and filename. The first, fourth and fifth token (directory, . and h) are left unchanged. This is not what you wanted, obviously.
It's a lot easier to rely on automatic string concatenation. "directory/" "filename" is the same string literal as "directory/filename" Note that there is no + between the two fragments.

Expand define macro with include macro

I'm trying to define a macro. The idea is that when it expands, it'll include a header. For example:
#define function() \
include <CustomHeader.h>
Thanks a lot.
As others have pointed out, you cannot produce a directive from a macro.
You can however produce the argument to a directive from a macro:
#define INCF(F) INCF_(F)
#define INCF_(F) #F
#define BAR foo.h
#include INCF(BAR) // same as #include "foo.h"
But you can't get rid of that explicit #include, or insert it into the middle of a different line, or anything like that.
This can't be done.
The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one, [...]
That particular quote is from a reasonably recent draft of the C++ standard, but with minor changes in wording, the same basic idea has been around nearly forever.

#include file derived from macro __FILE__?

Observe the following program:
#include __FILE__
main(){}
The preprocessor gets stuck in infinite recursion including a copy of itself inside itself and complaining about main() already being defined.
If I can use macros to include files,
can I derive a file name based on __FILE__ and include it?
For example, I'd like to include "foo.h" whilst inside "foo.cpp", but derive it from __FILE__.
## will concatenate macros.
It is also possible to Stringify macros.
Can it be done with the preprocessor?
The C standard specifies three forms of #include:
#include <file>
#include "file"
#include ANYTHING ELSE
In the former two cases, no macro expansion takes place, so there's no way to vary the behavior. In the third case, C99 says (§6.10.2p4):
The preprocessing tokens after #include in the directive are [macro-expanded]. The directive resulting after all replacements shall match one of the two previous forms [footnote: Note that adjacent string literals are not concatenated into a single string literal]. The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single header name preprocessing token is implementation-defined.
Slightly different, but effectively equivalent, wording appears in C++98 §16.2p4.
Any sentence with "shall" in it imposes a hard requirement: in this case, the program is ill-formed if ANYTHING ELSE expands to anything but a sequence of tokens beginning with < and ending with >, or beginning and ending with ". The exact interpretation of that sequence of tokens is implementation defined, but note that the footnote specifically forbids string-literal concatenation.
So, as the expansion of __FILE__ is a string constant, the only ways to use it in an #include are
#include __FILE__
which, as you discovered, leads to infinite recursion, and
#define LT <
#define GT >
#include LT __FILE__ etc GT
which has amusing, but useless, effects on all the compilers I can conveniently test. Assuming that the above is in a file named test.c:
GCC attempts to open a file named "test.c" etc, with the quotation marks and space included verbatim.
clang is even more literal, and looks for that same filename but with leading and trailing spaces.
MSVC macro-expands only the LT (it is my considered opinion that this is a conformance violation), complains that there is no matching >, and then attempts to open a file named __FILE__ etc GT.
(GCC's behavior is documented here; you are on your own for anything else.)
tl;dr: There is no way to do what you want from inside the preprocessor. I recommend working out the name of the file-to-be-included from your build system and notifying the compiler of it with a -D switch (on a Unixy system you will need double quotation, -DINCLUDEME='"includeme.h"'; I don't speak CMD)
The best I've come up with is this:
#define foo(x) #x
#include foo(x)
prog.cpp:2:16: error: x: No such file or directory

Concatenate and stringize macro values for #include

I'm trying to create a string from multiple macros/values for use in a #include. I'm doing this to clean up some code for an initial state in a simple state system.
I have 2 default, redefinable macros (if not defined there's a default value)
#define DEFAULT_STATE StateName // name of class
#define DEFAULT_STATE_LOCATION states/ // location of header file from root
The include directive is being used from a file 4 folders in from the root, so the include should look like this
#include "../../../../states/StateName.h"
based on the example above.
So I want to define a macro from the 4 values.
../../../../
DEFAULT_STATE_LOCATION
DEFAULT_STATE
.h
into some macro, say DEFAULT_STATE_INCLUDE
so I can say
#include #DEFAULT_STATE_INCLUDE
(to stringize the value for quotes)
That way I can change the default state and the path from the root of the header file for the default state in a prefix header, and the source using the #include will not have to be updated, and I can omit the constants from redefinition every time.
I'm not including the .h in the DEFAULT_STATE macro because I use the same macro to create and instance of the default state.
I've tried using the concatenation ##, and the stringize operator, and some tricks I've found online, but nothing worked.
I can define ../../../../ and .h in their own macros if needed.
But simply
#define DEFAULT_STATE_INCLUDE ../../../../ ## DEFAULT_STATE_LOCATION ## DEFAULT_STATE ## .h
#include #DEFAULT_STATE_INCLUDE
gives tons of errors.
Any help is appreciated.
Thanks
Note that footnote 143 in section §6.10.2 "Source file inclusion" of the C99 standard says:
143) Note that adjacent string literals are not concatenated into a single string literal (see the translation
phases in 5.1.1.2); thus, an expansion that results in two string literals is an invalid directive.
Thus, any string concatenation must be done outside the source code. Token concatenation with ## is not an option; that is used to build identifiers, and the bits of the header name you are joining are not identifiers.
I think you should simply use something like:
#ifndef STATE_HEADER
#define STATE_HEADER "states/StateName.h"
#endif
#include STATE_HEADER
and leave it to the build system, not the source code, to determine that -I../../../.. is required as an option to the compiler.
You'd better pass the include directory to gcc with -I option
-I../../../..
From gcc man page:
-I dir
Add the directory dir to the list of directories to be searched for header files.
This seems relevant: Computed Includes
My reading of that is that the #define macro has to include the " (quote) characters and that you can't rely on the stringize or concatenation operators to do it for you.

Multiple preprocessor directives on one line in C++

A hypothetical question: Is it possible to have a C++ program, which includes preprocessor directives, entirely on one line?
Such a line would look like this:
#define foo #ifdef foo #define bar #endif
What are the semantics of such a line?
Further, are there any combinations of directives which are impossible to construct on one line?
If this is compiler-specific then both VC++ and GCC answers are welcome.
A preprocessing directive must be terminated by a newline, so this is actually a single preprocessing directive that defines an object-like macro, named foo, that expands to the following token sequence:
# ifdef foo # define bar # endif
Any later use of the name foo in the source (until it is #undefed) will expand to this, but after the macro is expanded, the resulting tokens are not evaluated as a preprocessing directive.
This is not compiler-specific; this behavior is defined by the C and C++ standards.
Preprocessor directives are somewhat different than language statements, which are terminated by ; and use whitespace to delimit tokens. In the case of the preprocessor, the directive is terminated by a newline so it's impossible to do what you're attempting using the C++ language itself.
One way you could kind of simulate this is to put your desired lines into a separate header file and then #include it where you want. The separate header still has to have each directive on one line, but the point where you include it is just a single line, effectively doing what you asked.
Another way to accomplish something like that is to have a pre-C++ file that you use an external process to process into a C++ source file prior to compiling with your C++ compiler. This is probably rather more trouble than it's worth.