1
struct A {
    int a;
    .
    .
    .
    int b;
} obj;

const ptrdiff_t diff = &obj->b - &obj->a;

Will diff always contain a constant which doesn't change even when the program is run several times?

Will diff always be positive?

Is there a way to obtain that difference during compile-time? (other than manual counting)

Stargateur
  • 24,473
  • 8
  • 65
  • 91
Yashas
  • 1,154
  • 1
  • 12
  • 34
  • 2
    Yes, yes, and the compiler will probably optimize it like that. – Some programmer dude Dec 14 '17 at 09:47
  • Possible duplicate of [How do you use offsetof() on a struct?](https://stackoverflow.com/questions/7180290/how-do-you-use-offsetof-on-a-struct) – Stargateur Dec 14 '17 at 09:50
  • C or C++ ? In what actuel language you are coding please don't tag question with C and C++ for no reason. C is not C++ is not C. – Stargateur Dec 14 '17 at 09:51
  • 1
    I was coding in C++ but I thought this would be relevant for both. – Yashas Dec 14 '17 at 09:51
  • @Yashas answer could be relevant for both, question should not expect that the answer will be the same for two languages. If you want, made two question one with C and one with C++ but not both that will create a too broad question. – Stargateur Dec 14 '17 at 09:57
  • [This related question](https://stackoverflow.com/questions/47616508/what-is-the-rationale-for-limitations-on-pointer-arithmetic-or-comparison) may be helpful. – xskxzr Dec 14 '17 at 10:01

1 Answers1

5

The behaviour of

const ptrdiff_t diff = &obj->b - &obj->a;

is undefined. You can only subtract two pointers if they point to elements in the same array, or one past the end of that array. For this purpose, a scalar is considered as an array of length 1.

It surprises me that this is a little known rule in C++, and C for that matter.

Although I've never come across a compiler that doesn't give you a "sensible" result, don't code like this, as you're not writing portable C++. With compiler optimisation techniques becoming more and more aggressive, you can fully expect code based on this to break in the future.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Is this UB: `if(size == (&obj->b - &obj->a))` where `size` is of type `int`? – Yashas Dec 14 '17 at 09:55
  • 1
    Yup. A truck load of UB. – Bathsheba Dec 14 '17 at 09:56
  • Would taking the difference of `offsetof`s of two members give the address difference between the two quantities? (I think it should but I've got too scared now) – Yashas Dec 14 '17 at 10:18
  • @Yashas That will help if you post a question about your real problem and not what you think you need to do. https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – Stargateur Dec 14 '17 at 10:21
  • My real problem is I need to pass an offset from a middle of a struct to another member of the struct to a function which is written in assembly. – Yashas Dec 14 '17 at 10:35