2

我们有一个这样的函数:

const std::string& ConvertToString(Enum e)
{
    static const std::string enumStrings[4] =
    {
        std::string("first"),
        std::string("second"),
        std::string("third"),
        std::string("unknown")
    }

    int enumOrd = static_cast<int>(e);
    if (e < 0 || e > 2)
    {
        return enumStrings[3];
    }

    return enumStrings[enumOrd];
}

现在,问题是这个函数在 main() 返回之后被调用,并且由于该静态数组已经被破坏,它正在崩溃。我想把它改成这样:

std::string ConvertToString(Enum e)
{
    switch (static_cast<int>(e))
    {
        case 0: return std::string("first");
        case 1: return std::string("second");
        case 2: return std::string("third");
        default: return std::string("unknown");
    }
}

我想知道此更改是否有可能破坏任何调用此函数的代码。我想不出任何问题(只要返回的类在 const 方法中没有做鬼鬼祟祟的事情,但 std::string 应该没问题,尤其是在 const ref -> value 的转换中,但也许我'我错过了一些东西。

4

2 回答 2

7

可能出错的一种方法是调用代码执行以下操作:

const char* s = ConvertToString(first).c_str();

然后存储在s某处,以后再访问,以为std::string返回值所引用的对象ConvertToString永远不会被销毁。

当然,在这种情况下,调用代码无论如何都很糟糕。

于 2013-07-16T19:43:49.403 回答
2

您可以破坏依赖于ConvertToString产生相同对象的不同调用的代码:

for (std::string::const_iterator it = ConvertToString(first).begin();
     it != ConvertToString(first).end(); ++it) {
   // undefined behavior: cannot compare iterators referring 
   // to two different containers/strings
}

另一方面说明,您的实现可能无法达到您的预期。特别是如果您的枚举被定义为enum Enum { first, second, third };代码:

if (e < 0 || e > 2) {
   return enumStrings[3];
}

可以被优化编译器完全删除,并且unknown可能永远不会被函数返回。原因是Enum枚举不能合法地保存任何不是枚举数位掩码的值(在这种情况下:0、1、2、3)。这样做是未定义的行为。编译器可以使用这些知识来优化代码并删除e < 0和/或将测试条件转换为单个e == 3.

于 2013-07-16T19:53:14.227 回答