QString :: utf16():是否为UB?

时间:2018-07-20 09:47:41

标签: c++ qt undefined-behavior

让我们看下面的源代码:

const ushort *QString::utf16() const
{
    if (IS_RAW_DATA(d)) {
        // ensure '\0'-termination for ::fromRawData strings
        const_cast<QString*>(this)->reallocData(uint(d->size) + 1u);
    }
    return d->data();
}

reallocData()修改d指针类成员 d ,请参见https://code.woboq.org/qt5/qtbase/src/corelib/tools/qstring.cpp.html#_ZN7QString11reallocDataEjb。如果QString对象是const怎么办?根据{{​​3}},通过抛弃常量来修改const对象是UB:

struct type {
    int i;

    type(): i(3) {}

    void f(int v) const {
        const_cast<type*>(this)->i = v; // OK as long as the type object isn't const
    }
};

type t; // if this was const type t, then t.f(4) would be undefined behavior
t.f(4);

在这段特定的代码(QString :: utf16())中我们有UB吗?

2 个答案:

答案 0 :(得分:5)

如果在其上调用此方法的QString对象是const限定的,则这确实是UB:

QString const str{"whatever"};
str.utf16();

请注意,这里重要的一点是对象是const限定的,而不是方法是const限定的。

答案 1 :(得分:0)

当(且仅当)所涉及的对象最初是创建的const时,这是未定义的行为:

QString const sc("whatever");
sc.utf16();                  // undefined behaviour!

QString s("whatever");
QString const& scr = s;
scr.utf16();                 // NOT undefined behaviour!

仍然,抛弃constness是一个非常糟糕的想法,因为在函数内部,您永远不知道所讨论的对象是真正的const对象还是仅是对象的指针/引用最初创建的是非常量,因此UB总是存在 内在危险!

最好的就是没有const函数:

const ushort* QString::utf16()
{
    //...
}

视情况而定,然后即使原始对象实际上是 ,用户也不得不创建非常量副本,但这总是比冒险使用UB更好!

>