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

gcc

允许数组为0
#include <stdio.h>

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

在这里插入图片描述
在这里插入图片描述

允许对void进行sizeof

在这里插入图片描述

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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stddef.h>

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;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值