Стандартные библиотечные функции C, включенные в C++, создают исключение?

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

String &String::operator =( const char *str ) {
    // state is changed
    delete [] s_;                                        

    if( !str ) str = "";

    // exception might occur because of new operator
    s_ = strcpy( new char[ strlen(str)+1 ], str );

    return *this;
}

Читая, я удивлялся, что функции библиотеки C генерируют исключения в C++? Я знаю, что в C нет исключений, но, поскольку мы используем компилятор C++, могут быть исключения.

Итак, можем ли мы рассматривать стандартные функции lib как безопасные вызовы функций?

Спасибо.

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

String &String::operator =( const char *str ) {
    if( !str ) str = "";
    char *tmp = strcpy( new char[ strlen(str)+1 ], str );
    delete [] s_;
    s_ = tmp;
    return *this;
}

3 ответа

Решение

Вообще говоря, стандарт C++ не модифицирует ни одну из функций из стандарта C, за исключением того, что указатели должны ссылаться на реальные функции, а не на макросы. Таким образом, функции из стандартной библиотеки C не могут вызвать исключение ни при каких обстоятельствах, если стандарт C определяет, что может делать функция.

В число лазеек, которые допускают исключения, входят такие вещи, как неопределенное поведение или обратные вызовы (например, передача компаратора в qsort это вызывает исключение... хотя я на самом деле не уверен, разрешено ли это стандартом C++). Я не думаю, что особенно вероятно, что провайдеры библиотек потратят какие-либо усилия, пытаясь добавить функцию создания исключений в ситуациях, когда поведение не определено.

Читая, я удивлялся, что функции библиотеки C генерируют исключения в C++?

Нет, если вы используете функции правильно. Как они могли? Это полностью сломало бы обратную совместимость.

Однако, если вы используете их неправильно, происходит неопределенное поведение. И в этом случае компилятор может делать все, что захочет, включая создание исключений.

Например, возьмем следующую программу, которая демонстрирует неопределенное поведение в соответствии со стандартом языка C++:

#include <iostream>
#include <string.h>

int main()
{
    try
    {
        strcpy(nullptr, nullptr);
    }
    catch (...)
    {
        std::cerr << "exception\n";
    }
}

Скомпилируйте его с помощью Visual C++ 2013, используя Структурную обработку исключений, следующим образом:

cl /nologo /Za /EHa /W4 stackru.cpp

Результат программы:

exception

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

Другие вопросы по тегам