views:

348

answers:

3

is there some way to embed pragma statement in macro with other statements?

I am trying to achieve something like:

#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type_(int handle);                  \
    void delete_ ## type(int handle);                                                \
    #pragma weak delete_ ## type_ = delete_ ## type

I am okay with boost solutions (save for wave) if one exists. thank you

+1  A: 

is there some way to embed pragma statement in macro with other statements?

No, you cannot put preprocessor statements into preprocessor statements. You could, however, put it into an inline function. That defeats the C tag, though.

sbi
What good would putting it into an inline function do? Preprocessor directives are processed before anything that could recognise a function.
anon
C99 has `inline`, and most major C89 implementations have some variation.
Chris Lutz
@Chris Assuming your comment was directed at me - your point is - what?
anon
@Neil - No, sorry. I was directing it at @sbi's last sentence.
Chris Lutz
@Neil: I have no idea what that pragma is supposed to do.
sbi
@Chris: Ah, so `inline` is yet another thing C borrowed from C++! `:)`
sbi
+1  A: 

No, there is no portable way of doing that. Then again, there are no portable ways to use #pragma at all. Because of this, many C/C++ compilers define their own methods for doing pragma-like things, and they often can be embedded in macros, but you need a different macro definition on every compiler. If you are willing to go that route, you often end up doing stuff like this:

#if defined(COMPILER_GCC)
#define Weak_b
#define Weak_e __attribute__((weak))
#elif defined(COMPILER_FOO)
#define Weak_b __Is_Weak
#define Weak_e
#endif

#define DEFINE_DELETE_OBJECT(type)                      \
    Weak_b void delete_ ## type_(int handle) Weak_e;    \
    Weak_b void delete_ ## type(int handle)  Weak_e;    

In case its not obvious you want to define Weak_b and Weak_e as begin-and-end bracketing constructs because some compilers like GCC add the attributes as an addendum to a type signature, and some, like MSC add it as a prefix (or at least it did once, its been years since I've used MSC). Having bracketing contructs allows you to define something that always works, even if you have to pass the entire type signature into a compiler construct.

Of course, if you try porting this to a compiler without the attributes you want, there's nothing you can do but leave the macros expand to nothing and hope your code still runs. In case of purely warning or optimizing pragmas, this is likely. In other cases, not so much.

Oh, and I suspect you'd actually need to define Weak_b and Weak_e as macros that take parameters, but I wasn't willing to read through the docs for how to create a weak definition just for this example. I leave that as an exercise for the reader.

swestrup
+5  A: 

If you're using c99 or c++0x there is the pragma operator, used as

_Pragma("argument")

which is equivalent to

#pragma argument

except it can be used in macros (see section 6.10.9 of the c99 standard, or 16.9 of the c++0x final committee draft)

For example,

#define STRINGIFY(a) #a
#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type ## _(int handle);                  \
    void delete_ ## type(int handle);                   \
    _Pragma( STRINGIFY( weak delete_ ## type ## _ = delete_ ## type) )
DEFINE_DELETE_OBJECT(foo);

when put into gcc -E gives

void delete_foo_(int handle); void delete_foo(int handle);
#pragma weak delete_foo_ = delete_foo
 ;
Scott Wales
As an FYI: MSVC has the `__pragma()` preprocessor operator, which unfortunately is slightly different from C99's `_Pragma()` operator (C99's takes a string literal, MSVC's takes tokens that aren't in a string): http://msdn.microsoft.com/en-us/library/d9x1s805.aspx
Michael Burr