Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.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++ GCC中的结构构件对齐_C++_Visual C++_Gcc_Alignment - Fatal编程技术网

C++ GCC中的结构构件对齐

C++ GCC中的结构构件对齐,c++,visual-c++,gcc,alignment,C++,Visual C++,Gcc,Alignment,我正在移植一个msvc项目,它有几个库,每个库都有特定的结构和成员对齐。使用默认对齐方式导致了许多严重的未对齐问题,谷歌告诉我,我可以通过使用\uuuu属性(aligned(MY\u ALIGN))标志手动设置每个结构/类/联合的对齐方式来解决这个问题,但是有一件事困扰着我: 为了简单起见,假设项目A使用1字节对齐方式,而项目B使用项目A的功能并包含大量标题,具有16字节对齐方式。这会有问题吗?还是我想得太多了,这样就行了?我有一种不好的感觉,在构建库时,msvc编译器会在所有头文件中为每个结构

我正在移植一个msvc项目,它有几个库,每个库都有特定的结构和成员对齐。使用默认对齐方式导致了许多严重的未对齐问题,谷歌告诉我,我可以通过使用
\uuuu属性(aligned(MY\u ALIGN))
标志手动设置每个结构/类/联合的对齐方式来解决这个问题,但是有一件事困扰着我:


为了简单起见,假设项目A使用1字节对齐方式,而项目B使用项目A的功能并包含大量标题,具有16字节对齐方式。这会有问题吗?还是我想得太多了,这样就行了?我有一种不好的感觉,在构建库时,msvc编译器会在所有头文件中为每个结构设置对齐方式(无论它们是包含在项目中还是被源文件引用)。这是真的吗?如果是,请告诉我,我应该如何设置对齐以模拟MSVC的结构成员对齐设置?

我认为这不应该有问题。请记住,未对齐的访问(我认为在大多数系统上最小为4字节)会让您付出代价(尽管在某些情况下节省空间不多)。结构本身具有该属性,编译器将执行所有指针运算,因此只要标题不与彼此的定义相冲突,就应该可以了。

首先,源文件中的每个标题
#include
'd都会按字面意思获取进程,不管它是否在同一项目中

这肯定会导致一些问题。例如,项目A定义一个结构,将其所有成员与字节边界对齐(压缩),并导出一个接受指向该结构的指针的函数。 然后,如果出于某种原因在这样的环境中编译项目B,使得相同的结构以不同的方式对齐,那么就不可能将此
struct
的实例的地址直接传递给导出的例程。它们至少在A和B中具有不同的
sizeof
s

最简单的规则是:
1) 如果要与某个外部编译库进行接口,则应确保结构对齐与库编译器使用的对齐方式一致。这涉及到库标题中存在的结构。好的库通过为某些编译器提供
#pragma
,以确保正确的对齐,从而尽量减少工作量。

2) 如果您在某个项目中使用结构,您可以不使用它,只需编写不依赖于特定对齐的可移植代码即可。

这可能取决于您编译的体系结构。一些CPU不允许对某些类型的变量进行未对齐的访问(例如,需要int访问的偶数地址,double访问的地址需要除以8,…)。除此之外,只要对齐用于需要它的结构,并且没有全局打开,我就看不到任何问题。是的,这就是我的观点(未对齐的访问不是什么大问题)。只要路线没有在某个地方被覆盖,就没有问题。就我个人而言,我并不担心它,因为编译器最了解它。谢谢你的回答,但该项目正在被移植到Mac OS X平台,未对齐会导致应用程序失败,因此,未对齐的访问实际上是一个非常大的问题……没关系,只要标题不相互冲突,您就可以保持对齐。谢谢,耶稣!:)你能告诉我,你所说的标题冲突是什么意思吗?项目A的标题包含在项目B的源中,其中定义的实体在项目B中广泛使用。除非您使用的是SIMD类型(SSE),否则如果使用默认对齐方式,就不会出现任何问题。如果您确实出现错误,那是因为您在代码中做了一些可怕的事情,应该加以修复。好吧,SSE扩展正在广泛使用,并且有很多代码需要特定的对齐方式……给定SSE,您应该能够配置编译器以输出MOVUPS等,而不是MOVAP。这“解决”了你的问题,现在便携式的方式。第二个选项是使用一个将对齐固定为16字节的库,第三个选项是从项目中创建/集成这样的库。无论如何,您应该修复头中的结构和成员对齐,而不是在项目设置或编译器标志中。我的观点是,“正常”类型由编译器正确分配,除非您显式破坏它(通过执行依赖于未定义行为的危险强制转换)。因此,如果您在SSE之外出现对齐错误,这可能表明您的代码存在更深层次的问题。请告诉我,我应该如何配置Apple GCC 4.2.1编译器?