c++ - 检测对临时的悬空引用

标签 c++ c++11 undefined-behavior clang++ dangling-pointer

Clang 3.9 极大地重用了临时使用的内存。

此代码为UB(简化代码):

template <class T>
class my_optional
{
public:
    bool has{ false };
    T value;

    const T& get_or_default(const T& def)
    {
        return has ? value : def;
    }
};

void use(const std::string& s)
{
    // ...
}

int main()
{
    my_optional<std::string> m;
    // ...
    const std::string& s = m.get_or_default("default value");
    use(s); // s is dangling if default returned
}

我们有大量类似上面的代码(my_optional 只是一个简单的例子来说明它)。

因为UB所有clang编译器从3.9开始重用这 block 内存,是合法的行为。

问题是:如何在编译时检测这种悬空引用,或者在运行时使用 sanitizer 之类的东西?没有 clang sanitizer 可以检测到它们。

更新。请不要回答:“使用 std::optional”。仔细阅读:问题与它无关。
更新2。请不要回答:“你的代码设计不好”。仔细阅读:问题与代码设计无关。

最佳答案

您可以通过添加额外的重载来检测此特定 API 的滥用情况:

const T& get_or_default(T&& rvalue) = delete;

如果提供给 get_or_default 的参数是一个真正的右值,它将被选择,因此编译将失败。

至于在运行时检测此类错误,请尝试将 Clang 的 AddressSanitizer 与 use-after-return (ASAN_OPTIONS=detect_stack_use_after_return=1) 和/或 use-after-scope (-fsanitize- address-use-after-scope) 检测已启用。

关于c++ - 检测对临时的悬空引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42340073/

相关文章:

c++ - 符号查找错误 : undefined symbol: _alloca

c++ - 如何执行用c++编写的程序的运行时间?

c++ - 将函数调用表达式传递给 noexcept 有什么意义?

c++ - 指定函数参数类型,但不是变量

c++ - std::forward_list - 如何在末尾插入元素

c++ - 如何确定key的 "(default)"值

c++ - 如何检查函数参数的类型?

rust - 在 Rust 中借助原始指针进行运行时借用管理是未定义的行为吗?

c - 有符号整数溢出是否定义了未定义的行为或实现?

一对指向采用不同类型参数的不同函数的指针可以兼容吗?