tags:

views:

188

answers:

4

Hello,

I want to define a macro which includes another header file like so:

#define MY_MACRO (text) #include "__FILE__##_inline.inl"

So that when the preprocessor parses file person.h, MY_MACRO(blahblah) expands to

#include "person.h.inline.inl"

any hints on how to do this ?

+8  A: 

It's not possible to use #define to construct other preprocessor directives, unless you run the preprocessor twice.

But in your case even running the preprocessor twice won't help because the #include must be a single string of the form "..." or <...>.

KennyTM
+2  A: 

You can't write other pre-processor directives using the pre-processor. However, I believe you could define just the file name:

#define MY_MACRO(name) "__FILE__##name_inline.inl"

#include MY_MACRO(name)

The pre-processor runs multiple times until there are no further substitutions it can make, so it should expand the name first and then #include the referenced file.

EDIT: I just tried it and the pre-processor can't handle the quotes like that.

#define MY_MACRO(x) <__FILE__##x_inline.inl>
#include MY_MACRO(foo)

works OK, but <> may not be what you wanted.

EDIT2: As pointed out by sth in comments, the __FILE__ does not expand correctly, which makes this probably not what you want after all. Sorry.

Vicky
http://codepad.org/AxNh2h3F Apparently `"__FILE__##name_inline.inl"` is treated literally, but if you switch it to `#define MY_MACRO(name) <__FILE__ ## name ## _inline.inl>` then you *can* actually include a file variably.
Daniel Trebbien
I don't think this works at all. The macro you provide expands to `<__FILE__x_inline.inl>`, while it should be something like `<person.h_foo_inline.inl>`.
sth
@sth: You're quite right, I missed that. I tried breaking it down to two stages as well:[code]#define MY_MACRO(a) __FILE__ ##a #define MY_MACRO_2(b) < MY_MACRO(b) _inline.inl >#include MY_MACRO_2(test)[/code]but that doesn't help either.
Vicky
All this cannot work because `__FILE__` expands to a quoted literal string. The concatenation of `__FILE__` with something else then has the quotes at the wrong place.
Philipp
If the file name `"person.h".inline.inl` is also acceptable, then your solution works, but it's a bit nonportable because file names containing quotes are not allowed on Windows. However, it looks a bit ugly to require such file names only to save a few keystrokes.
Philipp
+4  A: 

You cannot use __FILE__ because that is already quoted, and #include doesn't support string concatenation. But you can use macros after #include:

#define STRINGIZE_AUX(a) #a
#define STRINGIZE(a) STRINGIZE_AUX(a)
#define CAT_AUX(a, b) a##b
#define CAT(a, b) CAT_AUX(a, b)
#define MY_MACRO(file, name) STRINGIZE(CAT(file, CAT(name, _inline.inl)))
#include MY_MACRO(aaaa, qqq)

You should use the equivalent Boost.Preprocessor macros instead of CAT and STRINGIZE to prevent global namespace pollution.

Philipp
+1 I'm not sure if it's very ugly or very beautyful but it seems to work...
Tomas
yes it does manage to include the file, but still i have to use a separate #include, and also it seems __FILE__ is expanded to a quoted string so may be this is not possible at all.
digitalSurgeon
Yes, it's truly impossible. Try to redesign your application so that it's not necessary.
Philipp
A: 

Was trying to do something like this recently and the C++ compiler poked me on the back of the head and said: "Are you crazy? A Macro that calls another Macro?".

The point here is that we need to understand that the pre-processor is just a "substitution process that runs once": no "multiple iterations" whatsoever.

So, you can't.

Detro
That's not right. It does run multiple iterations, until it can't make any further substitutions (it also has guards against infinite recursion). You can easily see this by defining one macro which says '#define A B' and another which says '#define B C'. If you then look at the pre-proceesed output, instances of A will be replaced with C, not B.
Vicky