Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Operok
174 / 172 / 64
Регистрация: 15.02.2015
Сообщений: 496
Завершенные тесты: 2
#1

Спецификатор noexcept для класса "исключение" - C++

01.02.2017, 12:45. Просмотров 209. Ответов 8
Метки нет (Все метки)

Доброго все дня!
Стандартный класс std::exception имеет спецификатор noexcept для всех своих методов/операторов/конструкторов. Однако, он работает с копированием строк и, следовательно, с кучей, что либо допускает вероятность std::bad_alloc в конструкторе исключения, либо в случае неудачной аллокации what вернёт некоторое сообщение, размещённое на стеке, вместо переданного в конструктор. Так ли это, поправьте, пожалуйста?
При написании собственного класса исключения, который собирает различную информацию (кто, куда откуда и когда его бросил), стоит ли обезопасить себя от bad_alloc и пользоваться "сишными" функциями-аллокаторами (ну или ловить его, используя те же строки "из коробки"), или не стоит: пускай бросается, там глядишь, кто-нибудь поймает и разберётся (хотя с чем тут разбираться, если bad_alloc)?
Я понимаю, что bad_alloc - это очень критично для программы, и скорее всего нет смысла продолжать её работу, и возникает такая ситуация скорее всего не в случае реальной нехватки памяти, а при попытке получить слишком большой кусок, но как можно определять у функции спецификатор noexcept, если такая вероятность есть?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.02.2017, 12:45
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Спецификатор noexcept для класса "исключение" (C++):

Необработанное исключение в "0x778e15de" в "dir-3.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00000000"
#include <windows.h> #include <d3d9.h> LRESULT __stdcall WndProc(HWND hWnd,...

Необработанное исключение в "0x00412b4a" в "kursovik.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00000004".
Программа компилируется нормально но потом на строчке...

Необработанное исключение в "0x013f2b22" в "123.exe": 0xC0000005: Нарушение прав доступа при записи "0xfdfdfdfd"
Вот функция для удаления столбца: #pragma once #include <iostream> using...

Необработанное исключение в "0x00414558" в "467.exe": 0xC0000005: Нарушение прав доступа при чтении "0xabababbb"
При выполнении этого кода #include <iostream> #include<conio.h> using...

Необработанное исключение в "0x775e15de" в "laba3.exe": 0xC0000005: Нарушение прав доступа при чтении "0xfdfdfdf9".
вылезает ошибка Необработанное исключение в "0x775e15de" в "laba3.exe":...

Необработанное исключение в "0x01082855" в "sort.exe": 0xC0000005: Нарушение прав доступа при записи "0xcccccccc"
Всем привет! помогите мне понять в чём дело. написал программу: #include...

8
hoggy
Заблокирован
01.02.2017, 12:50 #2
Цитата Сообщение от Operok Посмотреть сообщение
Однако, он работает с копированием строк и, следовательно, с кучей, что либо допускает вероятность std::bad_alloc в конструкторе
он не работает ни с какими строками.
вот весь класс:

C++
1
2
3
4
5
6
7
8
class exception {
public:
  exception () noexcept;
  exception (const exception&) noexcept;
  exception& operator= (const exception&) noexcept;
  virtual ~exception();
  virtual const char* what() const noexcept;
}
1
Operok
174 / 172 / 64
Регистрация: 15.02.2015
Сообщений: 496
Завершенные тесты: 2
01.02.2017, 13:17  [ТС] #3
"А слона то я и не приметил". Был уверен, что конструктор: explicit exception(const char*) noexcept; - это часть стандарта.
Однако это не отменяет тот факт, что некоторые компиляторы такой конструктор как-то поддерживают, более того, наследуемый от exception класс invalid_argument имеет таки конструктор(ы) с передаваемой строкой в качестве параметра. Вопросы в силе.
0
Croessmah
++Ͻ
14161 / 8086 / 1513
Регистрация: 27.09.2012
Сообщений: 19,929
Записей в блоге: 3
Завершенные тесты: 1
01.02.2017, 13:31 #4
Цитата Сообщение от Operok Посмотреть сообщение
с передаваемой строкой в качестве параметра.
Если присмотритесь, то он принимает ссылку на объект std::string,
либо же указатель на строку C'шную (помолимся за нее великому нулю),
т.е. сама строка формируется непосредственно в коде пользователя.
Если у пользователя там что-то не получилось - извините.
А как этой строкой распоряжается внутри invalid_argument - неизвестно.
Например, для подобных случаев, возможно,
память уже зарезервирована, а возможно что и нет.
И да, у invalid_argument конструкторы не noexcept, заметьте.
1
MrGluck
Модератор
Эксперт CЭксперт С++
8023 / 4866 / 1425
Регистрация: 29.11.2010
Сообщений: 13,251
01.02.2017, 13:46 #5
Если случился std::bad_alloc, то ничего кроме std::terminate (а именно он вызывается при прокидывании исключения в noexcept методе) и не сделаешь.
Зато noexcept позволяет компилятору оптимизировать код.

Добавлено через 3 минуты
И если посмотреть, то версия с std::string всего-лишь вызывает метод .c_str() и использует перегруженную версию с указателем. Никакого копирования объекта std::string не происходит.
0
Operok
174 / 172 / 64
Регистрация: 15.02.2015
Сообщений: 496
Завершенные тесты: 2
01.02.2017, 13:53  [ТС] #6
Цитата Сообщение от Croessmah Посмотреть сообщение
И да, у invalid_argument конструкторы не noexcept, заметьте.
Да, заметил. Обратил внимание с начала, что в описании возможных исключений их нет и отождествил это с noexcept.
Значит, не определяю методы класса-исключения как noexcept.

Цитата Сообщение от Croessmah Посмотреть сообщение
Если присмотритесь, то он принимает ссылку на объект std::string,
либо же указатель на строку C'шную (помолимся за нее великому нулю),
т.е. сама строка формируется непосредственно в коде пользователя.
Если у пользователя там что-то не получилось - извините.
Так invalid_argument (или logic_error) должен как-то скопировать строку себе (именно сишную строку), мало ли откуда пользователь её получил, может там rvalue какой-нибудь throw logic_error(string("что-то ") + "пошло " + "не так!");, а соответствующего конструктора нету.
0
Renji
2142 / 1501 / 457
Регистрация: 05.06.2014
Сообщений: 4,339
01.02.2017, 15:39 #7
Цитата Сообщение от Operok Посмотреть сообщение
При написании собственного класса исключения, который собирает различную информацию (кто, куда откуда и когда его бросил), стоит ли обезопасить себя от bad_alloc и пользоваться "сишными" функциями-аллокаторами
Нафиг аллокаторы.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class MyException:public std::exception
{
public:
    MyException(const char*format,...)noexcept
    {
        va_list args;
        va_start(args,format);
        vsnprintf(data,1024,format,args);
        va_end(args);
    }
 
    const char*what()const noexcept{return data;}
 
private:
    char data[1024];//Вам мало килобайта? Нет, серьезно?
};
int main()
{
    try
    {
        throw MyException("%d*%d=%d",2,2,4);
    }
    catch(const std::exception&error)
    {
        std::cout<<error.what()<<std::endl;
    }
    return 0;
}
1
Operok
174 / 172 / 64
Регистрация: 15.02.2015
Сообщений: 496
Завершенные тесты: 2
01.02.2017, 15:56  [ТС] #8
Цитата Сообщение от Renji Посмотреть сообщение
Нафиг аллокаторы.
...
Если в одной функции будет порядка десятка-двух ответвлений с возможным броском этого (или наследуемого) исключения, то такую функцию опасно будет вызывать в другом потоке (стек не резиновый).

Не по теме:

Цитата Сообщение от Renji Посмотреть сообщение
Вам мало килобайта? Нет, серьезно?
Видел, как одно приложение .NET выкидывало необработанное исключение, текст которого с развернутым стеком вызовов мог и не уместиться в 1кБ :D

0
Renji
2142 / 1501 / 457
Регистрация: 05.06.2014
Сообщений: 4,339
01.02.2017, 16:06 #9
Цитата Сообщение от Operok Посмотреть сообщение
Если в одной функции будет порядка десятка-двух ответвлений с возможным броском этого (или наследуемого) исключения, то такую функцию опасно будет вызывать в другом потоке (стек не резиновый).
Стек сейчас порядка нескольких мегабайт. Даже если каждая функция будет класть туда по килобайту, потребуется тысяча вложенных вызовов чтобы стек переполнить. Так что для большинства задач он вполне резиновый.
0
01.02.2017, 16:06
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.02.2017, 16:06
Привет! Вот еще темы с решениями:

Необработанное исключение в "0x1027c9c7 (msvcr100d.dll)" в "gh.exe": 0xC0000005: Нарушение прав доступа при чтении "0xfeeefeee".
// gh.cpp: определяет точку входа для консольного приложения. // #include...

Ошибка Необработанное исключение в "0x001d18f8" в "lr7v2.exe": 0xC0000005: Нарушение прав доступа при чтении "0xcdcdcde9"
class Hdd { public: char Hdd_name; int total_space; int free_space;...

Необработанное исключение в "0x0fc1d484 (msvcr100d.dll)" в "1.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00aee0af"
помогите разобраться в чем ошибка? необходимо, чтобы ввод массива...

Необработанное исключение в "0x54a2d2e9 (msvcr100d.dll)" в "3.exe": 0xC0000005: Нарушение прав доступа при записи "0xcccccccc".
#include&lt;iostream&gt; #include&lt;conio.h&gt; #include&lt;string&gt; #include&lt;stdlib.h&gt;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru