2016-10-01 2 views
13

goto или switch может перепрыгнуть через заявление-заявление, учитывая, что он не имеет инициализатора, а конструкция тривиальна и что объект также является тривиально разрушаемым.При переходе по декларации, зачем нужен тривиальный деструктор?

В чем смысл ограничения на деструктор?

struct trivial { 
    trivial() = default; 
    ~ trivial() = default; 
}; 

struct semi_trivial { 
    semi_trivial() = default; 
    ~ semi_trivial() noexcept { do_something(); } 
}; 

void foo() { 
    goto good_label; // OK 
    trivial foo; 
good_label: 

    goto bad_label; // Error: this goto statement 
    semi_trivial bar; // cannot jump over this declaration. 
bad_label: 

    std::cout << "hi\n"; 
} 

ответ

5

Текущая формулировка является результатом N2762. В статье дается следующее объяснение:

6,7 stmt.dcl:

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

Я думаю, что дело иметь в виду:

int i = 2; 
switch (i) { 
    case 1: 
    semi_trivial st; 
    do_something(st); 
    break; 
    case 2: 
    break; // should st be destructed here? 
} 

И действительно, это не простой вопрос. Вызов деструктора не будет, очевидно, правильным. Нет никакого хорошего способа сказать, следует ли его называть. Переменная st здесь используется только в операциях case 1, и программисты были бы удивлены, если ее деструктор получил вызванный case 2 оператор break, хотя он был полностью не использован и не был сконструирован.

+0

@Barry Первый 'break;' никогда не выполняется, так как 'i' имеет значение' 2'. Вопрос заключается в том, должен ли * second * 'break;' разрушать 'st', хотя он не был инициализирован и не использовался в операциях' case 2'. Без специальной формулировки, чтобы предотвратить ее, она будет разрушена, но ее разрушение может быть неправильным. Отсюда запрет прыгать на «случай 2». – hvd

+0

А, да. Должно добавить все это к ответу. – Barry

+0

Спасибо! При чтении между строками бумага, похоже, говорит о том, что деструктор должен работать, если был запущен тривиальный конструктор. Для меня, если объект можно использовать в пределах области действия, тогда он эффективно построен, и деструктор должен быть запущен. Хммм ... – Potatoswatter

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