【问题标题】:Problems with const in c when having typedef and array [duplicate]具有 typedef 和数组时 c 中的 const 问题[重复]
【发布时间】:2016-05-04 13:36:23
【问题描述】:

我有以下代码:

typedef float vec3_t[3];

void f(const vec3_t v[2]){
    // do stuff
}

int main(int argc, char * argv[]){
    vec3_t v[2];
    v[2][1] = 1;
    f(v);
    return 0;
}

不会编译使用

gcc main.c -std=gnu99 -O0 -o main

但给出错误

main.c: In function ‘main’:'
main.c:293:5: warning: passing argument 1 of ‘f’ from incompatible pointer type [enabled by default]
     f(v);
     ^
main.c:286:6: note: expected ‘const float (*)[3]’ but argument is of type ‘float (*)[3]’
 void f(const vec3_t v[2]){
      ^

另一方面,如果我删除函数 f 中的 const 要求。这一切都很好。我想不通是怎么回事??

【问题讨论】:

  • 正如我的欺骗链接中提到的,这可能是 C 类型系统中的一个缺陷。我认为这突出了为什么在 typedef 后面隐藏指针或数组不是一个好主意。
  • 这不是完全重复的,因为链接的问题是关于数组指针的。在这种情况下,有二维数组。不过答案几乎是一样的。
  • 无论如何,我强烈建议不要将数组隐藏在 typedef 后面。如果您需要不同的类型,请将数组放在结构中。然后制作一个此类结构的数组。巧合的是,这也解决了这个问题。
  • @user694733:好的,但实际上这个问题并不是由 typedef 引起的。输入 float[3] 你会得到同样的编译器警告。

标签: c constants typedef


【解决方案1】:

为什么不将参数强制转换为 const?

typedef float vec3_t[3];

void f(const vec3_t v[2]){
    // do stuff
}

int main(int argc, char * argv[]){
    vec3_t v[2];
    v[2][1] = 1;
    f((const vec3_t*)v);
    return 0;
}

【讨论】:

  • 找演员不是个好主意。编译器抱怨是有原因的。除非您比编译器了解更多,否则简单的强制转换迟早会导致麻烦。
  • 通过 C11 _Generic 实现安全的“const cast”是链接副本中讨论的一种可能的解决方案,例如参见 chux 的答案。如果这是一个好主意,我不确定。但它是 100% 安全的,不像这里的原始演员。
猜你喜欢
  • 2015-09-15
  • 1970-01-01
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
相关资源
最近更新 更多