Подтвердить что ты не робот

Когда временные объекты, созданные как часть вызова функции, уничтожены?

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

Там практически нет шансов, что это было связно, вот пример:

class A {
public:
    A(int x) : x(x) {printf("Constructed A(%d)\n", x);}
    ~A() {printf("Destroyed A\n");}

    int x;
    int* y() {return &x;}
};

void foo(int* bar) {
    printf("foo(): %d\n", *bar);
}

int main(int argc, char** argv) {
    foo(A(4).y());
}

Если A(4) были переданы непосредственно на foo, он определенно не будет уничтожен до тех пор, пока вызов foo не завершится, но вместо этого я вызываю метод во временном и теряю любую ссылку на него. Я бы инстинктивно подумал, что временная A будет уничтожена до начала foo, но тестирование с GCC 4.3.4 показывает, что это не так; выход:

Построенный A (4)
foo(): 4
Разрушенный A

Вопрос в том, что - поведение GCC, гарантированное спецификацией? Или компилятор разрешил уничтожить временный A перед вызовом foo, не указав указатель на его член, который я использую?

4b9b3361

Ответ 1

Временные объекты существуют до конца полного выражения, в котором они созданы.

В вашем примере объект A, созданный A(4), будет существовать, по крайней мере, до тех пор, пока выражение не закончится сразу после возврата из вызова foo().

Такое поведение гарантируется стандартом языка:

Временные объекты уничтожаются как последний шаг при оценке полного выражения (1.9), который (лексически) содержит точку, в которой они были созданы. Это справедливо, даже если эта оценка заканчивается выдачей исключения (С++ 03 §12.2/3).

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

Ответ 2

§12.2/3: "Временные объекты уничтожаются как последний шаг при оценке полного выражения (1.9), который (лексически) содержит точку, в которой они были созданы".

IOW, вы в безопасности - объект A не должен быть уничтожен до тех пор, пока не вернется foo.

Ответ 3

Временное продолжается до конца выражения, частью которого является - в этом случае это вызов функции.

Ответ 4

Время жизни вашего временного объекта A(4) будет длиться достаточно долго, чтобы вызвать y()

Память, указанная в возврате y(), не является надежной, в зависимости от потоков и распределений, которые могут быть перераспределены, и значение, измененное до того, как вызов foo() использует его.