【发布时间】:2012-05-09 14:52:42
【问题描述】:
我有这个不透明的类型 type_t 和一个像 foo(type_t *t) 和被调用者这样的函数原型:
int bar(void)
{
type_t t;
foo(&t);
return 0;
}
我想将函数原型从 foo(type_t *t) 更改为 foo(const type_t *t)。
不幸的是type_t被定义为一个数组,例如typedef char type_t[16]) ...
所以用&t参数调用函数foo会使编译器产生警告。
首先,foo 函数应该有一个原型,例如foo(type_t t),并用foo(t) 调用。在这种情况下,我希望 数组衰减到指针 规则也允许foo(&t),但它不适用于& 运算符。如果foo 写成foo(void *t),这可能会起作用
注意:详细示例可以跳过,见文末
所以我写了这个小测试程序来重现警告/错误https://gist.github.com/2644970
GCC 版本 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1) 正在产生这些警告:
array.c: In function ‘test_array_pointer’:
array.c:36: warning: return makes integer from pointer without a cast
array.c: In function ‘test_const_array_pointer’:
array.c:59: warning: return makes integer from pointer without a cast
array.c: In function ‘main’:
array.c:132: warning: passing argument 1 of ‘test_array_pointer’ from incompatible pointer type
array.c:18: note: expected ‘uint8_t (*)[16]’ but argument is of type ‘uint8_t *’
array.c:134: warning: passing argument 1 of ‘test_const_array_pointer’ from incompatible pointer type
array.c:41: note: expected ‘const uint8_t (*)[16]’ but argument is of type ‘uint8_t (*)[16]’
array.c:135: warning: passing argument 1 of ‘test_const_array_pointer’ from incompatible pointer type
array.c:41: note: expected ‘const uint8_t (*)[16]’ but argument is of type ‘uint8_t *’
array.c:137: warning: passing argument 1 of ‘test_array’ from incompatible pointer type
array.c:64: note: expected ‘uint8_t *’ but argument is of type ‘uint8_t (*)[16]’
array.c:140: warning: passing argument 1 of ‘test_const_array’ from incompatible pointer type
array.c:82: note: expected ‘const uint8_t *’ but argument is of type ‘uint8_t (*)[16]’
array.c:143: warning: passing argument 1 of ‘test_const_pointer’ from incompatible pointer type
array.c:100: note: expected ‘const uint8_t *’ but argument is of type ‘uint8_t (*)[16]’
虽然 LLVM/Clang 版本 1.1 (branches/release_27) 正在生成这些:
array.c:36:10: warning: incompatible pointer to integer conversion returning 'array_t' (aka 'uint8_t [16]'), expected 'uintptr_t' (aka 'unsigned int') [-pedantic]
return a[0]; /* warning: return makes integer from pointer without a cast */
^~~~
array.c:59:10: warning: incompatible pointer to integer conversion returning 'array_t const' (aka 'uint8_t const[16]'), expected 'uintptr_t' (aka 'unsigned int') [-pedantic]
return a[0]; /* warning: return makes integer from pointer without a cast */
^~~~
array.c:132:3: warning: incompatible pointer types passing 'array_t' (aka 'uint8_t [16]'), expected 'array_t *' [-pedantic]
TEST(array_pointer, a);
^~~~~~~~~~~~~~~~~~~~~~
array.c:132:23: note: instantiated from:
TEST(array_pointer, a);
^
array.c:134:3: warning: incompatible pointer types passing 'array_t *', expected 'array_t const *' [-pedantic]
TEST(const_array_pointer, &a);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
array.c:134:29: note: instantiated from:
TEST(const_array_pointer, &a);
^~
array.c:135:3: warning: incompatible pointer types passing 'array_t' (aka 'uint8_t [16]'), expected 'array_t const *' [-pedantic]
TEST(const_array_pointer, a);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
array.c:135:29: note: instantiated from:
TEST(const_array_pointer, a);
^
array.c:137:3: warning: incompatible pointer types passing 'array_t *', expected 'uint8_t *' [-pedantic]
TEST(array, &a);
^~~~~~~~~~~~~~~
array.c:137:15: note: instantiated from:
TEST(array, &a);
^~
array.c:140:3: warning: incompatible pointer types passing 'array_t *', expected 'uint8_t const *' [-pedantic]
TEST(const_array, &a);
^~~~~~~~~~~~~~~~~~~~~
array.c:140:21: note: instantiated from:
TEST(const_array, &a);
^~
array.c:143:3: warning: incompatible pointer types passing 'array_t *', expected 'uint8_t const *' [-pedantic]
TEST(const_pointer, &a);
^~~~~~~~~~~~~~~~~~~~~~~
array.c:143:23: note: instantiated from:
TEST(const_pointer, &a);
^~
8 diagnostics generated.
注意:精简版
请看最后一个例子:
typedef char array_t[16];
static int
test_const_array_pointer(const array_t *a)
{
return 0;
}
int
main(void)
{
array_t a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf };
const array_t b = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf };
test_const_array_pointer(&a); /* warning: passing argument 1 of ‘test_const_array_pointer’ from incompatible pointer type
note: expected ‘const char (*)[16]’ but argument is of type ‘char (*)[16]’ */
test_const_array_pointer(a); /* warning: passing argument 1 of ‘test_const_array_pointer’ from incompatible pointer type
note: expected ‘const char (*)[16]’ but argument is of type ‘char *’ */
test_const_array_pointer(&b); /* OK */
test_const_array_pointer(b); /* warning: passing argument 1 of ‘test_const_array_pointer’ from incompatible pointer type
note: expected ‘const char (*)[16]’ but argument is of type ‘const char *’ */
return 0;
}
我认为 &a 将等同于 &b。例如,当函数具有原型 foo(const char *) 时,没有必要给出 const char *,例如通过char * 被接受。
所以我的问题是为什么像const array_t * 这样的参数需要一个指向const 数组的指针? (将不胜感激指向 C11 草案部分的指针)。
【问题讨论】:
-
+1 用于创建测试用例,但是否可以将其缩减为更短的测试用例(例如,只是导致编译器错误的第一个示例)并将其直接粘贴到您的问题中?
标签: c arrays pointers constants