Incompatible pointer types passing in _Generic macro

不打扰是莪最后的温柔 提交于 2019-11-26 22:58:32

This is not a bug in clang, but unfortunately what the C11 standard requires. All branches of a _Generic primary expression must be a valid expressions, and thus valid under all circumstances. The fact that only one of the branches will ever be evaluated, is not related to this.

Your alternative version is what C11 foresees for situations as this: chose the function (and not the evaluated call) as a result of the type generic expression, and apply that function to the arguments.

Keith Thompson

CORRECTION : This is not (as far as I can tell) a bug in clang, but a correct interpretation of how _Generic is supposed to behave. Only one of the generic associations in a generic-selection expression is evaluated, but all of them must be valid expressions. (_Generic does not act like a macro.)

See Jens Gustedt's answer.


This definitely looks like a bug in clang. I'm reasonably sure your code is valid C11. I see the same thing with version 3.4 on Linux Mint.

I've put together a slightly simplified demo :

#include <stdio.h>

static void print_i(int i)   { puts("int"); }
static void print_ip(int *i) { puts("int*"); }

#define print(num) _Generic((num), \
    int    : print_i(num),         \
    int*   : print_ip(num))

int main(void) {
    int i = 10;
    print(i);
    print(&i);
}

The output is correct, but I get the following warnings:

c.c:12:11: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'int *'; take the address with & [-Wint-conversion]
    print(i);
          ^
          &
c.c:8:23: note: expanded from macro 'print'
    int*   : print_ip(num))
                      ^
c.c:4:27: note: passing argument to parameter 'i' here
static void print_ip(int *i) { puts("int*"); }
                          ^
c.c:13:11: warning: incompatible pointer to integer conversion passing 'int *' to parameter of type 'int'; remove & [-Wint-conversion]
    print(&i);
          ^~
c.c:7:22: note: expanded from macro 'print'
    int    : print_i(num),         \
                     ^
c.c:3:25: note: passing argument to parameter 'i' here
static void print_i(int i)   { puts("int"); }
                        ^
2 warnings generated.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!