How to make a char string from a C macro’s value?

He who is Shy* gave you the germ of an answer, but only the germ. The basic technique for converting a value into a string in the C pre-processor is indeed via the ‘#’ operator, but a simple transliteration of the proposed solution gets a compilation error:

#define TEST_FUNC test_func
#define TEST_FUNC_NAME #TEST_FUNC

#include <stdio.h>
int main(void)
{
    puts(TEST_FUNC_NAME);
    return(0);
}

The syntax error is on the ‘puts()’ line – the problem is a ‘stray #’ in the source.

In section 6.10.3.2 of the C standard, ‘The # operator’, it says:

Each # preprocessing token in the
replacement list for a function-like
macro shall be followed by a parameter
as the next preprocessing token in the
replacement list.

The trouble is that you can convert macro arguments to strings — but you can’t convert random items that are not macro arguments.

So, to achieve the effect you are after, you most certainly have to do some extra work.

#define FUNCTION_NAME(name) #name
#define TEST_FUNC_NAME  FUNCTION_NAME(test_func)

#include <stdio.h>

int main(void)
{
    puts(TEST_FUNC_NAME);
    return(0);
}

I’m not completely clear on how you plan to use the macros, and how you plan to avoid repetition altogether. This slightly more elaborate example might be more informative. The use of a macro equivalent to STR_VALUE is an idiom that is necessary to get the desired result.

#define STR_VALUE(arg)      #arg
#define FUNCTION_NAME(name) STR_VALUE(name)

#define TEST_FUNC      test_func
#define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC)

#include <stdio.h>

static void TEST_FUNC(void)
{
    printf("In function %s\n", TEST_FUNC_NAME);
}

int main(void)
{
    puts(TEST_FUNC_NAME);
    TEST_FUNC();
    return(0);
}

* At the time when this answer was first written, shoosh‘s name used ‘Shy’ as part of the name.

Leave a Comment