1

在下面的代码中,作者指出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++ 编译器,因此可能会有异常。

那么,我们可以将 c 标准库函数视为异常安全函数调用吗?

谢谢你。

顺便说一句,为了记录,实现上述功能的正确方法(异常安全)如下。

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

3 回答 3

5

在阅读时,我想知道 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 stackoverflow.cpp

程序结果:

exception
于 2015-03-08T12:10:20.757 回答
3

一般来说,C++ 标准不会修改 C 标准中的任何函数,除了规定标识符应该引用实际函数而不是宏。因此,C 标准库中的函数在 C 标准规定函数可以做什么的任何情况下都不能抛出异常。

允许异常的漏洞包括诸如未定义的行为或回调之类的东西(例如,将比较器传递给qsort它会引发异常......虽然我实际上不确定C++ 标准是否允许这样做)。我认为库提供者不太可能会花任何精力尝试在存在未定义行为的情况下添加抛出异常的功能。

于 2015-03-08T11:53:05.067 回答
0

不 - 仅仅因为您使用 C++ 编译器进行编译并不意味着会抛出异常。C 不支持异常,因此 C 程序不能抛出任何类型的异常。

于 2015-03-08T11:32:57.383 回答