LINUX.ORG.RU

История изменений

Исправление kvpfs_2, (текущая версия) :

Почему? В случае basic safety, все данные тоже в порядке, и все инварианты выполняются.

Ну вот давайте на примере:

struct Linkable {
   //...private data
   set_link(Linkable_iface &iface);
   // there is no unlink
};
Linkable a, b;
void do() {
   a.set_link(b);
   b.set_link(a); // #1
}

на #1 кидается исключение, операция не закончена. У а линк создан у b нет, пусть каждый из них и остался в валидном состоянии, но в целом программа будет вести себя некорректно.

Другой пример:

struct A {
   //...private data
   process_input_data(vector<char> &src);
}
A a, b;
void fn() {
   vector<char> input;
   //... fill input somehow
   a.process_input_data(input);
   b.process_input_data(input); #1
}

Аналогино - на #1 летит исключение, a учел новый данный, b - нет. Объекты в программе находятся в рассогласованном состоянии. Всё, это не может дальше корректно работать с предсказуемым результатом.

Тут вообще не понял. Гарантии обеспечивает кидающая, а не проверяющая сторона.

Ну а как, вам придется оборачивать всё в try catch любой потенциально кидающий вызов и пытаться вернуть состояние обратно в случае исключения. Вместо if (return …) -> catch (…)

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

Исправление kvpfs_2, :

Почему? В случае basic safety, все данные тоже в порядке, и все инварианты выполняются.

Ну вот давайте на примере:

struct Linkable {
   //...private data
   set_link(Linkable_iface &iface);
   // there is no unlink
};
Linkable a, b;
void do() {
   a.set_link(b);
   b.set_link(a); // #1
}

на #1 кидается исключение, операция не закончена. У а линк создан у b нет, пусть каждый из них и остался в валидном состоянии, но в целом программа будет вести себя некорректно.

Другой пример:

struct A {
   //...private data
   process_input_data(vector<char> &src);
}
A a, b;
void fn() {
   vector<char> input;
   //... fill input somehow
   a.process_input_data(input);
   b.process_input_data(input); #1
}

Аналогино - на #1 летит исключение, a учел новый данный, b - нет. Объекты в программе находятся в рассогласованном состоянии. Всё, это не может дальше корректно работать с предсказуемым результатом.

Тут вообще не понял. Гарантии обеспечивает кидающая, а не проверяющая сторона.

Ну а как, вам придется оборачивать всё в try catch любой потенциально кидающий вызов и пытаться вернуть состояние обратно в случае исключения. Вместо if (return …) -> catch (…)

Исходная версия kvpfs_2, :

Почему? В случае basic safety, все данные тоже в порядке, и все инварианты выполняются.

Ну вот давайте на примере:

struct Linkable {
   set_link(Linkable_iface &iface);
   // there is no unlink
};
Linkable a, b;
void do() {
   a.set_link(b);
   b.set_link(a); // #1
}

на #1 кидается исключение, операция не закончена. У а линк создан у b нет, пусть каждый из них и остался в валидном состоянии, но в целом программа будет вести себя некорректно.

Другой пример:

struct A {
   process_input_data(vector<char> &src);
}
A a, b;
void fn() {
   vector<char> input;
   //... fill input somehow
   a.process_input_data(input);
   b.process_input_data(input); #1
}

Аналогино - на #1 летит исключение, a учел новый данный, b - нет. Объекты в программе находятся в рассогласованном состоянии. Всё, это не может дальше корректно работать с предсказуемым результатом.

Тут вообще не понял. Гарантии обеспечивает кидающая, а не проверяющая сторона.

Ну а как, вам придется оборачивать всё в try catch любой потенциально кидающий вызов и пытаться вернуть состояние обратно в случае исключения. Вместо if (return …) -> catch (…)