Можно ли обеспечить исключение копирования? - PullRequest
7 голосов
/ 26 мая 2011

Копирование elision - это аккуратный метод оптимизации, и в некоторых случаях использование elision в действительности может быть быстрее , чем передача ссылок «вручную».

Итак, давайте предположим, что вы определили критический путь к коду, в котором вы полагаетесь на тот факт, что компилятор выполняет определение копии для пути к коду для максимальной производительности.

Но теперь вы полагаетесь на оптимизацию компилятора.

Существует ли какой-либо (очевидно, специфичный для компилятора) способ убедиться, что удаление копии действительно выполняется и что компилятор (или другой инструмент) генерирует предупреждение / ошибку, если удаление копии не может быть выполнено?

(Я имею в виду нечто отдаленно похожее на __forceinline в Visual C ++, которое выдаст предупреждение, если отмеченная функция не будет встроена компилятором.)

Ответы [ 3 ]

4 голосов
/ 26 мая 2011

Не совсем, за исключением помещения assert(false); в конструктор копирования.

В противном случае используйте ваш любимый профилировщик, чтобы измерить, что интересные части вашего приложения достаточно быстрые.

4 голосов
/ 26 мая 2011

номер

Но вы можете написать эквивалентный, хотя и нечитаемый, код:

BigObj f()
{
    BigObj x(g());
    x.someMethod();
    return x;
}

//...
BigObj z = f();
//...

переведено (с пропуском копии) на:

void f(BigObj* obj)
{
    new(obj) BigObj(g());
    obj->someMethod();
}

//...
char z[sizeof(BigObj)];
f((BigObj*)&z[0]);
//...
((BigObj*)&z[0])->~BigObj();

А если серьезно, просто напишите свой код таким образом, чтобы компилятор мог исключить копию. То есть вернуть только один объект без ветвления:

BigObj f()
{
    BigObj x, y;
    // use x and y
    if(condition)
        return x;
    else
        return y;
    // cannot be elided
}


BigObj f()
{
    if(condition)
    {
        BigObj x;
        return x;
    }
    else
    {
        BigObj y;
        return y;
    }
    // can be elided
}
2 голосов
/ 27 июня 2016

В C ++ 1z (ожидается 2017), в некоторых случаях потребуется гарантировать разрешение на копирование:

http://www.open -std.org / jtc1 / sc22 / wg21 / docs / paper /2015 / p0135r0.html

В поддержку коммунальной функции компилятора cppreference.com вики GCC 7+ и Clang 4+ гарантируют это.

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

Кроме того, для того, чтобы конструктор копирования был недоступен, когда применяется оптимизация, вероятно, потребуется более новый стандарт языкавключен во время компиляции или использования свободного или расширенного режима, который не требует строгого соответствия (например, потенциально GCC -fpermissive).

...