Home > Software design >  Evaluate/print function return that is used as input to macro
Evaluate/print function return that is used as input to macro

Time:11-12

I am trying to create a simple unit test library for my projects. I can get most things working, but now I am trying to add some functionality: printing the expressions/input.

It works if I pass arguments by actual value (1, 2.456, false), but if I pass a function argument I get the function string printed.

Here is my code explaining the problem I am not 100% sure what the STR(x) macro is doing, copied it from somewhere online...

The code actually works (the evaluation of LHS and RHS) just the printing does not, shown below.

#include <stdio.h>

#define STR(x) #x

#define TEST_COMPARE_EQ(TestName, LHS, RHS) \
do {                             \
    if ((LHS) != (RHS)) {              \
      printf("[Test: %s] --- Failed at line %d in file %s\n", TestName, __LINE__, __FILE__); \
      printf("\Got value %s\n", STR(LHS));                                       \
      printf("\Expected value      %s\n", STR(RHS));                                       \
    }                                        \
    else {                                   \
      printf("[Test: %s] --- Passed\n", TestName); \
    }\
  } while (0)

// Calling code example
// This works, prints: 
// Got value 123 
// Expected value 124
TEST_COMPARE_EQ("PrintingWorks", 123, 124);

// This however does not work. 
// It prints 
// Got value my_fn_that_returns_false
// Expected value true
// How can I get it to print the return value of my_fn_that_returns_false, and not
// the actual function name?
TEST_COMPARE_EQ("PrintingDoesNotWork", my_fn_that_returns_false(), true);

CodePudding user response:

what the STR(x) macro is doing,

It takes the code as it is and adds " in front and back. STR(anything) is "anything", just like that.

How can I get it to print the return value

You have to print it.

printf("Got value %d\n", LHS);

No, there are no templates in C. It is hard to write type generic functions in C. You have to handle each possible type separately - like TEST_COMPARE_EQ_INT TEST_COMPARE_EQ_FLOAT etc. For inspiration, take a look at Unity C unit testing library.

Writing that in a type-generic way sounds like a nice challenge in C. It would look basically like the following:

void test_eq_int(int a, const char *astr, int b, const char *btr) {
   if (a != b) {
      printf("%s = %s -> %d != %s\n", astr, bstr, a, b);
   }
}
void test_eq_long(....) { .... }
void test_eq_some_other_type(...) { .... }
// etc. for each possible type

#define TEST_COMPARE_EQ(msg, a, b) \
   _Generic(a, \
       int: test_eq_int, \
       long: test_eq_long, \
       /* etc. for each type */ \
    )(msg, a, #a, b, #b);
  •  Tags:  
  • c
  • Related