使用数组的地址获取过去的指针

Stu*_*sen 7 c c++ undefined-behavior c++11 c11

在C和C++中,使用past-the-end指针来编写可以在任意大型数组上运行的函数通常很有用.C++提供了一个std::end重载,使这更容易.另一方面,在C中,我发现看到一个像这样定义和使用的宏并不罕见:

#define ARRAYLEN(array) (sizeof(array)/sizeof(array[0]))

// ...

int a [42];
do_something (a, a + ARRAYLEN (a));
Run Code Online (Sandbox Code Playgroud)

我还看到了一个指针算术技巧,用于让这些函数在单个对象上运行:

int b;
do_something (&b, &b + 1);
Run Code Online (Sandbox Code Playgroud)

我发现类似的事情可以用数组来完成,因为它们被C(并且我相信,C++)认为是"完整的对象".给定一个数组,我们可以在它之后立即派生一个指向数组的指针,取消引用该指针,并对结果对数组的引用使用数组到指针转换来获取原始数组的过去指针:

#define END(array) (*(&array + 1))

// ...

int a [42];
do_something (a, END (a));
Run Code Online (Sandbox Code Playgroud)

我的问题是:在解除引用指向不存在的数组对象的指针时,此代码是否显示未定义的行为?我对C和C++的最新版本对这段代码的评价感兴趣(不是因为我打算使用它,因为有更好的方法可以实现相同的结果,但因为它是一个有趣的问题).

Ben*_*igt 1

我在自己的代码中使用了它,如(&arr)[1].

我非常确定它是安全的。数组到指针的衰减不是“左值到右值的转换”,尽管它以左值开始并以右值结束。