-3
#include <iostream>
using namespace std;

int main()
{
    int a[100],n;
    cout<<&n<<" "<<&a[100]<<endl;
    if(&n!=&a[100])
    {
         cout<<" What is wrong with C++?";
    }
}

It prints the address of n and a[100] as same. But when I compare the two values in the if loop It says that they both are not equal.

What does this mean?

When I change the value of n, a[100] also changes so doesn't that mean n and a[100] are equal.

Cœur
  • 37,241
  • 25
  • 195
  • 267

4 Answers4

4

First, let's remember that there is no a[100]. It does not exist! If you tried to access a[100]'s "value" then, according to the abstract machine called C++, anything can happen. This includes blowing up the sun or dying my hair purple; now, I like my hair the way it is, so please don't!

Anyway, what you're doing is playing with the array's "one-past-the-end" pointer. You are allowed to obtain this pointer, which is a fake pointer of sorts, as long as you do not dereference it.

It is available only because the "101st element" would be "one past the end" of the array. (And there is debate as to whether you are allowed to write &a[100], rather than a+100, to get such a pointer; I am in the "no" camp.)

However, that still says nothing about comparing it to the address of some entirely different object. You cannot assume anything about the relative location of local variables in memory. You simply have no idea where n will live with respect to a.

The results you're observing are unpredictable, unreliable and meaningless side effects of the undefined behaviour exhibited by your program, caused by a combination of compiler optimisations and data locality.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • I thought the standard said that taking the address of the one-past-array-end element was valid (IIRC `end()` does that sometimes). Wouldn't the behavior be defined then? – Frédéric Hamidi Feb 10 '15 at 12:42
  • @FrédéricHamidi: Yes, taking the address is fine. There is debate as to whether it's defined if you write `&a[100]` rather than `(a+100)` (I am in the 'no' camp) but that's by-the-by. But he's trying to rationalise about whether that one-past-the-end pointer is the same as the address of `n`, which is meaningless. – Lightness Races in Orbit Feb 10 '15 at 12:53
  • All right. So, since only the address of `a[100]` is taken in that code, its behavior is defined and `&n` is only different from `&a[100]` because of padding/alignment, right? – Frédéric Hamidi Feb 10 '15 at 12:55
  • 1
    @FrédéricHamidi: It's more fundamental than padding/alignment. The relative location of local variables is completely unspecified. – Lightness Races in Orbit Feb 10 '15 at 12:58
  • 1
    @FrédéricHamidi: Thanks for your comments though because they made me realise that my answer focuses on something the OP isn't actually doing... – Lightness Races in Orbit Feb 10 '15 at 12:58
  • 1
    Note that `std::less<>`, `std::greater<>` _can_ be used to establish a total ordering of unrelated pointers. (§ 20.8.5/8) – sehe Feb 10 '15 at 13:10
  • Yes it is at least guaranteed that `&a[0]` to `&a[99]` will not equal `&n` (which implies a value greater or lesser for each relation). – Lightness Races in Orbit Feb 10 '15 at 13:14
2

For the array declaration int a[100], array index starts from 0 to 99 and when you try access the address of 101th element which is out of its range could overlap with next member (in your case its variable n) on the stack. However its undefined behavior.

Sunil Bojanapally
  • 12,528
  • 4
  • 33
  • 46
0

For a bit if facts here is the relevant text from the specifications Equality operator (==,!=)

Pointers to objects of the same type can be compared for equality with the 'intuitive' expected results:

From § 5.10 of the C++11 standard:

Pointers of the same type (after pointer conversions) can be compared for equality. Two pointers of the same type compare equal if > and only if they are both null, both point to the same function, or > both represent the same address (3.9.2).

(leaving out details on comparison of pointers to member and or the null pointer constants - they continue down the same line of 'Do > What I Mean':)

  • [...] If both operands are null, they compare equal. Otherwise if only one is null, they compare unequal.[...]

The most 'conspicuous' caveat has to do with virtuals, and it does seem to be the logical thing to expect too:

  • [...] if either is a pointer to a virtual member function, the result is unspecified. Otherwise they compare equal if and only if they would refer to the same member of the same most derived object (1.8) or the same subobject if they were dereferenced with a hypothetical object of the associated class type. [...]

Maybe the problem could be that array of int is not the same as int!

heinz
  • 31
  • 2
-1

by writing &a[100] you're invoking undefined behavior, since there is no element with index 100 in the array a. To get the same address safely, you could instead write a+100 (or &a[0]+100) in which case your program would be well-defined, but whether or not the if condition will hold cannot be predicted or relied upon on any implementation.

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434