0

I write a code (in my Windows 11, with Embarcadero C++ and using GNU G++17) as follows:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a,b;
    cout<<&a+1<<endl<<&b<<endl;
    cout<<(&a+1==&b)<<endl;
    return 0;
}

I suppose that, if &a+1 and &b gives the same address value, the statement &a+1==&b will returns 1. However, it returns a 0.

0x78fe1c
0x78fe1c
0

To clarify this issue, I added some lines of code.

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a,b;
    cout<<&a+1<<endl<<&b<<endl;
    cout<<(&a+1<=&b)<<endl;
    cout<<(&a+1>=&b)<<endl;
    cout<<(&a+1==&b)<<endl;
    cout<<(&a+1!=&b)<<endl;
    return 0;
}

But the result becomes more confusing:

0x78fe1c
0x78fe1c
1
1
0
1

It means that, &a+1 is no more than &b and no less than it. In the meantime they are not equal. But why?

  • 4
    Can't replicate, `fatal error: 'bits/stdc++.h' file not found`. – 273K Jun 22 '23 at 06:14
  • 6
    [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – Chris Jun 22 '23 at 06:15
  • 5
    Comparing two pointers for anything except equality and inequality (`==` or `!=`) gives undefined behaviour unless those pointers both point to something in the same aggregate (or object). For example, if `a` and `b` are both (references to) elements of the same array, or both are members of the same structure. For `int a, b;`, `a` and `b` are not in the same aggregate. – Peter Jun 22 '23 at 06:17
  • It looks like the pointer is within a 24 bit address space - am I missing something here? And why would you expect two memory addresses to be consecutive? Besides, even if they were consecutive you wouldn't be able to compare by adding one - you'd need to add the length of the first to get to the second. – headbanger Jun 22 '23 at 06:22
  • 2
    @headbanger, pointer arithmetic works _if_ they are stored consecutively. – Chris Jun 22 '23 at 06:25
  • 1
    In addition to the UB issue for pointer comparison, there is no guarantee that `a` and `b` are even located exactly one after the other in memory. Just as an example when I tried it in MSVC, in Debug build there was quite a large gap between them. – wohlstad Jun 22 '23 at 06:35
  • This is a case where your mental model of how C++ should work is different from how it actually works. The code `&a+1` is not legal, and comparisons between pointers are not legal unless the pointers are both pointing to some part of the same larger object. The results of writing such code are unpredictable (as you have found), the technical term for this is *undefined behaviour*. – john Jun 22 '23 at 06:56
  • 2
    @john The code `&a+1` is perfectly legal. – n. m. could be an AI Jun 22 '23 at 06:57
  • @headbanger "you'd need to add the length of the first" No, that's not how pointer arithmetic works. – n. m. could be an AI Jun 22 '23 at 06:58
  • @n.m.willseey'allonReddit OK, is that a change then? There was a time when the one past the end rule only applied to arrays – john Jun 22 '23 at 06:58
  • @john no, for purposes of pointer arithmetic a non-array object is considered to belong to a one-element array https://eel.is/c++draft/basic#compound-3.4 AFAICT this rule was there from day one. – n. m. could be an AI Jun 22 '23 at 07:04
  • @n.m.willseey'allonReddit The [draft standard](https://eel.is/c++draft/expr.add#4) seems confused on this point. The body of the section supports what I was saying, but the note implies that what you are saying is correct. – john Jun 22 '23 at 07:06
  • @n.m.willseey'allonReddit OK, I can see now that you are correct. Not sure if there has been a change or if I was always unaware of that part of the standard. – john Jun 22 '23 at 07:09
  • @john `&a + 1` is valid in standard C++ (all C++ standards) but not in standard C. Related: https://stackoverflow.com/questions/14505851/is-the-one-past-the-end-pointer-of-a-non-array-type-a-valid-concept-in-c – Peter Jun 22 '23 at 07:19
  • @Peter Also C https://port70.net/~nsz/c/c11/n1570.html#6.5.6p7 – n. m. could be an AI Jun 22 '23 at 07:25
  • @Peter Thanks, I was a C programmer before becoming a C++ one, so that's probably where I picked that up. – john Jun 22 '23 at 07:30
  • @n.m.willseey'allonReddit I don't see how that para is relevant. It just says that a pointer to a single object acts like it is a pointer to the first element of an array with one element. That has no bearing on whether it is valid to add one to such a pointer. – Peter Jun 22 '23 at 07:35
  • @Peter Since it is valid to add one to a pointer to an array element, it is also valid to add one to a pointer to a non-array-element, because it acts as a pointer to an element of an array of size one for the purpose of pointer arithmetic. – n. m. could be an AI Jun 22 '23 at 07:37
  • @Peter Thanks a lot! I will explore the concepts of undefined behaviour. – cppHusky Jun 22 '23 at 07:40
  • @Peter `<` for pointers is unspecified not undefined behavior. – 463035818_is_not_an_ai Jun 22 '23 at 08:21
  • @Peter https://eel.is/c++draft/expr.compound#expr.rel-4 – 463035818_is_not_an_ai Jun 22 '23 at 08:24

0 Answers0