eye*_*ash 5 c++ pointers reference pointer-arithmetic undefined-behavior
我有以下 C++ 代码:
void bar(int&);
void baz();
void foo(std::vector<int>& v) {
int* pointer_to_last = v.data() + (v.size() - 1);
if (v.size() > 0 && *pointer_to_last == 42) {
bar(*pointer_to_last);
} else {
baz();
}
}
Run Code Online (Sandbox Code Playgroud)
我无条件创建一个指向向量最后一个元素的指针,但仅当向量不为空时才取消引用该指针。根据标准,这是否合法,或者上面的代码是否包含未定义的行为?
如果上面的程序合法,那么下面的程序也合法吗?
void bar(int&);
void baz();
void foo(std::vector<int>& v) {
int& reference_to_last = v.back();
if (v.size() > 0 && reference_to_last == 42) {
bar(reference_to_last);
} else {
baz();
}
}
Run Code Online (Sandbox Code Playgroud)
回调空容器会导致未定义的行为。
所以我假设这个程序不合法。是否有 GCC 或 Clang 的编译器标志或任何静态分析器可以对上述代码发出警告?
两者都是非法的。前者被 UBSAN (aka -fsanitize=undefined) 拒绝(参见[expr.add]/4)
runtime error: applying non-zero offset 18446744073709551612 to null pointer
Run Code Online (Sandbox Code Playgroud)
Error: attempt to access an element in an empty container.
Run Code Online (Sandbox Code Playgroud)
是否有 GCC 或 Clang 的编译器标志
上面两个加上-fsanitize=address.
-D_GLIBCXX_DEBUG是 libstdc++ 特定的。如果您将 Clang 与 libc++ 而不是 libstdc++ 一起使用,则使用-D_LIBCPP_ENABLE_DEBUG_MODE. (似乎需要 libc++ 17 或更新版本,他们的调试模式被破坏了一段时间。它似乎也缺乏迭代器验证。:c)