2016-08-08 27 views
3

Предоставляет ли стандартный C++ 11 гарантию, что все 3 временных объекта были созданы до начала выполнения функции?Предоставляет ли стандартный C++ 11 гарантию того, что временный объект, переданный функции, будет создан перед вызовом функции?

Даже если временный объект передается как:

  1. объект
  2. Rvalue ссылка
  3. передается только член временного объекта

http://ideone.com/EV0hSP

#include <iostream> 
using namespace std; 

struct T { 
    T() { std::cout << "T created \n"; } 
    int val = 0; 
    ~T() { std::cout << "T destroyed \n"; } 
}; 

void function(T t_obj, T &&t, int &&val) { 
    std::cout << "func-start \n"; 
    std::cout << t_obj.val << ", " << t.val << ", " << val << std::endl; 
    std::cout << "func-end \n"; 
} 

int main() { 

    function(T(), T(), T().val); 

    return 0; 
} 

Выход:

T created 
T created 
T created 
func-start 
0, 0, 0 
func-end 
T destroyed 
T destroyed 
T destroyed 

Рабочий проект, стандарт для программирования языка C++ 2016-07-12: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf

§ 5.2.2 Функция вызова

§ 5.2.2

1 A вызов функции представляет собой постфиксное выражение , за которым следуют круглые скобки, содержащие возможно пустой список номеров инициализаторов, разделенных запятыми , которые составляют аргументы функции.

Но может быть любой из T создана после Func стартером?

Или есть способ передать аргументы как g/r/l/x/pr-value, чтобы функция запускалась до создания временного объекта?

enter image description here

+0

Непонимающий вопрос. Как могла бы функция быть любой, если бы, когда ее тело начало выполняться, ее аргументы еще не существовали? –

+0

@underscore_d В C++ это не может быть то, что четко описано в стандарте. Но если бы это не было описано в стандарте, то: ** 1. ** 'function()' может быть встроена. ** 2. ** Объект может быть сконструирован при первом использовании этого объекта даже после некоторого кода из функции - поскольку компилятор может изменить порядок любой операции, если он не изменится. Наблюдаемое поведение (не имеет/выхода, памяти, ...) - ** § 1.9 Исполнение программы 1, 5, 8 **. Цитата: «компилятор может свободно переупорядочивать инструкции и операции, но им это нравится». http://stackoverflow.com/questions/30606924/can-function-calls-be-reordered – Alex

+0

Правильно, # 2 помогает мне понять и сделать это хорошим моментом, который, как представляется, исключается из требования последовательности. Я все еще жду, когда C++ получит собственный синтаксис для лениво инициализированных объектов ... Примерно # 1, я уверен, что он все еще может быть встроен, не так ли? просто компилятор должен был сначала создать три аргумента (неопределенно упорядоченные между собой) и сохранить их для использования в встроенном теле. –

ответ

11

[intro.execution]/16:

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

7

С [expr.call]/8 мы имеем

[Примечание: оценки выражения постфикса и аргументов являются все unsequenced относительно друг друга. Все побочные эффекты оценок аргументов секвенированы до ввода функции (см. 1.9). -end note]

Это означает, что все параметры сконструированы до ввода функции.

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

 Смежные вопросы

  • Нет связанных вопросов^_^