开发者

Can I substitute __func__ into an identifier name in a C macro?

I'd like to write a C macro which takes this:

int foo() {
  MY_MACRO
}

and expands it to this:

int foo() {
  _macro_var_foo++;
}

I've found th开发者_如何学Goat I can't use __func__, because that doesn't actually get expanded in the macro; it's treated by the preprocessor like a variable.

Is there some way to get this to work?


The preprocessor doesn't know about functions, just source files and line numbers. At that stage it's not performing syntactical analysis, just textual analysis and substitutions. That's why __func__ is a magical variable instead of a magical macro like __FILE__ and __LINE__.


In the C99 standard, __func__ is given a special new category of 'predefined identifier' (in section 6.4.2.2 Predefined Identifiers):

The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration

    static const char __func__[] = "function-name";

appeared, where function-name is the name of the lexically-enclosing function

This means that it is out of the scope of the C preprocessor, which is not aware of function boundaries or function names. Further, it would expand to a string, which makes it inappropriate for embedding into a variable name.


The GCC (4.4.1) manual says in section 5.43 (Function Names as Strings):

These identifiers [meaning __func__, __FUNCTION__ and __PRETTY_FUNCTION__] are not preprocessor macros. In GCC 3.3 and earlier, in C only, __FUNCTION__ and __PRETTY_FUNCTION__ were treated as string literals; they could be used to initialize char arrays, and they could be concatenated with other string literals. GCC 3.4 and later treat them as variables, like __func__. In C++, __FUNCTION__ and __PRETTY_FUNCTION__ have always been variables.

If there was a way to get the function name into a preprocessor cleanly, then it is probable that the documentation here would have cross-referenced it, if it did not define it.


Technically, the answer to your question is "yes", there is "some way". But I think you already knew that, and it's true that you cannot deal with this at the macro preprocessor level.

Sure, there is always a way, you just might need a really long tape on that Turing Machine.

I think you already know this, but for the record you can get the overall result you want with:

#define MY_MACRO f_dictionary(__func__, ADDONE);

So now, you just need to implement f_dictionary and an ADDONE op for it.


You can do this using token concatenation.

#define MY_MACRO(baz) _macro_var_##baz++;

#define FUNC_WRAPPER(bar)\
int bar()\
{\
    MY_MACRO(bar)\
}

FUNC_WRAPPER(foo)

The output from gcc -E:

int foo(){ _macro_var_foo++;}

Version dealing with argument lists using variadic macros and x macros:

#define MY_MACRO(baz) _macro_var_##baz++;

#define FUNC_DEF(ret_type,bar,...)\
ret_type bar(__VA_ARGS__)\
{\
    MY_MACRO(bar)\
    FUNC_CONTENTS\
}

#define FUNC_CONTENTS\
    printf("Do some stuff\n", s1, s2);
FUNC_DEF(int, foo, char *s1, char *s2)
#undef FUNC_CONTENT
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜