C函数常量多维数组参数怪警告 [英] C function const multidimensional-array argument strange warning

查看:239
本文介绍了C函数常量多维数组参数怪警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Ehllo,

我收到一些奇怪的警告,这个code:

I'm getting some strange warning about this code:

typedef double mat4[4][4];

void mprod4(mat4 r, const mat4 a, const mat4 b)
{
/* yes, function is empty */
}

int main()
{
    mat4 mr, ma, mb;
    mprod4(mr, ma, mb);
}

GCC输出如下:

gcc output as follows:

$ gcc -o test test.c
test.c: In function 'main':
test.c:13: warning: passing argument 2 of 'mprod4' from incompatible pointer
type
test.c:4: note: expected 'const double (*)[4]' but argument is of type 'double
(*)[4]'
test.c:13: warning: passing argument 3 of 'mprod4' from incompatible pointer
type
test.c:4:
note: expected 'const double (*)[4]' but argument is of type 'double
(*)[4]'

定义函数为:

void mprod4(mat4 r, mat4 a, mat4 b)
{
}

或主定义为矩阵:

mat4 mr;
const mat4 ma;
const mat4 mb;

或调用,在格兰功能主要为:

OR calling teh function in main as:

mprod4(mr, (const double(*)[4])ma, (const double(*)[4])mb);

甚至定义为mat4:

OR even defining mat4 as:

typedef double mat4[16];

让德警告消失。吴哥窟是怎么回事?我做得无效?

make teh warning go away. Wat is happening here? Am I doing something invalid?

gcc版本4.4.3是如果相关的。

gcc version is 4.4.3 if relevant.

我也张贴在GCC的Bugzilla: http://gcc.gnu.org /bugzilla/show_bug.cgi?id=47143

I also posted on gcc bugzilla: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47143

我目前的解决方法包括在制造丑陋的宏投的东西对我来说:

My current workaround consist in making ugly macros that cast stuff for me:

#ifndef _NO_UGLY_MATRIX_MACROS

#define mprod4(r, a, b) mprod4(r, (const double(*)[4])a, (const double(*)[4])b)

#endif

谢谢您的关注。

从约瑟夫·迈尔斯回答GCC的Bugzilla:

Answer from Joseph S. Myers on gcc bugzilla:

不是一个错误。功能参数
  有类型的指针数组[4]的
  常量双,因为常量上
  数组类型适用于元素
  型,递归,然后
  最外层数组类型,只是,一
  阵列型的参数衰变到一个
  指针,传递的参数是
  类型的指针数组[4]的
  双后的阵列到指针衰减,
  并在预选赛是唯一的情况下,
  获准在分配以复加,
  参数传递等,是预选赛上
  眼前的指针目标,不
  这些嵌套更深刻。

Not a bug. The function parameters are of type "pointer to array[4] of const double" because const on an array type applies to the element type, recursively, and then the outermost array type, only, of a parameter of array type decays to a pointer, and the arguments passed are of type "pointer to array[4] of double" after array-to-pointer decay, and the only case where qualifiers are permitted to be added in assignment, argument passing etc. is qualifiers on the immediate pointer target, not those nested more deeply.

听起来pretty混乱给我,声音liek函数需要:

Sounds pretty confusing to me, sounds liek function expects:

pointer to array[4] of const doubles

和我们传递

pointer to const array[4] of doubles

这一翻译。

或者这将是逆?德警告提示,德函数要求:

Or would it be the inverse? Teh warnings suggest that teh function expects a:

const double (*)[4]

这似乎是我moar liek一个

which seems to me moar liek a

pointer to const array[4] of doubles

我这个答案真的很困惑,别人谁能够理解他所说的话可以澄清和体现?

I'm really confused with this answer, somebody who can understand what he said could clarify and exemplify?

您的关注再次感谢

推荐答案

我相信这个问题是在指定的约束的 C99 6.5.16.1(1),这似乎禁止混合资格的任务,除了一个具有包容性,除了限定为其定义指针。问题是,与间接指针,就结束了一个指针传递到一件事的指针到另一个。分配是无效的,因为,如果是,你可以欺骗它变成修改const限定的对象,下面code:

I believe the problem is the constraints specified in C99 6.5.16.1(1), which seem to prohibit mixing qualifications in assignments, except for pointers for which an inclusive-qualifier exception is defined. The problem is that with indirect pointers, you end up passing a pointer to one thing to a pointer to another. The assignment isn't valid because, if it was, you could fool it into modifying a const-qualified object with the following code:

const char **cpp;
char *p;
const char c = 'A';
cpp = &p;  // constraint violation
*cpp = &c; // valid
*p = 0;    // valid by itself, but would clobber c

这似乎是合理的 CPP ,并承诺不修改任何字符 S,可能被分配一个指针在非限定字符指点下一个对象。毕竟,这是允许的单间接指针,这就是为什么,例如,你可以通过一个可变对象的第二个参数的strcpy(3),第一个参数和strchr(3),并声明与许多其他参数常量

It might seem reasonable that cpp, which promises not to modify any chars, might be assigned a pointer to an object pointing at non-qualified chars. After all, that's allowed for single-indirect pointers, which is why, e.g., you can pass a mutable object to the second parameter of strcpy(3), the first parameter to strchr(3), and many other parameters that are declared with const.

但与间接指针,在一个新的水平,从一个合格的指针赋值是允许的,而现在完全不合格的指针赋值会揍一个合格的对象。

But with the indirect pointer, at the next level, assignment from a qualified pointer is allowed, and now a perfectly unqualified pointer assignment will clobber a qualified object.

我没有立即看到一个二维数组如何导致这种情况,但在任何情况下,它击中标准相同的约束。

I don't immediately see how a 2-D array could lead to this situation, but in any case it hits the same constraint in the standard.

由于你的情况,你实际上并没有欺骗它变成弄错一个const,为正确的事情的的code似乎是插入投。

Since in your case, you aren't actually tricking it into clobbering a const, the right thing for your code would seem to be inserting the cast.

更新:确定的家伙,因为它发生这个问题的 在C常见问题解答 ,然后整个讨论也发生了几次 上GCC的bug列表 并gcc的邮件列表上。

Update: OK guys, as it happens this issue is in the C faq, and this entire discussion has also taken place several times on the gcc bug list and on the gcc mailing list.


  • 的gcc的bug列表: <一个href=\"http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20230\">http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20230.

  • Ç常见问题解答:这是问题11.10: <一个href=\"http://c-faq.com/ansi/constmismatch.html\">http://c-faq.com/ansi/constmismatch.html

的教训是:你可以传递一个 T * X const的T * X 预计,到明确的异常,但 T * X const的T * X 还是不同的类型,所以你不能传递一个指针任一方的指针的其它

The lesson: you can pass a T *x when const T *x is expected, by explicit exception, but T *x and const T *x are still distinct types, so you can't pass a pointer to either one to a pointer to the other.

这篇关于C函数常量多维数组参数怪警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆