C宏与运算符解释

3
我想知道操作符传递到宏中是如何工作的。它们是来自glib源代码(glib/testutils.h)的宏。
在代码中,您使用assert作为g_assert_cmpint(1, ==, 2);,所以运算符就直接传递了进去。它是如何工作的?在这个宏中,#代表什么意思?
#define g_assert_cmpint(n1, cmp, n2)                  \
  G_STMT_START {                                      \
    gint64 __n1 = (n1), __n2 = (n2);                  \
    if (__n1 cmp __n2) ;                              \
    else                                              \
      g_assertion_message_cmpnum(                     \
        G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC,  \
        #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); \
  } G_STMT_END

g_assert_message_cmpnum 具有以下接口:

void g_assertion_message_cmpnum(const char *domain, \
                                 const char *file,\
                                 int line,\
                                 const char func,\
                                 const char *expr,\
                                 long double arg1, \
                                 const char *cmp,\
                                 long double arg2,\
                                 char numtype);

这是否意味着 #cmp 运算符转换为字符串?

但是如何理解来自宏的这一行代码 #n1 " " #cmp " " #n2

2个回答

3
因为宏在编译时(预处理阶段)被处理,所以它只是用传递的运算符“替换”了cmp。 使用“宏”是不安全的,因为它不执行类型检查。
下面是示例:
#define DOUBLE(x) x << 1 /// shift 1 bit left = multiple by 2

cout << DOUBLE(5) << endl; /// result "51" instead of "10" 
/// because the result of processed code is:
cout << 5 << 1 << endl;

5
OP在C语言中使用coutendl可能会遇到困难。(我同意你回答的其他部分) - David C. Rankin
1
这不是一个答案。 - Jens Gustedt

1

是的,在预处理器中#被称为“字符串化”。

然后,在预处理后的后续阶段,所有相邻的字符串字面值都会合并成一个大字符串。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接