![]() |
1
2
因此,您试图在C中构建子类。一种可能的方法是将基结构作为子结构的第一个元素,因为在这种情况下,C标准明确允许在这两种类型之间来回转换:
缺点是需要对基类进行转换才能访问其成员: 示例代码:
然后,您可以这样使用它:
|
![]() |
2
2
如果使用
当前第6.5.2.3节 C standard ,以及C89标准第6.3.2.3节规定如下:
由于两个结构的前两个成员的类型相同,因此可以使用任一联合成员自由访问这些成员。 |
![]() |
3
0
您所描述的内容在C标准下应该是允许的。常见的初始序列规则的混乱源于一个更大的问题:该标准未能规定使用明显源自另一个的指针或左值被视为使用了原始值。如果答案是“从不”,那么任何非字符类型的结构或联合成员都将毫无用处,因为该成员将是一个左值,其类型对于访问结构或联合无效。这种观点显然是荒谬的。如果答案是“仅当通过直接应用形成时”。“或”->在结构或联合类型上,或在指向此类类型的指针上,可以使用“&“在结构和工会成员身上是毫无用处的。我认为这种观点没有那么荒谬。 我认为很明显,为了有用,C语言必须被视为至少在某些情况下允许使用派生左值。您的代码或大多数依赖于公共初始序列规则的代码是否可用取决于这些情况。
如果代码不能可靠地使用派生的左值来访问结构成员,那么这种语言将相当愚蠢。不幸的是,尽管这个问题在1992年很明显(它构成了当年发布的缺陷报告#028的基础),但委员会没有解决根本问题,而是基于完全荒谬的逻辑得出了正确的结论,从那以后,它以“有效类型”的形式增加了不必要的复杂性,而从未真正定义
因此,如果不依赖于更多的行为,而不是通过标准的字面阅读来保证,那么就无法编写任何对结构或联合做很多事情的代码,无论这种访问是通过强制
如果有人认为6.5p7的意图是以某种方式允许使用从某一特定类型派生的左值的操作访问该类型的对象,至少在不涉及实际别名的情况下(请注意,脚注#88“此列表的意图是指定对象可能被别名或不被别名的情况”),并认识到别名要求在存在另一个引用时使用引用X访问存储区域 从中看不到X 这将在将来用于以冲突的方式访问存储,那么遵循这一意图的编译器应该能够毫不费力地处理像您这样的代码。 不幸的是,gcc和clang似乎都将p6.5p7解释为,从另一种类型派生的左值通常应该被假定为无法实际识别前一种类型的对象,即使在派生完全可见的情况下也是如此。 例如:
当时
除非或直到该标准被更正为说明在何种情况下可以使用派生左值访问结构或联合的成员,否则不清楚任何对结构或联合执行任何异常操作的代码是否应该在
|
![]() |
Xirema · 如何正确编写运算符的R值重载 7 年前 |
![]() |
Mário Feroldi · 在运行时调用代码中未调用的函数 7 年前 |
![]() |
chqrlie · 所有位0都可以是整数的陷阱表示吗? 7 年前 |
![]() |
Vincent · 打印零,但不基于该条件退出循环 7 年前 |
![]() |
Dror K. · 用%p打印空指针是未定义的行为? 7 年前 |
![]() |
Bite Bytes · C中允许这种函数调用吗 7 年前 |
![]() |
K J Gor · C中strncpy的内存混淆 8 年前 |