Kluddizz
Kluddizz

Reputation: 723

Get the name of a function in C

I'm implementing a test library and I want to be able to print the test functions, which fail. Therefore I need a way to get the name of the failing function. I know there are predefined identifiers like __func__ and __FUNCTION__, but they only give me the name of the last executed function. I also don't want to use those identifiers inside the unit test functions, but in the procedure, which runs all the tests.

I posted an example, which uses an imaginary function called function_name. Is there any macro or something else available for this purpose?

/** Description
 *      This function calls a number of unit tests and print the results.
 *      Please note the imaginary function 'function_name'.
 * 
 *  Parameters:
 *      tests: Function pointers to unit tests
 *      number_tests: The number of tests to run
 */
void run_tests(unit_test* tests, unsigned int number_tests) {
    int number_passed = 0;

    for (unsigned int i = 0; i < number_tests; i++) {
        // Execute the unit test and get the result
        test_result result = (*tests[i])();

        if (result == TEST_PASSED)
            number_passed++;
        else
            printf("Test %s failed!\n", function_name(*tests[i]));
    }

    printf("%d/%d passed tests, %d failed tests\n", number_passed,
        number_tests, number_tests - number_passed);
}

Upvotes: 0

Views: 91

Answers (1)

Hilton Fernandes
Hilton Fernandes

Reputation: 660

Since you're using C, a good solution seems to lie in the use of the preprocessor, and in the use of a richer structure for the unit_test type. That is: instead of simply having a function pointer, it would contain also the function name, like:

struct _unit_test {
   int (*func)();
   char* func_name;
};
typedef struct _unit_test unit_test;

A macro like this would help it be populated

#define ptr_name(x) {x, #x}

And the initialization of the tests array could be

unit_tests tests[] = {ptr_name(func1), ptr_name(func2)};

You would have to change the following line of your code

test_result result = (*tests[i])();

to

test_result result = tests[i].func();

And the failed result line to

printf("Test %s failed!\n", tests[i].func_name);

Upvotes: 4

Related Questions