Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从不兼容的指针类型(常量与非常量)返回。C/GCC_C_Gcc - Fatal编程技术网

从不兼容的指针类型(常量与非常量)返回。C/GCC

从不兼容的指针类型(常量与非常量)返回。C/GCC,c,gcc,C,Gcc,我有以下代码: typedef uint8_t array_t[8]; static array_t _my_array; static const array_t * foo(void) { return &_my_array; // <-- return from incompatible pointer type } 也可以工作,即编译时带有相同的警告。问题在于常量;函数返回常量数组*(指向常量数组的指针),但返回的表达式和

我有以下代码:

typedef uint8_t array_t[8];
static array_t _my_array;
static const array_t * foo(void) {
    return &_my_array; // <-- return from incompatible pointer type
}   

也可以工作,即编译时带有相同的警告。

问题在于
常量
;函数返回
常量数组*
(指向常量数组的指针),但返回的表达式
,属于
数组*
类型,两种类型不兼容

最简单的修复方法是从返回类型中删除
常量

typedef uint8_t array_t[8];
static array_t _my_array;
static array_t * foo(void) {
    return &_my_array;
}
编辑

我很犹豫是否要提出一个编译器错误,但我已经提出了一个测试程序,我认为它表明了gcc中的错误或者C标准中一个非常模糊的方面

typedef int this_type;
typedef int that_type[8];

static this_type this;
static that_type that;

static const this_type *this_func(void) {
    return &this;
}

static const that_type *that_func(void) {
    return &that;
}
当我用
gcc-c-std=c99-pedanticerrors c.c
(gcc 4.5.2)编译这个时,我得到:

为什么它会抱怨从
那个类型*
常数那个类型*
的隐式转换,而不是从
这个类型*
常数这个类型*
的转换

由于
that_type
是typedef,它是数组类型的别名,
that_type*
是指向数组的指针(而不是指向数组元素的指针);据我所知,没有数组到指针的转换。我不认为
this\u type
是整数类型而
是数组类型这一事实会有任何区别

另一个数据点是:在Solaris 9上,
cc-c-Xc.c
没有抱怨

从逻辑上讲,将指向foo的指针转换为指向const foo的指针应该是安全的;它不会产生任何违反const正确性的机会

如果我是对的,那么问题中的代码是有效的,gcc的警告是不正确的,您可以通过在函数定义上删除
常量来解决它(使其返回
数组*
而不是
常量数组*
,或者通过在return语句上添加强制转换:

return (const array_t*)&_my_array;
如果我错了,我希望不久会有人指出这一点

(我使用<代码>这个<代码>,C++关键字,作为一个标识符,有点深思熟虑。这是一个C问题。我理解C++在这个领域有稍微不同的规则。) EDIT2: 我刚刚提交了一份报告

EDIT3: Joseph S.Myers回应了我的错误报告:

这不是错误。您可以隐式地将“指向int的指针”转换为 “指向常量int的指针”,但不是“指向int数组的指针”指向“指针” 到常量int数组”(见6.5.16.1)和“const that_type*”为 “指向常量int数组的指针”(没有“指向 int的const数组”,这将是此类 转换;见6.7.3#8)

这不是错误。您可以隐式地将“指向int的指针”转换为 “指向常量int的指针”,但不是“指向int数组的指针”指向“指针” 到常量int数组”(见6.5.16.1)和“const that_type*”为 “指向常量int数组的指针”(没有“指向 int的const数组”,这将是此类 转换;见6.7.3#8)


这与您的问题无关,但使用标识符
\u my_array
是不明智的。C99 7.1.3:“所有以下划线开头的标识符始终保留在普通和标记名称空间中用作具有文件范围的标识符。”
static array\u t\u my\u array
文件范围不是很广吗?是的,这就是问题所在。这些标识符是为实现保留的;您不允许自己使用它们。在同一节的后面:“如果程序在保留的上下文中声明或定义标识符[…],则行为是未定义的。”允许实现(编译器或预定义头)声明其自己的名为“_my_array”的文件作用域实体。最新的C99草案是.clang,但它也不满意。
警告:不兼容的指针类型从结果类型为“that_type const*”(又称“int const(*)[8]”的函数返回“that_type*”(又名“int const(*)[8]”的函数)
我认为clang试图与gcc兼容。可能他们只是复制了这个错误。我们将看看gcc维护人员如何回应我的错误报告。@Keith。请发布一个引用Joseph回应的答案,然后我就可以接受了。gcc 5和clang 3.7都没有对此抱怨。
c.c: In function ‘that_func’:
c.c:12:5: error: return from incompatible pointer type
return (const array_t*)&_my_array;