Будущее выравнивания С++: переход по значению? - программирование
Подтвердить что ты не робот

Будущее выравнивания С++: переход по значению?

Чтение документации библиотеки Eigen, я заметил, что некоторые объекты не могут передаваться по значению. Есть ли какие-либо события в С++ 11 или запланированные разработки, которые позволят безопасно передавать такие объекты по значению?

Кроме того, почему нет проблем с возвратом таких объектов по значению?

4b9b3361

Ответ 1

Они могли сделать это в С++ 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];
};

Теперь компиляторы обязаны выделять Matrix4f на 16-байтной границе, потому что это сломает его; уровень класса alignas должен быть избыточным. Но в прошлом я был известен как ошибочный.

Ответ 2

Вполне возможно, что Eigen - это просто ужасно написанная библиотека (или просто плохо продуманная); просто потому, что что-то в сети не делает это правдой. Например:

Передача объектов по значению почти всегда является очень плохой идеей в С++, так как это означает бесполезные копии, и вместо этого следует передавать их по ссылке.

Это не хороший совет в целом, в зависимости от объекта. Иногда требуется pre-С++ 11 (потому что вы можете захотеть, чтобы объект был незамкнутым), но в С++ 11 он никогда не нужен. Вы все еще можете это сделать, но никогда не нужно всегда передавать значение по ссылке. Вы можете просто переместить его по значению, если он содержит выделенную память или что-то в этом роде. Очевидно, что если это "вид, но не дотрагивайтесь", const& в порядке.

Простые объекты структуры, предположительно похожие на Eigen Vector2d, вероятно, достаточно дешевы для копирования (особенно в x86-64, где указатели - 64 бита), что копия не будет означать многого с точки зрения производительности. В то же время, это накладные расходы (теоретически), поэтому, если вы находитесь в критическом для производительности коде, это может помочь.

Тогда это может и не быть.

Особая проблема сбоя, о которой говорит Эйген, связана с выравниванием объектов. Тем не менее, большая поддержка С++ 03 для поддержки компилятора гарантирует выравнивание во всех случаях. Поэтому нет причин, которые должны "заставить вашу программу сбой!". Я никогда не видел библиотеку SSE/AltaVec/etc, которая использовала объявления выравнивания, специфичные для компилятора, которые вызывали сбои со значениями параметров. И я использовал немало.

Итак, если у них есть какая-то проблема с крушением, я бы подумал, что Эйген будет... сомнительной заслугой. Не без дальнейшего изучения.

Кроме того, если объект небезопасен для передачи по значению, как предлагают предложения Eigen, тогда правильный способ справиться с этим состоит в том, чтобы сделать объект неконкурентоспособным. Назначение копирования будет прекрасным, поскольку для этого требуется уже существующий объект. Однако Eigen этого не делает, что опять же предполагает, что разработчики пропустили некоторые тонкости дизайна API.

Однако для записи С++ 11 имеет ключевое слово alignas, которое является стандартным способом объявить, что объект должен иметь определенное выравнивание.

Кроме того, почему нет проблем с возвратом таких объектов по значению?

Кто говорит, что нет (замечая проблему копирования, а не проблему выравнивания)? Разница в том, что вы не можете вернуть временное значение по ссылке. Поэтому они не делают этого, потому что это невозможно.