RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 810620
Accepted
eanmos
eanmos
Asked:2020-04-07 00:01:12 +0000 UTC2020-04-07 00:01:12 +0000 UTC 2020-04-07 00:01:12 +0000 UTC

使用 _Generic 时的类型不匹配警告

  • 772

_Generic从C11处理,我写了一个简单的例子:

#include <stdio.h>

#define swap(a, b) _Generic((a), \
    int*: swap_int(a, b), \
    float*: swap_float(a, b) \
)

void swap_int(int* a, int* b) {
    int tmp = *a; *a = *b; *b = tmp;
}

void swap_float(float* a, float* b) {
    float tmp = *a; *a = *b; *b = tmp;
}

int main(int argc, char const *argv[]) {
    int a = 10, b = 40;
    float c = 3.14, d = 2.71;

    printf("a = %d    b = %d\n", a, b);
    swap(&a, &b);
    printf("a = %d    b = %d\n\n", a, b);

    printf("c = %.2f  d = %.2f\n", c, d);
    swap(&c, &d);
    printf("c = %.2f  d = %.2f\n", c, d);
}

程序运行正常,但编译时出现类型不匹配警告:

temp.c: In function 'main':
temp.c:819:10: warning: passing argument 1 of 'swap_float' from incompatible pointer type [-Wincompatible-pointer-types]
     swap(&a, &b);
          ^
temp.c:799:24: note: in definition of macro 'swap'
     float*: swap_float(a, b) \
                        ^
temp.c:808:6: note: expected 'float *' but argument is of type 'int *'
 void swap_float(float* a, float* b) {
      ^~~~~~~~~~
temp.c:819:14: warning: passing argument 2 of 'swap_float' from incompatible pointer type [-Wincompatible-pointer-types]
     swap(&a, &b);
              ^
temp.c:799:27: note: in definition of macro 'swap'
     float*: swap_float(a, b) \
                           ^
temp.c:808:6: note: expected 'float *' but argument is of type 'int *'
 void swap_float(float* a, float* b) {
      ^~~~~~~~~~
temp.c:823:10: warning: passing argument 1 of 'swap_int' from incompatible pointer type [-Wincompatible-pointer-types]
     swap(&c, &d);
          ^
temp.c:798:20: note: in definition of macro 'swap'
     int*: swap_int(a, b), \
                    ^
temp.c:802:6: note: expected 'int *' but argument is of type 'float *'
 void swap_int(int* a, int* b) {
      ^~~~~~~~
temp.c:823:14: warning: passing argument 2 of 'swap_int' from incompatible pointer type [-Wincompatible-pointer-types]
     swap(&c, &d);
              ^
temp.c:798:23: note: in definition of macro 'swap'
     int*: swap_int(a, b), \
                       ^
temp.c:802:6: note: expected 'int *' but argument is of type 'float *'
 void swap_int(int* a, int* b) {

如何删除它们?

编译器:gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)

c
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Fat-Zer
    2020-04-07T02:10:57Z2020-04-07T02:10:57Z

    在这种情况下,您只需稍微更改宏的语法:

    #define swap(a, b) _Generic((a), \
        int*: swap_int, \
        double*: swap_double, \
        float*: swap_float \
    )((a),(b))
    

    也许有更好的解决方案。我_Generic还没有深挖...

    更新: 以下是我的观点和思考。

    这实际上是标准的重写示例。我或多或少可以回答“它是如何工作的”这个问题:_Generic表达式实际上“有一个值”指向相应函数的指针,然后用参数а和b. 但是这种方法有局限性:例如,如果swap_int它是一个宏或者如果其中一个函数有其他元素,它将不起作用。

    考虑到这一点,原始版本更加灵活。推测一下,我也可以解释为什么 gcc 实现在处理它时会出现警告:实际上,表达式存在于文本中,并且在扩展之前检查指针的正确性_Generic。但是,我在代码中没有看到任何犯罪行为,恕我直言,它们是误报,因此值得在知识渊博的人居住的地方讨论这个示例,例如在 gcc 邮件列表或 bugzilla 中。

    此外,为了抑制警告,您可以使用 hack:将指针显式转换为所需类型或(void*).

    #define swap(a, b) _Generic((a), \
        int*:    swap_int    ((void*)a, (void*)b), \
        double*: swap_double ((void*)a, (void*)b), \
        float*:  swap_float  ((void*)a, (void*)b)  \
    )
    
    • 3

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5