Address Arithmetic

Discussion in 'C++' started by aistone@gmail.com, Jul 6, 2006.

  1. Guest

    Hi all,

    If I compile the following program with G++ 4.0.2 and run it I get the
    following output:

    #include <iostream>
    using namespace std;

    int main(char argc, char *argv[]) {
    int x, y;

    cout << "Address of x = " << (unsigned long)&x << endl;
    cout << "Address of y = " << (unsigned long)&y << endl;
    cout << "Difference in addresses = "
    << (unsigned long)&y - (unsigned long)&x << endl;

    return 1;
    }

    $ ./a.out
    Address of x = 3219613408
    Address of y = 3219613404
    Difference in addresses = 4294967292

    I'm wondering why does "Difference in addresses" show a long, seemingly
    random, number instead of 4? Am I casting things wrong?

    Thanks,
    -Andy
     
    , Jul 6, 2006
    #1
    1. Advertising

  2. Guest

    Acck! I should review my problems longer before submitting them to
    UseNet :-(. For some reason y is allocated before x in the address
    space. Doing arithmatic on the unsigned values underflows and a "big"
    value is produced.

    Never mind.
    -Andy

    wrote:
    > Hi all,
    >
    > If I compile the following program with G++ 4.0.2 and run it I get the
    > following output:
    >
    > #include <iostream>
    > using namespace std;
    >
    > int main(char argc, char *argv[]) {
    > int x, y;
    >
    > cout << "Address of x = " << (unsigned long)&x << endl;
    > cout << "Address of y = " << (unsigned long)&y << endl;
    > cout << "Difference in addresses = "
    > << (unsigned long)&y - (unsigned long)&x << endl;
    >
    > return 1;
    > }
    >
    > $ ./a.out
    > Address of x = 3219613408
    > Address of y = 3219613404
    > Difference in addresses = 4294967292
    >
    > I'm wondering why does "Difference in addresses" show a long, seemingly
    > random, number instead of 4? Am I casting things wrong?
    >
    > Thanks,
    > -Andy
     
    , Jul 6, 2006
    #2
    1. Advertising

  3. Ian Collins Guest

    wrote:
    > Acck! I should review my problems longer before submitting them to
    > UseNet :-(. For some reason y is allocated before x in the address
    > space. Doing arithmatic on the unsigned values underflows and a "big"
    > value is produced.
    >

    Framing a post to Usenet is often a good way to solve you own problems!

    --
    Ian Collins.
     
    Ian Collins, Jul 6, 2006
    #3
  4. Eric Jensen Guest

    <> skrev i en meddelelse
    news:...
    > Hi all,
    >
    > If I compile the following program with G++ 4.0.2 and run it I get the
    > following output:
    >
    > #include <iostream>
    > using namespace std;
    >
    > int main(char argc, char *argv[]) {
    > int x, y;
    >
    > cout << "Address of x = " << (unsigned long)&x << endl;
    > cout << "Address of y = " << (unsigned long)&y << endl;
    > cout << "Difference in addresses = "
    > << (unsigned long)&y - (unsigned long)&x << endl;
    >
    > return 1;
    > }
    >
    > $ ./a.out
    > Address of x = 3219613408
    > Address of y = 3219613404
    > Difference in addresses = 4294967292
    >
    > I'm wondering why does "Difference in addresses" show a long, seemingly
    > random, number instead of 4? Am I casting things wrong?


    Because you assume that the address of pointer y is greater than pointer x.

    On the win32 platform your cast will result in pointer turncation, most
    likely also on linux.
    You need to cast to a 64 bit number instead of a 32 bit number.

    If you change your cast to (unsigned long long) it will work fine on atleast
    win32.

    int x, y;
    unsigned long long addrOfX = reinterpret_cast<unsigned long long>(&x),
    addrOfY = reinterpret_cast<unsigned long
    long>(&y);
    cout << "Address of x = " << addrOfX << endl <<
    "Address of y = " << addrOfY << endl <<
    "Difference in addresses = " <<
    (addrOfX < addrOfY ? (addrOfY - addrOfX) : (addrOfX - addrOfY))
    << endl;

    //eric
     
    Eric Jensen, Jul 7, 2006
    #4
  5. posted:


    > I'm wondering why does "Difference in addresses" show a long, seemingly
    > random, number instead of 4? Am I casting things wrong?



    Perhaps you want something like:

    #include <stdio.h>
    #include <stddef.h>

    typedef int SomeType;

    int main(void)
    {
    SomeType const obj[2];

    ptrdiff_t const diff = (char*)(obj + 1) - (char*)obj;

    printf("The difference is %lu bytes.\n", diff);
    }

    (Would "ptrdiff_t" be preferable over "size_t"? Is "%lu" suitable to use
    with "printf"?)


    When you define two objects of the same type as follows:

    int a, b;

    You have no guarantee that there is no padding between them, or even that
    they're stored ANYWHERE near each other in memory.



    --

    Frederick Gotham
     
    Frederick Gotham, Jul 7, 2006
    #5
  6. Frederick Gotham posted:


    I forgot I was on the C++ forum, rather than C.


    > #include <stdio.h>
    > #include <stddef.h>



    #include <iostream>
    #include <cstddef>


    > typedef int SomeType;
    >
    > int main(void)
    > {
    > SomeType const obj[2];
    >
    > ptrdiff_t const diff = (char*)(obj + 1) - (char*)obj;



    std::ptrdiff_t


    > printf("The difference is %lu bytes.\n", diff);




    std::cout << ...


    --

    Frederick Gotham
     
    Frederick Gotham, Jul 7, 2006
    #6
  7. <> wrote:

    > cout << "Difference in addresses = "
    > << (unsigned long)&y - (unsigned long)&x << endl;
    >
    > Address of x = 3219613408
    > Address of y = 3219613404
    > Difference in addresses = 4294967292
    >
    > I'm wondering why does "Difference in addresses" show a long,
    > seemingly random, number instead of 4?



    (uint32)(4 - 8) = (uint32) (-4)
    = 2^32 - 4
    = 4294967296 - 4
    = 4294967292

    Which is exactly what you got.


    --
    Cheers,
    Robbie Hatley
    Tustin, CA, USA
    lonewolfintj at pacbell dot net
    (put "[usenet]" in subject to bypass spam filter)
    http://home.pacbell.net/earnur/
     
    Robbie Hatley, Jul 7, 2006
    #7
  8. Jack Klein Guest

    On Thu, 06 Jul 2006 23:40:43 GMT, Frederick Gotham
    <> wrote in comp.lang.c++:

    > Frederick Gotham posted:
    >
    >
    > I forgot I was on the C++ forum, rather than C.
    >
    >
    > > #include <stdio.h>
    > > #include <stddef.h>

    >
    >
    > #include <iostream>
    > #include <cstddef>
    >
    >
    > > typedef int SomeType;
    > >
    > > int main(void)
    > > {
    > > SomeType const obj[2];
    > >
    > > ptrdiff_t const diff = (char*)(obj + 1) - (char*)obj;


    Subtracting pointers that do not point to parts of the same object is
    undefined behavior.

    >
    >
    > std::ptrdiff_t
    >
    >
    > > printf("The difference is %lu bytes.\n", diff);

    >
    >
    >
    > std::cout << ...


    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jul 7, 2006
    #8
  9. Jack Klein Guest

    On Thu, 06 Jul 2006 23:37:40 GMT, Frederick Gotham
    <> wrote in comp.lang.c++:

    > posted:
    >
    >
    > > I'm wondering why does "Difference in addresses" show a long, seemingly
    > > random, number instead of 4? Am I casting things wrong?

    >
    >
    > Perhaps you want something like:
    >
    > #include <stdio.h>
    > #include <stddef.h>
    >
    > typedef int SomeType;
    >
    > int main(void)
    > {
    > SomeType const obj[2];
    >
    > ptrdiff_t const diff = (char*)(obj + 1) - (char*)obj;


    Subtracting or comparing pointers that do not point to parts of the
    same object is undefined behavior.

    > printf("The difference is %lu bytes.\n", diff);
    > }
    >
    > (Would "ptrdiff_t" be preferable over "size_t"? Is "%lu" suitable to use
    > with "printf"?)


    ptrdiff_t is a signed type. There is no guarantee whatsoever what, if
    any, relationship it might have with an unsigned long, so "%lu" is
    particularly inappropriate. In fact, it needs a cast to whatever type
    of printf() conversion specified is used.

    > When you define two objects of the same type as follows:
    >
    > int a, b;
    >
    > You have no guarantee that there is no padding between them, or even that
    > they're stored ANYWHERE near each other in memory.


    That's why subtracting or comparing their addresses is strictly
    undefined.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jul 7, 2006
    #9
  10. Jerry Coffin Guest

    In article <>,
    says...

    [ ... ]

    > Subtracting or comparing pointers that do not point to parts of the
    > same object is undefined behavior.


    Close, but not quite right. The behavior is defined, but the result
    is unspecified. If you do something like this:

    int a, b;

    if ( a < b)
    std::cout << "A less than B";
    else
    std::cout << "A greater than or equal to B";

    It's entirely open to question _which_ leg of the if statement will
    execute, but you basically get normal execution: one leg or the other
    will execute, and things proceed normally from there. Undefined
    behavior would mean absolutely _anything_ could happen from there
    out.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Jul 8, 2006
    #10
  11. * Jerry Coffin:
    > In article <>,
    > says...
    >
    > [ ... ]
    >
    >> Subtracting or comparing pointers that do not point to parts of the
    >> same object is undefined behavior.

    >
    > Close, but not quite right. The behavior is defined, but the result
    > is unspecified. If you do something like this:
    >
    > int a, b;
    >
    > if ( a < b)
    > std::cout << "A less than B";
    > else
    > std::cout << "A greater than or equal to B";
    >
    > It's entirely open to question _which_ leg of the if statement will
    > execute, but you basically get normal execution: one leg or the other
    > will execute, and things proceed normally from there. Undefined
    > behavior would mean absolutely _anything_ could happen from there
    > out.


    Not sure about that and right now I don't feel like checking it out;
    however, I'm writing to point out that the /standard library/ provides
    functions to compare unrelated pointers safely.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jul 8, 2006
    #11
  12. Ron Natalie Guest

    Alf P. Steinbach wrote:

    >
    > Not sure about that and right now I don't feel like checking it out;
    > however, I'm writing to point out that the /standard library/ provides
    > functions to compare unrelated pointers safely.
    >


    Really?

    The original poster was quite right. The line from the standard
    explicitly defines unspecified result:

    If two pointers p and q of the same type point to different objects
    that are not members of the same object or elements of the same array
    or to different functions, or if only one of them is null, the
    results of p<q, p>q, p<=q, and p>=q are unspecified.


    I don't know what you mean by the quoted passage above. But I don't
    believe there is anything in the library that provides any stricter
    ordering on unrelated pointers that my passage above (from 5.9 of the
    standard).
     
    Ron Natalie, Jul 8, 2006
    #12
  13. * Ron Natalie:
    > Alf P. Steinbach wrote:
    >>
    >> Not sure about that and right now I don't feel like checking it out;
    >> however, I'm writing to point out that the /standard library/ provides
    >> functions to compare unrelated pointers safely.

    >
    > Really?


    Yep.


    > The original poster was quite right. The line from the standard
    > explicitly defines unspecified result:
    >
    > If two pointers p and q of the same type point to different objects
    > that are not members of the same object or elements of the same array
    > or to different functions, or if only one of them is null, the
    > results of p<q, p>q, p<=q, and p>=q are unspecified.


    That means /unspecified/, not undefined, as Jack wrote. So Jerry was
    right, and Jack was wrong; what the OP was, I don't know. Thanks for
    doing what I didn't have time to do (looking this up in the standard).


    > I don't know what you mean by the quoted passage above. But I don't
    > believe there is anything in the library that provides any stricter
    > ordering on unrelated pointers that my passage above (from 5.9 of the
    > standard).


    std::less & family.

    Cheers,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jul 8, 2006
    #13
  14. Ron Natalie Guest

    Alf P. Steinbach wrote:

    >
    > That means /unspecified/, not undefined, as Jack wrote. So Jerry was
    > right, and Jack was wrong; what the OP was, I don't know. Thanks for
    > doing what I didn't have time to do (looking this up in the standard).
    >

    Your followup was to Jerry Coffin's correction to Jack (which did say
    unspecified) ...that's what was confusing.

    You're right about the <functional> relational templates. I'd forgotten
    that. It's one of the places where less() is something more than a pure
    wrapper around the < operator.
     
    Ron Natalie, Jul 8, 2006
    #14
  15. Old Wolf Guest

    Jack Klein wrote:
    > Frederick Gotham wroteL
    >>> SomeType const obj[2];
    >>> ptrdiff_t const diff = (char*)(obj + 1) - (char*)obj;

    >
    > Subtracting pointers that do not point to parts of the same object is
    > undefined behavior.


    But they do point to parts of the same object: the array 'obj'.
     
    Old Wolf, Jul 10, 2006
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stephen Biggs

    Arithmetic on function address

    Stephen Biggs, Apr 23, 2004, in forum: C Programming
    Replies:
    21
    Views:
    735
    Dan Pop
    Apr 28, 2004
  2. joshc
    Replies:
    5
    Views:
    588
    Keith Thompson
    Mar 31, 2005
  3. joshc
    Replies:
    16
    Views:
    494
    Joe Wright
    Jun 15, 2006
  4. Frederick Gotham

    Byte Address Arithmetic Debate

    Frederick Gotham, Nov 19, 2006, in forum: C++
    Replies:
    24
    Views:
    761
    Frederick Gotham
    Nov 21, 2006
  5. vjay

    Array address arithmetic

    vjay, Dec 9, 2007, in forum: C Programming
    Replies:
    15
    Views:
    581
    Keith Thompson
    Dec 11, 2007
Loading...

Share This Page