Not with standard macros, no. The C standard (C11) has a specific requirement for macros in 6.10.3 Macro replacement
:
# define identifier replacement-list new-line
with identifier
being explicitly defined in 6.4.2.1 Identifiers, General
as:
identifier:
identifier-nondigit
identifier identifier-nondigit
identifier digit
identifier-nondigit:
nondigit
universal-character-name
other implementation-defined characters
nondigit: one of
_ a b c d e f g h i j k l m
n o p q r s t u v w x y z
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z
digit: one of
0 1 2 3 4 5 6 7 8 9
So the only *possible loophole would be other implementation-defined characters
but that's not covered by the standard, hence not really portable.
In any case, it wouldn't work very well with code like:
typedef struct {
int field1;
int field2;
} tMyStruct;
since it would rather annoyingly place a C statement where no statements should ever exist :-)
I think if you really want to do this, you're going to have pre-process your file with a more intelligent pre-processor (one that can tell where and where not the code should go), or modify the code to explicitly put in a macro where they should be, such as selecting behaviour with:
#ifdef PING_DEBUGGING
#define MYPING printf("%s,%s", _FUNCTION_, _LINE_)
#else
#define MY_PING
#endif
and using it with:
void myFunc(void) { MYPING;
// proper body of function.
}