将_Generic与其他宏结合

时间:2020-10-13 19:13:59

标签: c

因此,我熟悉嵌套宏。 现在,我想更改一个由_Generic首先更改的宏以及其他一些宏,例如:

#include<stdio.h>

#define some_func(X) _Generic((X),  \
    char* : some_func_char,         \
    default : some_func_default)(X)

#define some_func_char(X) some_func_char(X, sizeof(X)/ sizeof(char))

void (some_func_char)(char *blah, size_t len_blah)
{
  // do something
}

void some_func_default(double blah)
{
  // code
}

int main()
{
  some_func("hello");
  return 0;
}

但它正在引发错误

main.c: In function ‘main’:
main.c:5:22: error: too few arguments to function ‘some_func_char’
    5 | #define some_func(X) _Generic((X),  \
      |                      ^~~~~~~~
main.c:22:3: note: in expansion of macro ‘some_func’
   22 |   some_func("hello");
      |   ^~~~~~~~~
main.c:10:7: note: declared here
   10 | void (some_func_char)(char *blah, size_t len_blah)
      |       ^~~~~~~~~~~~~~

2 个答案:

答案 0 :(得分:2)

some_func_char_Generic调用中正在调用函数而不是宏(即使试图用括号停止扩展),另一方面,您不能省略{{ 1}}如果some_func_default需要两个参数,请切换到:

some_func_char

或更妙的是:

#include <stdio.h>

#define some_func(X) _Generic((X),  \
    char *: some_func_char,         \
    default: some_func_default)(X, sizeof X)

void some_func_char(char *blah, size_t len_blah)
{
    // do something
}

void some_func_default(double blah, size_t dummy)
{
    (void)dummy;
    // code
}

int main()
{
    some_func("hello");
    return 0;
}

第二个版本允许您也为指向#include <stdio.h> #include <string.h> #define some_func(X) _Generic((X), \ char *: some_func_char, \ default: some_func_default)(X) void some_func_char(char *blah) { size_t len = strlen(blah); // do something } void some_func_default(double blah) { // code } int main() { some_func("hello"); return 0; } 的指针传递并计算正确的长度,不用担心性能,char非常快。

还要注意,strlen始终为1

答案 1 :(得分:1)

重要的是要理解,尽管泛型选择除与宏结合使用外并没有真正的用处,但预处理器本身并不能解释泛型选择。然后考虑以下语句:

  some_func("hello");

在示例代码中出现的地方,定义了some_func作为类函数宏的标识符,并且在重新扫描之前,该宏的扩展会产生该定义:

_Generic(("hello"), char *: some_func_char, default: some_func_default)("hello")

然后,预处理器将扫描该宏以进行进一步的宏替换,但是_Generic也不是宏,并且对预处理器没有其他特殊意义。在范围内定义some_func_char作为类函数宏的标识符,但是该标识符在上一行中的外观与之不匹配,因为它后面没有括号。在上下文中,该行中的其他任何内容都不重要,因此实际上是最终的预处理形式。

现在观察到表达式("hello")与通用选择表达式的char *匹配,因此函数标识符some_func_char是选择的结果,但括号参数列表{{1} }没有包含该函数的正确数量的参数。整体表达式是尝试调用("hello")时的更复杂的变化。 (some_func_char)("hello")宏永远不会起作用。

现在应该很清楚,您不能使用通用选择来选择带有不同数量参数的函数的函数标识符。但是您当然可以 使用它来选择不同的函数 calls 。例如,

some_func_char()
相关问题