简体   繁体   中英

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

This can be guaranteed in C because of the following sentence in WG14/N1570:

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.

But in WG21/N4527, ie in C++, the corresponding sentence becomes

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

while the word "describes" is changed to "contains", which cannot guarantee that the address of the array equals to that of its first element. Is this change intentional or unintentional? If it is intentional, does the address of the array equal to that of its first element in C++? If it does, which paragraph in the C++ standard can guarantee this?

In C++ it is guaranteed by 4.2/1 Array-to-pointer conversion [conv.array], (bold by me)

An lvalue or rvalue of type “array of NT” 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.

That means if you want to take the address of an array in C++, you would get a pointer which points to the first element of the array. ie

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

The standard guarantees that p1 and p2 will point to same address.

I don't think it's stated explicitly anywhere, but I believe it follows from 5.3.3 Sizeof :

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

that the only thing that can be stored at the array's starting address is the array's first element.

It depends what you mean by "address of array".

If you are asking if an array, when converted to a pointer, gives a result equal to the address of its first element, then the answer is yes. For example;

#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]);
}

This will always report that the two pointers are equal. songyuanyao has explained why.

However, x is not actually a pointer to an array (and nor is it converted to one in this code). If you change the call of func() in main() to

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

then that statement will not even compile. The reason is that &x (the address of the array x ) is not a pointer to an int - it is a pointer to an array of two int , and that cannot be implicitly converted into a pointer to int .

The value, however, will be the same, as may be demonstrated by running this code.

#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()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM