C++对齐的未来:通过值传递
The future of C++ alignment: passing by value?
阅读Eigen库文档时,我注意到有些对象不能通过值传递。C++11中是否有任何开发或计划中的开发可以安全地按值传递此类对象?
另外,为什么按值返回这样的对象没有问题?
Eigen完全有可能只是一个写得很糟糕的库(或者只是考虑不周);仅仅因为某件事在网上并不意味着它是真的。例如:
在C++中,按值传递对象几乎总是一个非常糟糕的主意,因为这意味着无用的副本,而应该通过引用传递它们。
这不是一个好的建议通常,具体取决于对象。在C++11之前,它有时是必要的(因为您可能希望对象是不可复制的),但在C++11中,它是从不必要的。您仍然可以这样做,但始终通过引用传递值从来都不是必需的。如果它包含已分配的内存或其他内容,则可以按值移动它。显然,如果这是一种"看但不做"的事情,const&
就可以了。
简单的结构对象,大概像Eigen的Vector2d
,可能足够便宜,可以复制(尤其是在x86-64中,指针是64位),复制对性能来说意义不大。同时,它是开销(理论上),所以如果您使用性能关键型代码,它可能会有所帮助。
再说一遍,它可能不会。
Eigen似乎在谈论的特定崩溃问题与对象的对齐有关。然而,大多数C++03编译器特定的对齐支持在所有情况下都能保证这种对齐。所以没有理由"让你的程序崩溃!"。我从未见过基于SSE/AltaVec/etc的库使用编译器特定的对齐声明,导致值参数崩溃。我用了不少。
所以,如果他们有某种崩溃问题,那么我会认为Eigen是。。。可疑的优点。并非没有进一步调查。
此外,如果一个对象通过值传递是不安全的,正如Eigen文档所建议的那样,那么处理这一问题的正确方法是使该对象不可复制构造。复制分配是可以的,因为它需要一个已经存在的对象。然而,Eigen没有这样做,这再次表明开发人员错过了API设计的一些细节。
然而,对于记录,C++11具有alignas
关键字,这是声明对象应具有特定对齐的标准方法。
另外,为什么按值返回这样的对象没有问题?
谁说没有(注意复制问题,而不是对齐问题)?不同之处在于,不能通过引用返回临时值。所以他们不这么做是因为这是不可能的。
他们可以在C++11:中做到这一点
class alignas(16) Matrix4f
{
// ...
};
现在,类将始终在16字节的边界上对齐。
另外,也许我很傻,但这不应该成为一个问题。给定这样一个类:
class Matrix4f
{
public:
// ...
private:
// their data type (aligned however they decided in that library):
aligned_data_type data;
// or in C++11
alignas(16) float data[16];
};
编译器现在有义务在16字节的边界上分配一个Matrix4f
,因为这会破坏它;类级别CCD_ 5应该是冗余的。但不知怎么的,我过去一直被认为是错的。
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 为什么可以将左值传递给"std::async",即使它引用了右值
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 64位机器上的C++内存对齐
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 使 std::vector 分配对齐内存的现代方法
- C++ cout 将双精度对齐到精度 2 并正确对齐
- 在 64 位边界上对齐C++结构数组?
- 哪些值存储在对齐的结构/类对象的填充字节中
- 有没有办法将来自不同语言的这两个值对齐?
- MMAP是否返回对齐的指针值
- C 分配器的STD :: Align_val_t的有效对齐值是多少
- 如何将值与给定的对齐方式对齐
- 如果浮点值是16字节对齐的,是否可以将其直接转换为__m128
- 如何以标准方式从未对齐的内存中获取值
- 为什么长长值与 8 字节边界对齐
- C++对齐的未来:通过值传递
- C++为什么将左值传递给move构造函数对模板有效
- 对齐会影响sizeof的值吗?