我有以下 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();
}
}
我无条件创建一个指向向量最后一个元素的指针,但仅当向量不为空时才取消引用该指针。根据标准,这是合法的还是上面的代码包含未定义的行为?
如果上面的程序合法,那么下面的程序也合法吗?
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();
}
}
std::vector::back
的参考说
回调空容器会导致未定义的行为。
所以我假设这个程序不合法。是否有 GCC 或 Clang 的编译器标志或任何静态分析器可以对上述代码发出警告?
两者都是非法的。前者被 UBSAN 拒绝(又名 -fsanitize=undefined
)(参见
[expr.add]/4
)
runtime error: applying non-zero offset 18446744073709551612 to null pointer
后者被拒绝:
Error: attempt to access an element in an empty container.
有 GCC 或 Clang 的编译器标志吗以上两项,加上
-fsanitize=address
。
(4.1) — 如果 P 计算结果为空指针值并且 J 计算结果为 0, 结果是空指针值。(4.2) — 否则,如果 P 指向数组的数组元素 i 具有 n 个元素的对象 x (9.3.4.5),80 表达式 P + J 和 J + P (其中 J 的值为 j)指向(可能是假设的)数组 x 的元素 i + j 如果 0 ≤ i + j ≤ n 并且表达式 P - J 指向 如果 0 ≤ i − j ≤ n,则 x 的(可能是假设的)数组元素 i − j。
(4.3) — 否则,行为未定义