C ++ «вернуть» результат выражения - PullRequest
0 голосов
/ 18 января 2019

Есть ли разница между вычислением выражений между двумя приведенными ниже операторами возврата, основанными на дополнительных скобках?

    return a++ *(-b+123.456)/999.12344;

против

    return (a++ *(-b+123.456)/999.12344);

Язык программирования C ++ Стандарты CPP 98'ish (До C ++ 11)

Надеюсь, вопрос ясен. Ожидается, что выражение будет полностью оценено.

Ответы [ 3 ]

0 голосов
/ 18 января 2019

Неаккуратная речь x - это то же самое, что и (x) (см. этот ответ для ответа на "строгую речь";). Добавление скобок вокруг полного выражения ничего не меняет в отношении приоритета оператора .

PS: он оказывает неясное влияние на оптимизацию возвращаемого значения (подробности см. в этом ответе ). Хотя это определенно не влияет на возвращаемое значение.

0 голосов
/ 18 января 2019

Есть различия. Использование скобок устранит оптимизация возвращаемого значения .

Если, например, a и / или b были объектами с перегруженными всеми подходящими операторами, то использование скобок может привести к дополнительным затратам на копирование значения объекта.

Для простых старых данных разницы нет, в зависимости от мерзости C ++ 11

decltype(auto) ub_server() { int a; return (a);}

, который фактически дает вам свисающую ссылку .

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

0 голосов
/ 18 января 2019

Есть ли какая-либо разница между оценкой выражений между двумя приведенными ниже операторами возврата, основанными на дополнительных скобках?

Нет; круглые скобки полностью избыточны в этом случае .


Выражение expr на самом деле не совпадает с выражением (expr), и вы можете наблюдать это с помощью return, поскольку в последнем случае исключение копирования / перемещения запрещено:

#include <iostream>

struct T
{
    T() { std::cout << "T()\n"; }
    T(const T&) { std::cout << "T(const T&)\n"; }
    T(T&&) { std::cout << "T(T&&)\n"; }
    ~T() { std::cout << "~T()\n"; }
};

T foo()
{
    T t;
    return t;
}

T bar()
{
    T t;
    return (t);
}

int main()
{
    std::cout << "Test 1\n------\n";
    foo();
    std::cout << '\n';
    std::cout << "Test 2\n------\n";
    bar();
}

Выход:

Test 1
------
T()
~T()

Test 2
------
T()
T(T&&)
~T()
~T()

( живая демоверсия )

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

Но, эй, ничего из этого не имеет отношения к простому арифметическому выражению.

...