C++ 参考偏移中看似无关的规范

C++ 参考偏移中看似无关的规范,c++,C++,我在阅读参考资料时看到了以下内容: 给定具有静态存储持续时间的类型的对象o,和(o.member)应为常量表达式,并指向o的子对象否则,行为未定义。特别是,如果成员是静态数据成员、位字段或成员函数,则行为未定义 我的第一个问题是,为什么这会出现在offsetof的引用中,因为我看不出它与offsetof有任何明显的相关性 第二,关于上述引文的重点,“否则”是什么意思?这是否意味着对于具有自动或动态存储持续时间的对象o,和(o.member)未定义?我以为这样的表达是合法的,我是不是遗漏了什么?还

我在阅读参考资料时看到了以下内容:

给定具有静态存储持续时间的类型的对象
o
和(o.member)
应为常量表达式,并指向
o
的子对象否则,行为未定义。特别是,如果成员是静态数据成员、位字段或成员函数,则行为未定义

我的第一个问题是,为什么这会出现在offsetof的引用中,因为我看不出它与offsetof有任何明显的相关性


第二,关于上述引文的重点,“否则”是什么意思?这是否意味着对于具有自动或动态存储持续时间的对象
o
和(o.member)
未定义?我以为这样的表达是合法的,我是不是遗漏了什么?还是因为括号的缘故?

相关性在于,这是在解释
偏移量的要求。不用说,您无法传递两个任意参数并给出有意义的结果。因此,
offsetof
的要求通过一个例子来说明<代码>偏移量
指定如下:

#define offsetof(type, member) ...
宏的第一个参数名为
类型
,第二个参数名为
成员
。这样一来:

给定具有静态存储持续时间的类型为o的对象

这是对需求的概述:假设您有一个
静态
对象,其类型为
类型
(宏的第一个参数),并且:

&(o.member)应为常量表达式,并指向o的子对象

。。。这意味着,如果在这种情况下,
o.member
也是一个常量表达式,并引用某个“子对象”,即
o
的成员,类型为
类型

。。。然后这就是宏的要求,以便
offsetof
为您提供指定的结果

你问:

“否则”是什么意思


这里,“否则”指的是除上述所有条件之外的任何条件。

对于问题的第二部分,在引文的第二部分“特别…”中给出了答案。
&o
&o.member
之间的(原始的、未键入的)差异实际上是抵消。除此之外,静态成员具有恒定地址(
&o
)。类似地,任何非静态成员(
&(o.member)
)的地址也将是常量。因此,它们之间的差异(
&(o.member)&o
)是恒定的。所以这个子句实际上是说,
offsetof(type,member)
是常量。否则意味着,如果上述条件均不成立,则行为未定义。本质上,这意味着
&o
&o1
之间没有特定的关系,除非
o1
o
的子对象(即,它不是成员或成员的成员…)。谢谢,各位,我看到了我的问题。我认为对于静态对象,
&(o.member)
应该是一个常量表达式。但这一条款是对宏参数类型和成员的要求,我在C标准中发现了这一点。否则意味着它不是一个常量表达式。我不明白为什么offsetof的要求会涉及一个对象,因为offsetof的参数只是一个类型及其成员。更不用说有进一步存储持续时间需求的对象了。我确信有其他方法可以定义正式需求。这就是那些选择表达需求的人的写作方式。你说它只是“类型及其成员”,但是他们选择用一个名为<代码> o>代码>的假设对象来框架它,并且在那个情况下,用<代码>和(o.成员< /代码>)是有效的C++代码。这也说明了同样的事情,但以一种更迂腐的方式。因此,强调部分中的行为未定义是指表达式的偏移量而不是
&(o.member)
未定义?正确,“未定义”表示从“代码将不会编译并产生您无法理解的混乱错误消息”到“代码将编译,但将使用一个随机数生成器来生成返回的偏移量值,当您的代码使用它时会发生什么将由您来处理”。