C++对齐的未来:通过值传递

The future of C++ alignment: passing by value?

本文关键字:值传 对齐 未来 C++      更新时间:2023-10-16

阅读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应该是冗余的。但不知怎么的,我过去一直被认为是错的。