【问题标题】:Problem using const together with typedef and function pointer将 const 与 typedef 和函数指针一起使用时出现问题
【发布时间】:2020-11-07 22:51:54
【问题描述】:

这是一个 MRE

#include <string.h>

typedef char* mytype;

typedef int(*cmp)(const mytype, const mytype);

void foo(cmp f) {}

int main(void) {
    foo(strcmp);
}

当我编译时,我得到:

$ gcc mre.c -Wall -Wextra
mre.c: In function ‘foo’:
mre.c:7:14: warning: unused parameter ‘f’ [-Wunused-parameter]
    7 | void foo(cmp f) {}
      |          ~~~~^
mre.c: In function ‘main’:
mre.c:10:9: warning: passing argument 1 of ‘foo’ from incompatible pointer type [-Wincompatible-pointer-types]
   10 |     foo(strcmp);
      |         ^~~~~~
      |         |
      |         int (*)(const char *, const char *)
mre.c:7:14: note: expected ‘cmp’ {aka ‘int (*)(char * const,  char * const)’} but argument is of type ‘int (*)(const char *, const char *)’
    7 | void foo(cmp f) {}
      |          ~~~~^

第一个警告无关紧要。但是第二个我该怎么办?我尝试将 typedef 更改为:

typedef int(*cmp)(mytype const,mytype const);

但这给出了完全相同的结果。当我改为:

typedef int(*cmp)(const char*, const char*);

它起作用了,但出于显而易见的原因,这并不可取。另一件有效但也不可取的事情是:

typedef const char* mytype;

typedef int(*cmp)(mytype, mytype);

那么我在这里错过了什么?

我要解决的问题是我想创建一个通用结构,其中数据的类型为mytype。该结构的用户应实现比较功能,但我希望它与strcmp 一起工作,以防mytype 的类型为char*

请注意,mytype 不一定需要是指针。这取决于用户指定的数据类型。另外,我知道 typedefing 指针通常是不好的做法,但我认为这是一种特殊情况,因为我想 typedef 无论类型是什么,它可能是一个指针。

结构如下:

struct node {
    struct node *next;
    mytype data;
};

我设法用#define mytype char* 解决了这个问题,但感觉非常难看,如果有其他方法,我更愿意。我希望它是可移植的,所以我不想使用 gcc 扩展。

【问题讨论】:

  • 这能回答你的问题吗? typedef pointer const weirdness
  • mytype 的 typedef 应该是 typedef char mytype; 以便 mytype 实际上是一个类型,而不是一个指向类型的指针。那么函数的 typedef 是 typedef int (*cmp)(const mytype *, const mytype *);mytype 只是一个类型时,你可以完全控制装饰器的顺序。
  • 我想我会选择foo((cmp)strcmp);
  • 建议您检查 qsort() 函数的源代码,因为这需要用户编写比较函数。

标签: c pointers constants typedef


【解决方案1】:
typedef char* mytype;

mytype 是指向char 的指针。 const mytype 是指向 char 的 const 指针,而不是指向 const char 的指针。

不幸的是,在 C 语言中你不能使用 typedef 指针,而使用这个类型来声明指向 const 对象的指针。

你需要

typedef int(*cmp)(const char *, const char *);

void foo(cmp f) {}

int main(void) {
    foo(strcmp);
}

    foo((cmp)strcmp);

顺便说一句,将指针隐藏在 typedef 后面是一种非常糟糕的做法。

【讨论】:

  • 所以我想做的事情是不可能的?
  • 是的,不违反某些规定是不可能的。 cast 只隐藏了这个问题。但正如我所写的,不要 typedef 指针。
  • @klutt 是你想在 C 中发明 C++ 为什么你干脆不使用 C++。
  • 因为我打算用 C 写这个,而这个小特性是唯一让我停下来的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-18
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 2021-02-05
相关资源
最近更新 更多