代码之家  ›  专栏  ›  技术社区  ›  Petr Skocik

将指向较大数组的指针分配给指向较小VLA的指针

  •  3
  • Petr Skocik  · 技术社区  · 6 年前

    我注意到C编译器(gcc、clang、tinycc)允许我将指向较大数组的指针分配给指向较小VLA的指针,而不发出警告:

    #include <stdio.h>
    #if !__TINYC__
    void take_vla(int N, char const X[1][N]) { printf("%zd\n", sizeof(*X)); }
    #endif
    int main()
    {
        static char bigarray[]="0123456789abcdefghijklmnopqrstuvwxyz";
        //VLA
        int n = 3;
        char const (*subarray2)[n]=&bigarray;
        //char const (*subarray3)[(int){3}]=&bigarray; //VLA but clang doesn't see it as such (a bug, I guess)
    #if !__TINYC__
        take_vla(3,&bigarray);
        take_vla(3,&"abcdefg");
    #endif
    
        #if 0
            char const (*subarray1)[3]=&bigarray; //-Wincompatible-pointer-types
        #endif
    }
    

    这符合C吗?为什么?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Lundin    6 年前

    const char[3] 与不兼容 char[37] .

    “指向限定类型的指针”也不与“指向类型的指针”兼容-不要将其与“指向类型的限定指针”混淆。(不幸的是,常量正确性不适用于数组指针。)

    相关部分为简单赋值规则C17 6.5.16.1:

    • 左操作数具有原子、限定或非限定指针类型,并且(考虑 左操作数在左值转换后的类型)两个操作数都是 指向兼容类型的限定或非限定版本的指针,以及指向的类型 左边的to具有右边指向的类型的所有限定符;

    查看各种编译器:

    • “GNU模式”下的GCC对于检查C一致性是无用的。必须用编译 -std=cxx -pedantic-errors . 在此之后,GCC表现良好: gcc -std=c17 -pedantic-errors 以下内容:

      错误:指向具有不同限定符的数组的指针在ISO C中不兼容[-wpedantic]

    • ICC提供与GCC相同的诊断,它工作正常。

    • 反之 clang -std=c17 -pedantic-errors 不报告错误,因此显然不符合C标准。