Is it possible to replace __func__ with the name of an identifier in a C macro?

I would like to write a C macro that accepts this:

int foo() {
  MY_MACRO
}

      

and expands it like this:

int foo() {
  _macro_var_foo++;
}

      

I found I couldn't use __func__

it because it doesn't actually expand in a macro; it is processed as a variable by the preprocessor.

Is there a way to make this work?

+2


source to share


4 answers


The preprocessor doesn't know about functions, only source files and line numbers. At this point, it doesn't parse, just textual parsing and substitutions. This is why __func__

- a magic variable instead of a magic macro like __FILE__

and __LINE__

.



+3


source


The C99 standard __func__

provides a special new category of "predefined identifiers" (in section 6.4.2.2 "Predefined identifiers"):

The identifier __func__

must be implicitly declared by the translator, as if, immediately after opening the parenthesis of each function definition, the declaration

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

      

Appeared

where function-name is the name of the lexically closing function

This means that it is outside the scope of the C preprocessor, which does not know function boundaries or function names. Also, it will expand to a string, making it unacceptable for embedding in a variable name.




The GCC manual (4.4.1) says in section 5.43 (Function names as strings):

These identifiers [values __func__

, __FUNCTION__

and __PRETTY_FUNCTION__

] are not preprocessor macros. In GCC 3.3 and earlier, only in C, __FUNCTION__

and were __PRETTY_FUNCTION__

treated as string literals; they can be used to initialize char arrays and they can be concatenated with other string literals. NKU 3.4 and above treat them as variables, for example __func__

. In C ++, __FUNCTION__

and __PRETTY_FUNCTION__

have always been variables.

If there was a way to get the function name in the preprocessor cleanly, then the documentation here would probably be a cross-reference if it didn't define it.

+3


source


You can do this using a token connector .

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

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

FUNC_WRAPPER(foo)

      

Exiting gcc -E:

int foo(){ _macro_var_foo++;}

      

The version referring to argument lists using variable 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

      

+1


source


Technically, the answer to your question is "yes" is "in some way". But I think you already knew that, and it is true that you cannot handle it at the macro processor level.

Of course, there is always a way, you may need a very long tape on this Turing machine.

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

#define MY_MACRO f_dictionary(__func__, ADDONE);

      

So now you just need to implement f_dictionary

and ADDONE

op for it.

+1


source







All Articles