如何使宏返回字符,而不是一个字符串? [英] How to make a macro return characters rather than a string?

查看:108
本文介绍了如何使宏返回字符,而不是一个字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的宏(后续:<一href=\"http://stackoverflow.com/questions/27980354/when-writing-a-macro-in-c-how-do-i-find-the-type-and-printf-specifier-for-an-ar\">When C语言编写的宏,我怎么找到一个参数的类型和printf说明):

I have the following macros (follow up to: When writing a macro in C, how do I find the type and printf specifier for an argument? ):

#define mu_format_specifier(expression) _Generic((expression), unsigned long: "%lu", int: "%i")

#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 == " mu_format_specifier(actual),                            \
      #actual, #expected, #actual, actual);                                                         \
    return message;                                                                                 \
  }                                                                                                 \
} while (0)

问题是,mu_format_specifier的看起来的解析为的char * 而不是简单地替换%录 要求:%s =%s的,现实是:找到%s ==mu_format_specifier(实际),我想得要求:%s =%s的,现实是:%s的==%lu个这ç会理解为一个文本字符串

The problem is that the mu_format_specifier seems to resolve to a char * rather than simply substituting "%lu" into "required: %s != %s, reality: %s == " mu_format_specifier(actual), which I would like to yield "required: %s != %s, reality: %s == " "%lu" which C would understand as one literal string.

我可以看到两个可怕的变通:

I can see two horrible work arounds:


  1. 为每个类型的一个版本mu_assert_equal的版本,并调用正确的用 _Generic

snprintf的格式化字符串,虽然我可能会遇到问题,如果格式化字符串必须是常量

snprintf the formatting string, though I may run into problems if the formatting string has to be const.

有没有更好的选择?

(问题是, _Generic 实际计算一个前pression,而不是简单的替代来源人物 - 即%录 成为它自己的文本字符串,而不是只生产这是统一与源字符要求:找到%s =%s的,现实是:%s的==

(The problem is that _Generic actually evaluates an expression, rather than simply substituting source characters - i.e. the "%lu" becomes it's own literal string, rather than just producing source characters which are unified with "required: %s != %s, reality: %s == ".)

推荐答案

我做了工作:

#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, _Generic(                                 \
        (actual),                                                                         \
        unsigned long: "required: %s != %s, reality: %s == %lu",                          \
        int:           "required: %s != %s, reality: %s == %i"                            \
      ),                                                                                  \
      #actual, #expected, #actual, actual);                                               \
    return message;                                                                       \
  }                                                                                       \
} while (0)

解决方案是使整个格式化字符串从 _Generic

从测试code:

mu_assert_equal(bytes_parsed, 1);

我得到的输出:

required: bytes_parsed != 1, reality: bytes_parsed == 0

这篇关于如何使宏返回字符,而不是一个字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆