C/C++不同编译器对数组为0和void的处理

C/C++数组为0

      • gcc
        • 允许数组为0
        • 允许对void进行sizeof
      • MSVC
        • 不允许数组为0
        • 不允许对void进行sizeof
      • 数组为0的妙用

gcc

允许数组为0

#include 

int main(int argc, char **argv)
{
    char array[0];
    printf("%zu\n", sizeof(array));
    return 0;
}

C/C++不同编译器对数组为0和void的处理_第1张图片
C/C++不同编译器对数组为0和void的处理_第2张图片

允许对void进行sizeof

C/C++不同编译器对数组为0和void的处理_第3张图片

MSVC

不允许数组为0

报错

error C2466: cannot allocate an array of constant size 0
error C2133: 'array': unknown size
error C2070: 'char [0]': illegal sizeof operand

不允许对void进行sizeof

报错

error C2070: 'void': illegal sizeof operand

数组为0的妙用

将数组放在结构体末尾,可以用做变长数组,动态决定数组的实际大小,即使未使用,也不会占用结构体空间。
但是在写代码时为了兼容各种编译器,会见到在数组末尾形如char array[1]的写法,这也是一种方法,不过这种方法会因为内存对齐,导致结构体实际占用更大的空间,如下代码,将0换成1后sizeof(PERSON) == 12 (4字节对齐)

#include 
#include 
#include 
#include 
#include 

typedef struct Person
{
    int32_t     age;
    uint32_t    nameSize;
    char        name[0]; // name只是一个占位符, 实际不占用任何空间,也可以看做是一个偏移量, 此处偏移为8
} PERSON;

int main(int argc, char **argv)
{
    printf("sizeof(PERSON) = %zu\n", sizeof(PERSON));
    printf("offsetof(PERSON, name) = %ld\n", offsetof(PERSON, name));

    uint32_t nameSize = 16;
    PERSON *pPerson = (PERSON *)malloc(sizeof(PERSON) + nameSize);
    if (pPerson == NULL)
    {
        return 0;
    }

    pPerson->age = 10;
    pPerson->nameSize = nameSize;
    memset(pPerson->name, 0, nameSize);
    strcpy(pPerson->name, "eular");

    printf("person name: %s\n", pPerson->name);
    free(pPerson);
    return 0;
}

C/C++不同编译器对数组为0和void的处理_第4张图片

你可能感兴趣的:(c语言,c++)