Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将类与其继承的类对齐?强制所有堆栈对齐?换尺寸?_C++_Memory_Stack_Alignment_Struct Member Alignment - Fatal编程技术网

C++ 将类与其继承的类对齐?强制所有堆栈对齐?换尺寸?

C++ 将类与其继承的类对齐?强制所有堆栈对齐?换尺寸?,c++,memory,stack,alignment,struct-member-alignment,C++,Memory,Stack,Alignment,Struct Member Alignment,我希望有一个基类,它指定从它继承的对象的对齐方式。这对于堆来说很好,因为我可以控制如何分配它,以及如何在自定义数组模板中分配它的数组。但是,C++中的类的实际大小根本没有改变。也就是说,如果我对派生类的指针执行指针算术,那么它将跳到错误的位置。这是第一个问题 问题二是堆栈对齐。似乎没有办法直接强制整个堆栈为16字节对齐指针 我能看到的唯一影响这些的是vc++和g++编译器特定的设置,但这里的问题是我不想一直手动修复对齐。这必然是容易出错的,更不用说痛苦了 我也可以做一些智能指针,但这也会带来更多

我希望有一个基类,它指定从它继承的对象的对齐方式。这对于堆来说很好,因为我可以控制如何分配它,以及如何在自定义数组模板中分配它的数组。但是,C++中的类的实际大小根本没有改变。也就是说,如果我对派生类的指针执行指针算术,那么它将跳到错误的位置。这是第一个问题

问题二是堆栈对齐。似乎没有办法直接强制整个堆栈为16字节对齐指针

我能看到的唯一影响这些的是vc++和g++编译器特定的设置,但这里的问题是我不想一直手动修复对齐。这必然是容易出错的,更不用说痛苦了

我也可以做一些智能指针,但这也会带来更多的问题


如果我只是对齐基类,那么子类也会对齐吗?如果是这样的话,这将解决我的大多数问题,但这似乎是可疑的(尽管我会尝试这种做法)。

如果基类有特定的对齐要求,那么任何派生类都至少会有该对齐(由于它们自己的成员,它们可能会得到更严格的对齐要求)。否则,编译器无法保证访问基成员将满足它们的要求


然而,对于堆栈对齐,实际上没有什么可以移植的事情可以做——这完全由编译器和编译器的平台ABI需求来处理。正如您所指出的,编译器选项或pragma可能会让您施加一些控制,但不具有可移植性。

记住Michael关于可移植性的答案。。我假设你的目标是SSE矢量化,并开始感受到这种痛苦,这真的应该是一种通过明确提示和低水平控制来实现的标准方式。默认情况下,您提到的两个编译器都会在堆栈上进行16字节对齐

因此,虽然编译器支持确实存在差异,可以更改,受到挑战等,但它也可能在其中一个编译器上严重利用不足;这取决于您包含的优化器和类型,当然也取决于矢量器的选择。再说一遍,不清楚你在做什么,有什么用

由于没有示例的问题定义很粗略,也许您可以对加利福尼亚州(使用LTCG)的declspec(align(16))和gcc的_属性(aligned(16))进行一次尝试。如果这有帮助的话,最好让我们知道,在这个例子中,哪些编译器警告或错误是有效的或无效的。出于各种原因,我也会避免使用任何智能指针


sizeof在您的问题中表示您还面临变量数组和指针类型方面的挑战,在这种情况下,前者可能会有问题。即使你可以忍受失去复制构造函数和赋值工具,检查机器代码也不会有什么坏处。也就是说,如果出现复杂情况,您需要做的是查看输出,如果是VC++,则切换到Intel以在Windows中获得更好的提示,并尽早测试/compilet和运行时断言/陷阱故障,或者选择任何免费的对象文件分析工具。然后,您只需以最合理的方式处理明显有问题的结构,这是始终可能的。

我们在PARISC HPUX上遇到了类似的问题,其中唯一的原子结构是需要16字节对齐的4字节原子结构

我们可以通过如下方式声明我们的4字节数量来伪造它:

struct Stupid_HPUX { int 4byteLockWordInHere[4] ; } ; 结构愚蠢的 { int 4byteLockWordInHere[4]; } ; 并在运行时选择正确的一个。对于你的问题,你可以做类似的事情

union rawMemory { int blah[(sizeof(yourtype) + 16)/4] ; char c[1] ; } u ; 联合随机存储器 { int blah[(大小(yourtype)+16)/4]; charc[1]; }u;
然后使用带有运行时确定的地址的placement new来修复所需的位置。

谢谢,这很有帮助。当我尝试将编译器错误分配给“未对齐”指针时,是否有一些方法可以避免编译器错误?我知道自从我自己弄到它后,它总是对齐的。如果可能的话,我宁愿避免在整个程序中使用这些声明。看起来这应该很容易,但事实并非如此。没关系,我终于明白了这个问题。我以前有过这个弹出窗口,但我不认为它可以解决,但只是改为传递一个引用就解决了它。我一直很困惑,但我想这是一个令人困惑的话题。你可能想发布一些代码-我不确定你的编译器可能会抱怨“未对齐指针”。如果将指向字节数组的指针强制转换到类,则可能违反了对齐要求。不管你对引用做什么,都可能隐藏了一个问题。我现在明白它为什么这么做了。我不确定它保持16字节的效果如何,但即使这种可能性也会导致传递值的编译器错误。我不知道为什么,但这些传球只是一个错误。谢谢你们给我的好答案,伙计们,我大部分时间都在过度复杂化,但现在工作起来很有魅力。惊人的速度提升。