sizeof 运算符在 c 中显示错误的结构大小

问题描述

有这个简单的代码:

#include <stdio.h>

typedef struct
{
    int a;
    char c;
} foo;

void func(void *arg)
{
    printf("sizeof arg: %ld\n",sizeof(*arg));
}

int main()
{
    foo f = {6,'c'};
    func(&f);

    printf("the real sizeof struct foo: %ld\n",sizeof(f));
}

输出:

sizeof arg: 1
the real sizeof struct foo: 8

如您所见,该函数显示错误的结果。如果原因是invalid application of ‘sizeof’ to incomplete type,那么为什么显示sizeof arg: 1void 不是 1 字节长,而是不完整的类型,为什么会是这个结果?

解决方法

您正在尝试获取 C 标准不允许的 void 大小。但是,某些实现将 sizeof(void) 定义为 1,这就是您在此处看到的内容。

该函数无法知道您传递给它的 void * 实际上是一个 foo *。您需要通过其他方式来传达该信息。

,

本声明

printf("sizeof arg: %ld\n",sizeof(*arg));

不正确。表达式 *arg 具有不完整的类型 void。你需要写

printf("sizeof arg: %ld\n",sizeof(* ( foo * )arg));

早期版本的 C 没有 void 类型。相反,类型 char 被用作类型 void。由于 sizeof( char ) 始终等于 1,因此一些编译器为了向后兼容旧的 C 规范将 sizeof( void ) 设置为 1,尽管从 C 标准的角度来看这是不正确的的观点。

,

结果应该是一个诊断结果,因为sizeof (void)sizeof (*arg)解析为)是一个约束违规

6.5.3.4 sizeof_Alignof 运算符

约束

1 sizeof 运算符不得应用于具有函数类型或 不完整类型、此类类型的括号名称或表达式 指定位域成员。 _Alignof 运算符不得应用于 函数类型或不完整的类型。 C 2011 Online Draft

void 是无法完成的不完整类型 - 您无法创建该类型的对象,因此在其上使用 sizeof 是编码错误,句号。

但是,出于某种原因,某些实现决定让 sizeof (void) 评估为 1,除非您处于“迂腐”模式。显然有人认为它在某些情况下很有用,但我不建议使用它。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...