简体   繁体   English

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

[英]sizeof operator shows wrong size of struct in c

Having this simple code:有这个简单的代码:

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

output: output:

sizeof arg: 1
the real sizeof struct foo: 8

As you can see the function shows wrong result.如您所见,function 显示错误的结果。 If the reason is invalid application of 'sizeof' to incomplete type , then why does it shows sizeof arg: 1 ?如果原因是'sizeof' 对不完整类型的无效应用,那么为什么它显示sizeof arg: 1 void is not 1 bytes long, but incomplete type, so why is this result? void不是1个字节长,而是不完整的类型,那么为什么会出现这个结果呢?

You're attempting to get the size of void which the C standard doesn't allow.您正在尝试获取 C 标准不允许的void大小。 However, some implementations define sizeof(void) to be 1 which is what you're seeing here.但是,某些实现将sizeof(void)定义为 1,这就是您在此处看到的。

The function has no way of knowing that the void * you passed it is actually a foo * . function 无法知道您传递的void *实际上是foo * You would need some other way of conveying that information.您将需要其他方式来传达该信息。

This statement这个说法

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

is incorrect.是不正确的。 The expression *arg has the incomplete type void .表达式*arg具有不完整的类型void You need to write你需要写

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

Early versions of C do not have the type void . C 的早期版本没有void类型。 Instead the type char was used as the type void .相反,类型char被用作类型void As the sizeof( char ) is always equal to 1 then some compilers for backward compatibility with the old specifications of C set sizeof( void ) to 1 though it is not correct from the C Standard's point of view.由于sizeof( char )始终等于1 ,因此一些编译器为了向后兼容 C 的旧规范,将sizeof( void )设置为1 ,尽管从 C 标准的角度来看它是不正确的。

The result should be a diagnostic, as sizeof (void) (which sizeof (*arg) resolves to) is a constraint violation :结果应该是诊断结果,因为sizeof (void)sizeof (*arg)解析为)是违反约束的:

6.5.3.4 The sizeof and _Alignof operators 6.5.3.4 sizeof_Alignof运算符

Constraints 约束

1 The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member. 1 sizeof运算符不得应用于具有 function 类型或不完整类型的表达式、此类类型的括号名称或指定位字段成员的表达式。 The _Alignof operator shall not be applied to a function type or an incomplete type. _Alignof运算符不应应用于 function 类型或不完整类型。
C 2011 Online Draft C 2011年在线草案

void is an incomplete type that cannot be completed - you cannot create an object that type, so using sizeof on it is a coding error, full stop. void是无法完成的不完整类型 - 您无法创建该类型的 object,因此在其上使用sizeof是编码错误,句号。

However , for some reason, certain implementations decided to have sizeof (void) evaluate to 1 unless you're in "pedantic" mode.但是,出于某种原因,某些实现决定让sizeof (void)评估为 1,除非您处于“迂腐”模式。 Obviously someone thought it was useful in some circumstances, but I wouldn't recommend its use.显然有人认为它在某些情况下很有用,但我不建议使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM