在这个片段中,使用指向VLA的指针来更容易地访问大型查找表:
代码无论哪种方式运行都符合预期。
我猜测GCC可能会混淆“指向VLA的常量元素的指针”和“指向常量VLA的指针”,但我不确定...
有没有一种方法可以让GCC保持安静而不用操心警告? 这是GCC的一个bug吗?
编辑1:实际代码的详细信息:
#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(trunk) 则可以正常编译,两者在启用 -Wcast-qual
选项时均可。
In function 'lookup':
warning: cast discards 'const' qualifier from pointer target type [-Wcast-qual]
DATA_PTR data = (DATA_PTR)raw;
^
代码无论哪种方式运行都符合预期。
我猜测GCC可能会混淆“指向VLA的常量元素的指针”和“指向常量VLA的指针”,但我不确定...
有没有一种方法可以让GCC保持安静而不用操心警告? 这是GCC的一个bug吗?
编辑1:实际代码的详细信息:
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];
}
编辑2:
因此,在C11标准草案第6.7.3/9中指出:
如果数组类型的规范包括任何类型修饰符,则元素类型是带修饰符的,而不是数组类型。
请参见@hvd回答。
消除-Wcast-qual
的一种方法:
DATA_PTR data = (DATA_PTR)(intptr_t)raw;
raw
变成char const (*raw)[a][b][c]
? - StoryTeller - Unslander Monica-Wcast-qual
还是有点奇怪。 - diapirchar
,而不是一个const char
,因此编译器(在这种情况下为gcc
)会在语句typedef char const (*DATA_PTR)[a][b][c];
和函数签名中丢弃const
。 - user3629249