C 将堆分配的指针强制转换为指向VLA的指针是否安全?

C 将堆分配的指针强制转换为指向VLA的指针是否安全?,c,arrays,pointers,language-lawyer,c99,C,Arrays,Pointers,Language Lawyer,C99,如果我有一个指向某个堆分配空间的指针,它代表一个典型的 行主二维数组,将此指针投射到 指向VLA的等效指针,以方便编写子脚本?例如: // // Assuming 'm' was allocated and initialized something like: // // int *matrix = malloc(sizeof(*matrix) * rows * cols); // // for (int r = 0; r < rows; r++) { // for (int c

如果我有一个指向某个堆分配空间的指针,它代表一个典型的 行主二维数组,将此指针投射到 指向VLA的等效指针,以方便编写子脚本?例如:

//
// Assuming 'm' was allocated and initialized something like:
//
// int *matrix = malloc(sizeof(*matrix) * rows * cols);
//
// for (int r = 0; r < rows; r++) {
//     for (int c = 0; c < cols; c++) {
//         matrix[r * cols + c] = some_value;
//     }
// }
//
// Is it safe for this function to cast 'm' to a pointer to a VLA?
//
void print_matrix(int *m, int rows, int cols) {
    int (*mp)[cols] = (int (*)[cols])m;

    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
            printf(" %d", mp[r][c]);
        }
        printf("\n");
    }
}
//
//假设已分配并初始化“m”,如下所示:
//
//int*矩阵=malloc(sizeof(*矩阵)*行*cols);
//
//对于(int r=0;r
我已经测试了上面的代码。它似乎起作用了,我认为它应该起作用,但它是安全的、明确的行为吗

如果有人想知道,这里的用例是我从 表示行主2D(或3D)数组的文件/socket/etc,我想使用
VLA用于避免手动计算元素的索引。

如果
cols
为0或更小,则行为未定义。C11将对VLA的支持设置为可选(例如,您在需要时标记了问题C99),如果不支持,则宏
\u STDC\u NO\u VLA\u
定义为1(参见C11 6.10.8.3 p1)

撇开这件事不谈,你是安全的


感谢Ouah和Alter Mann

等等,也许你不是。忘记了严格的别名。该死。别名没有问题,数组对象在任何情况下都是以
int
的形式访问的。VLA是可选的,因此,如果嵌入式平台的编译器不希望对VLA的支持是可选的(不知道为什么):@epicbrew,任何也实现C99的编译器都可以保存以供VLA使用。它们是可选的,希望将那些尚未C99的编译器移植到现代C语言中。这可能只是一厢情愿的想法。