在此片段中,使用指向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];
}
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;
^
代码按预期运行。
我的猜测是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];
}
EDIT2:
所以它是...... C11标准草案在6.7.3 / 9中说:
如果数组类型的规范包含任何类型限定符,则元素类型是限定的,而不是数组类型。
请参阅@hvd answer。
沉默-Wcast-qual
:
DATA_PTR data = (DATA_PTR)(intptr_t)raw;
答案 0 :(得分:7)
这是C中一个长期存在的问题。这与
的原因相同int array[2];
const int (*ptr)[2] = &array;
在C中无效(但在C ++中有效):这声明了一个指向const
数组的指针 - 合格的整数,不 a const
- 限定的整数数组,因此指向类型的指针可以隐式转换为指向const
的指针的正常规则 - 该类型的限定版本不适用。
在您的情况下,您将const char *
(指向const
- 限定类型的指针)转换为char const (*)[a][b][c]
(指向非const
的指针} -qualified type),-Wcast-qual
应警告。
clang从不打算实现C的这种特殊奇怪性,它用C ++语义处理C代码,它说const
元素的数组本身const
- 也是合格的。
您通常可以通过将数组包装在struct
中来解决它:
typedef struct { char d[a][b][c]; } const *DATA_PTR;
但这不是VLA的选项。除了不使用多维数组或不使用-Wcast-qual
之外,我不相信有合适的解决方法。