Trong đoạn này, một con trỏ để VLA được sử dụng để truy cập dễ dàng hơn để một bảng tra cứu lớn:Cast "con trỏ đến const" thành "con trỏ đến const 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 cuộn cảm trên nó trong khi Clang 4.0.0 (thân cây) biên dịch tốt, cả hai đều bật với kích hoạt -Wcast-qual
.
In function 'lookup':
warning: cast discards 'const' qualifier from pointer target type [-Wcast-qual]
DATA_PTR data = (DATA_PTR)raw;
^
Mã chạy như mong đợi theo một trong hai cách.
tôi đoán là GCC lẫn lộn một "con trỏ đến VLA của các yếu tố const" và "con trỏ đến const VLA" nhưng tôi đạt ...
Có cách nào để im lặng GCC mà không cần loay hoay với cảnh báo? Đây có phải là lỗi của GCC không?
EDIT1:
Chi tiết về mã thực tế:
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:
Vì vậy, nó là ... tiêu chuẩn dự thảo C11 nói trong 6.7.3/9:
Nếu cụ thể ation của một loại mảng bao gồm bất kỳ loại vòng loại nào, loại phần tử đủ điều kiện, không phải kiểu mảng.
Xem câu trả lời @hvd.
Một hack để im lặng -Wcast-qual
:
DATA_PTR data = (DATA_PTR)(intptr_t)raw;
"con trỏ tới VLA của các phần tử const" và "con trỏ đến const VLA" là giống nhau. Mảng const là một mảng các phần tử const. Có vẻ như một con bọ. – emlai
Tại sao không làm cho toàn bộ điều an toàn hơn một chút, và tạo 'nguyên' thành' char const (* raw) [a] [b] [c] '? – StoryTeller
@StoryTeller Tôi đã thêm mã có thể trông như thế nào nhưng vẫn là '-Wcast-qual' là lạ. – diapir