gpt4 book ai didi

c - 如何使宏返回字符而不是字符串?

转载 作者:行者123 更新时间:2023-11-30 17:22:38 25 4
gpt4 key购买 nike

我有以下宏(后续: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 * 而不是简单地将 "%lu" 替换为 "必需:%s != %s,现实:%s == "mu_format_specifier(actual), 我想产生 "必需:%s != %s,现实:%s == ""%lu" C 会将其理解为一个文字字符串。

我可以看到两个可怕的解决方法:

  1. 为每种类型创建一个版本的 mu_assert_equal,并使用 _Generic 调用正确的版本。

  2. snprintf 格式字符串,但如果格式字符串必须为 const,我可能会遇到问题。

有更好的选择吗?

(问题是 _Generic 实际上评估一个表达式,而不是简单地替换源字符 - 即 "%lu" 变成它自己的文字字符串,而不仅仅是生成与“必需:%s != %s,现实:%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 的输出表达式

来自测试代码:

mu_assert_equal(bytes_parsed, 1);

我得到输出:

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

关于c - 如何使宏返回字符而不是字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27981317/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com