繁体   English   中英

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

[英]QString::utf16(): Is it UB or not?

让我们看下面的源代码:

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怎么办? 根据https://en.cppreference.com/w/cpp/language/const_cast修改具有constness的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?

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

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

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

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

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

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

尽管如此,抛弃constness是一个非常糟糕的主意,因为在函数内部,您永远都不知道所讨论的对象是真正的const对象还是仅是最初创建的非const对象的指针/引用,因此总会有 UB的内在危险!

最好的就是没有const函数:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM