dia*_*pir 8 c pointers const c99 variable-length-array
在此代码段中,指向VLA的指针用于更轻松地访问大型查找表:
#pragma GCC diagnostic warning "-Wcast-qual"
char
lookup(int a, int b, int c, char const *raw, int x, int y, int z)
{
typedef char const (*DATA_PTR)[a][b][c];
DATA_PTR data = (DATA_PTR)raw;
return (*data)[x][y][z];
}
Run Code Online (Sandbox Code Playgroud)
GCC 6.2.0扼杀它,而Clang 4.0.0(主干)编译得很好,两者都-Wcast-qual启用了.
In function 'lookup':
warning: cast discards 'const' qualifier from pointer target type [-Wcast-qual]
DATA_PTR data = (DATA_PTR)raw;
^
Run Code Online (Sandbox Code Playgroud)
代码按预期方式运行.
我的猜测是GCC混淆了"指向const元素的VLA的指针"和"指向const VLA的指针",但我达到了......
有没有办法在没有摆弄警告的情况下关闭GCC?这是GCC的错误吗?
EDIT1:
有关实际代码的详细信息:
struct table {
int a;
int b;
int c;
char *raw;
};
char
lookup2(struct table const *table, int x, int y, int z)
{
typedef char const(*DATA_PTR)[table->a][table->b][table->c];
DATA_PTR data;
data = (DATA_PTR)table->raw; // GCC ok
data = (DATA_PTR)(char const *)table->raw; // GCC raises -Wcast-qual
return (*data)[x][y][z];
}
Run Code Online (Sandbox Code Playgroud)
EDIT2:
所以它是...... C11标准草案在6.7.3/9中说:
如果数组类型的规范包含任何类型限定符,则元素类型是限定的,而不是数组类型.
见@hvd回答.
一个沉默的黑客-Wcast-qual:
DATA_PTR data = (DATA_PTR)(intptr_t)raw;
Run Code Online (Sandbox Code Playgroud)
小智 7
这是C中一个长期存在的问题.原因也是如此
int array[2];
const int (*ptr)[2] = &array;
Run Code Online (Sandbox Code Playgroud)
是无效的在C(但将在C++中有效):这声明一个指针数组const-qualified整数,这是不一个const整数-qualified阵列,所以正常规则的指针类型可以隐式转换到指向const该类型的限定版本的指针不适用.
在你的情况下,你将const char *(从指向一个const限定类型char const (*)[a][b][c]的指针)转换为(一个指向非const限定类型的指针),这-Wcast-qual应该是警告的.
clang从不打算实现C的这种特殊奇怪性,它用C++语义处理C代码,它说const元素数组本身也是const合格的.
您通常可以通过将数组包装在以下内容来解决它struct:
typedef struct { char d[a][b][c]; } const *DATA_PTR;
Run Code Online (Sandbox Code Playgroud)
但这不是VLA的选择.除了不使用多维数组或不使用多维数组之外,我不相信有合适的解决方法-Wcast-qual.
| 归档时间: |
|
| 查看次数: |
319 次 |
| 最近记录: |