数组的地址是否等于 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
标准保证p1
和p2
指向同一个地址。
这取决于你"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
唯一可以存储在数组起始地址的是数组的第一个元素。
因为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
标准保证p1
和p2
指向同一个地址。
这取决于你"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
唯一可以存储在数组起始地址的是数组的第一个元素。