我在cppreference(https://en.cppreference.com/w/c/types/offsetof)上读到:
尽管在C23中指定在offsetof中定义新类型是未定义的行为,但即使在早期模式中,这种用法也只得到部分实现的支持:通常支持offsetof(struct Foo { int a; }, a)
,但offsetof(struct Foo { int a, b; }, a)
不支持,因为在struct Foo的定义中有逗号。
因此,由于定义中的逗号,它不能用于新类型,这是否意味着使用typeof
将使它工作(因为它将在括号中 Package 类型)?
offsetof(typeof(struct Foo { int a,b; }), a);
编辑:
如果这不起作用,有没有一个变通办法让结构体在offsetof
内部定义?
例如:
void *dummy;
offsetof(typeof(*((struct { int a; int b; }*)dummy)), a);
1条答案
按热度按时间5vf7fwbs1#
C 2023草案N3096 7.21 4说,
offsetof(
type,
member-designator)
:.如果指定的 type 定义了一个新的类型,或者指定的成员是一个位域,则行为是未定义的。
因此,C标准不要求
offsetof
在符合C实现的新类型中工作,无论type
的宏参数是否包含逗号。如果参数包含一个typeof
,其中定义了一个新的类型,则参数定义了一个新的类型,并受上述条件的约束。另一个原因是,假设它不能与新类型一起工作,宏可能会在其替换列表中使用类型参数,从而导致由于类型的多个定义而导致的问题。这不是一个正确的逻辑推理,因为X(逗号的存在)导致Y(
offsetof
将不起作用),非X将导致非Y。