相关疑难解决方法(0)

什么是严格别名规则?

当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?

c strict-aliasing undefined-behavior type-punning

778
推荐指数
10
解决办法
19万
查看次数

"匿名结构"标准吗?而且,真的,他们是什么?

MSDN 认为匿名结构在C++中是非标准的:

Microsoft C扩展允许您在另一个结构中声明结构变量而不为其指定名称.这些嵌套结构称为匿名结构.C++不允许匿名结构.

您可以访问匿名结构的成员,就好像它们是包含结构中的成员一样.

@ K-ballo同意.

我被告知这个功能不一定只是创建一个未命名的结构,但我不能看到标准措辞的区别.

C++ 11说:

[C++11: 9/1]:[..]一个类说明符,类头省略了class-head-name,定义了一个未命名的类.

并为缺少名称的类型定义提供完整的语法结构.

C++ 03缺少这种明确的措辞,但同样表明identifier类型定义中的类型是可选的,并在9.4.2/5和中引用了"未命名的类" 3.5/4.

  • 那么MSDN是错的,这些东西都是完全标准的吗?
  • 或者在"未命名的结构/类"之间是否存在一些微妙之处,并且当用作成员时它们会被这个C++ 03/C++ 11功能覆盖?
  • 我错过了"unnamed struct"和"anonymous struct"之间的一些根本区别吗?它们看起来像我的同义词.

c++

55
推荐指数
3
解决办法
3万
查看次数

具有"共同初始序列"的联合'双关'结构:为什么C(99+)而不是C++规定了'联合类型的可见声明'?

背景

union通过@ecatmur(/sf/answers/2209049671/)通过引用以下位来讨论关于类型惩罚的大部分未实现或实现定义的性质,关于标准的豁免 -布局structs具有成员类型的"公共初始序列":

C11(6.5.2.3结构和联合成员 ; 语义):

[...]如果一个联合包含几个共享一个共同初始序列的结构(见下文),并且如果联合对象当前包含这些结构中的一个,则允许检查其中任何一个的公共初始部分.完整的工会类型的声明是可见的.如果对应的成员具有一个或多个初始成员的序列的兼容类型(并且对于位字段,具有相同的宽度),则两个结构共享 共同的初始序列.

C++ 03([class.mem]/16):

如果POD-union包含两个或多个共享公共初始序列的POD结构,并且如果POD-union对象当前包含这些POD结构中的一个,则允许检查它们中的任何一个的公共初始部分.如果对应的成员具有一个或多个初始成员的序列的布局兼容类型(并且对于位字段,具有相同的宽度),则两个POD结构共享共同的初始序列.

这两个标准的其他版本有相似的语言; 从C++ 11开始,使用的术语是标准布局而不是POD.

由于不需要重新解释,这不是真正的类型惩罚,只是应用于union成员访问的名称替换.C++ 17(臭名昭着的P0137R1)的提议使得这种语言明确地使用了"访问就像其他结构成员被提名一样"的语言.

但请注意粗体 - " 在任何地方都可以看到完整类型的联合声明 " - C11中存在的条款,但在2003年,2011年或2014年的C++草案中没有任何内容(几乎完全相同,但后来的版本取代了" POD"使用新术语标准布局).在任何情况下,在union任何C++标准的相应部分中都完全没有' 类型位的可见声明.

@loop和@ Mints97,这里 - /sf/answers/1997029261/ - 显示这一行在C89中也没有出现,首先出现在C99中,然后保留在C中(尽管如此,从来没有过滤过到C++).

关于此的标准讨论

[剪掉 - 看我的回答]

问题

从那以后,我的问题是:

  • 这是什么意思?什么被归类为"可见声明"?该条款是否旨在缩小 - 或扩大 - 这种"惩罚"定义行为的背景范围?

  • 我们是否假设C++中的这种遗漏是非常慎重的?

  • C++与C不同的原因是什么?C++是否只是从C89"继承"了这个,然后决定 - 或者更糟,忘记 - 与C99一起更新?

  • 如果差异是故意的,那么 …

c c++ struct unions type-punning

26
推荐指数
2
解决办法
1474
查看次数

C++ POD结构继承?是否有关于派生成员的内存布局的保证

比方说,我有一个struct RGB,我想创建struct RGBA,继承RGB:

struct RGB {
    unsigned char r;
    unsigned char g;
    unsigned char b;
};

struct RGBA: RGB {
    unsigned char a;
};
Run Code Online (Sandbox Code Playgroud)

两者都将用于读取未压缩的图像数据:

RGBA *pixel=static_cast<RGBA *>(image->uncompressed_data);
Run Code Online (Sandbox Code Playgroud)

问题:关于内存布局,这样安全struct RGBA吗?有人保证:

  • unsigned char a之后RGB struct(不是之前)
  • 之间没有填充struct RGB和参数来自struct RGBA

会有#pragma pack帮助吗?这都是关于继承期间的内存布局.

c++ inheritance pod

25
推荐指数
2
解决办法
5437
查看次数

C 中的继承:好、坏还是其他?

我们拥有经过数十年开发的大型 C 代码库。该代码的特点之一是对函数指针和伪继承的大量依赖。习语(如此处讨论的如下所示:

typedef struct twod_ {
    double x, y;
} twod;

typedef struct threed_ {
    twod super;
    double z;
} threed;

threed *point_3d;
twod *point_2d = (twod *)point3d;
Run Code Online (Sandbox Code Playgroud)

此时point_2d->xpoint_3d->x是同一块内存。

我的问题是:

  • 这个习惯用法在现代生产代码中仍然流行吗?(任何推荐的开源示例)
  • 这段代码对性能有要求——这个习惯对速度和/或内存使用有帮助吗?
  • 它的实现方式(或者由于多年的代码膨胀)现在感觉有点像意大利面条代码——一般来说,这是实现的问题,还是习惯用法的问题?或者换句话说,在理想的情况下,500k LOC 这个习语会很快被理解吗?

当然,“如果它没坏,就不要修理它”这句格言值得牢记。然而,目前这并没有真正帮助我们,所以我们认为我们可能需要更深入地重构......

谢谢!

c oop

5
推荐指数
1
解决办法
519
查看次数