When writing a macro in C, how do I find the type

2020-06-29 06:11发布

I want to extend minunit to be more useful, with the macro.

#define mu_assert_equal(actual, expected) do {                                            \
  if (actual != expected) {                                                               \
    char *message = malloc(MAX_ERROR_MESSAGE_LENGTH);                                     \
    if (message == NULL) { printf("malloc failed"); exit(1); }                            \
    snprintf(message, MAX_ERROR_MESSAGE_LENGTH, "required: %s != %s, reality: %s == %lu", \
    #actual, #expected, #actual, actual);                                                 \
    return message;                                                                       \
  }                                                                                       \
} while (0)

invoked with:

mu_assert_equal(bytes_parsed, 1);

but the macro above only works for unsigned long values.

How I can I find the type of the macro arguments, and more importantly, their printf specifiers.

2条回答
ゆ 、 Hurt°
2楼-- · 2020-06-29 06:34

Without generics, perhaps the best would be different macros for your different types:

#define mu_assert_equal(actual, expected, test, fmt) do {                                 \
  if ( test ) {                                                                           \
    char *message = malloc(MAX_ERROR_MESSAGE_LENGTH);                                     \
    if (message == NULL) { printf("malloc failed"); exit(1); }                            \
    snprintf(message, MAX_ERROR_MESSAGE_LENGTH, "required: %s != %s, reality: %s == " fmt,\
    #actual, #expected, #actual, actual);                                                 \
    return message;                                                                       \
  }                                                                                       \
} while (0)

#define mu_assert_equal_int(actual, expected) \
        mu_assert_equal(actual, expected, actual != expected, "%lu")
#define mu_assert_equal_str(actual, expected) \
        mu_assert_equal(actual, expected, strcmp( actual, expected ), "%s")

and invoke as:

mu_assert_equal_str( test_str, "abcde" ) ;
mu_assert_equal_int( test_int, 12345 ) ;

(Edited in light of comment to also pass the test to the "generic" test).

查看更多
甜甜的少女心
3楼-- · 2020-06-29 06:55

You can't, in C before C11 (which adds generics).

There's no way to compute the type of an expression in C, which is what you would need to do. If it were possible, then printf() wouldn't need to have static specifiers in the first place, more or less.

查看更多
登录 后发表回答