无条件创建指向向量最后一个元素的指针合法吗?

问题描述 投票:0回答:2

我有以下 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 的编译器标志或任何静态分析器可以对上述代码发出警告?

c++ pointers reference undefined-behavior pointer-arithmetic
2个回答
2
投票

两者都是非法的。前者被 UBSAN 拒绝(又名 -fsanitize=undefined

)(参见 
[expr.add]/4

runtime error: applying non-zero offset 18446744073709551612 to null pointer
后者被

-D_GLIBCXX_DEBUG

拒绝:

Error: attempt to access an element in an empty container.

有 GCC 或 Clang 的编译器标志吗

以上两项,加上

-fsanitize=address


0
投票
根据 C++20 标准,行为未定义(7.6.6 加法运算符)

(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) — 否则,行为未定义

© www.soinside.com 2019 - 2024. All rights reserved.