数组的地址是否等于 C++ 中第一个元素的地址?

Does the address of the array equal to that of its first element in C++?

因为WG14/N1570中有下面这句话,所以在C中可以保证:

6.2.5/20 ... An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type.

但是在WG21/N4527中,即在C++中,对应的句子变成了

8.3.4/1 ...An object of array type contains a contiguously allocated non-empty set of N subobjects of type T.

而"describes"改为"contains",不能保证数组的地址等于第一个元素的地址。这种变化是有意的还是无意的?如果是故意的,那么数组的地址是否等于它在 C++ 中的第一个元素的地址?如果是,C++标准中哪一段可以保证?

在 C++ 中,它由 4.2/1 数组到指针转换保证 [conv.array],(我加粗)

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.

这意味着如果你想在 C++ 中获取数组的地址,你会得到一个指向数组第一个元素的指针。即

int a[10];
int* p1 = a;     // take the address of array
int* p2 = &a[0]; // take the address of the first element of the array

标准保证p1p2指向同一个地址。

这取决于你"address of array"的意思。

如果你问一个数组,当转换为指针时,给出的结果是否等于它的第一个元素的地址,那么答案是肯定的。例如;

#include <iostream>

void func(int *x, int *y)
{
     std::cout << "x and y are ";
     if (p != q) std::cout << "NOT ";
     std::cout << " equal\n";
}

int main()
{
    int x[2];

    func(x, &x[0]);
}

这将始终报告两个指针相等。宋元耀解释了原因

但是,x 实际上不是指向数组的指针(并且在此代码中也没有转换为数组)。如果将main()中的func()的调用改为

  func(&x, &x[0]);

那么该语句甚至不会编译。原因是 &x(数组 x 的地址)不是指向 int 的指针 - 它是指向两个 int 的数组的指针,并且不能隐式转换为指向 int.

的指针

但是,该值将是相同的,运行 这段代码可以证明这一点。

#include <iostream>

void func2(void *x, void *y)
{
     std::cout << "x and y are ";
     if (p != q) std::cout << "NOT ";
     std::cout << " equal\n";
}

int main()
{
    int x[2];

    func2(&x, &x[0]);     // both pointers implicitly converted to void * when calling func2()
}

我认为它没有在任何地方明确说明,但我相信它来自 5.3.3 Sizeof:

the size of an array of n elements is n times the size of an element

唯一可以存储在数组起始地址的是数组的第一个元素。