What does it mean to "Subtract one Pointer from another" ?

This is a discussion on What does it mean to "Subtract one Pointer from another" ? within the C Programming forums, part of the General Programming Boards category; According to : The C Book — Introduction Subtracting one pointer from another gives a result whose type differs between ...

  1. #1
    Registered User manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    Kolkata@India
    Posts
    2,498

    What does it mean to "Subtract one Pointer from another" ?

    According to : The C Book — Introduction
    Subtracting one pointer from another gives a result whose type differs between different implementations. To allow safe use of the difference, the type is defined in <stddef.h> to be ptrdiff_t. Similarly, you can use size_t to store the result of sizeof.
    The idea as it seems to me is to find out the distance (in bytes(?)) between two addresses.

    Why would the `difference` between different types of pointers have different types ?

    The next paragraph talks about a macro called offsetof for finding the offset of structure members. What is the difference between using it and simply ( *object - *member ) ?
    Manasij Mukherjee | gcc-4.8.2 @Arch Linux
    Slow and Steady wins the race... if and only if :
    1.None of the other participants are fast and steady.
    2.The fast and unsteady suddenly falls asleep while running !



  2. #2
    Registered User manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    Kolkata@India
    Posts
    2,498
    ^Sorry... The last line should read ( &object - &member) . Didn't edit it because editing seems to do away with all newlines and some other whitespaces in my case.
    Manasij Mukherjee | gcc-4.8.2 @Arch Linux
    Slow and Steady wins the race... if and only if :
    1.None of the other participants are fast and steady.
    2.The fast and unsteady suddenly falls asleep while running !



  3. #3
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    When in doubt... look it up...

    From the stddef.h supplied with Pelles C...
    Code:
    /* type definitions */
    #ifndef _PTRDIFF_T_DEFINED
    #define _PTRDIFF_T_DEFINED
    #if __POCC_TARGET__ == 3
    typedef long long ptrdiff_t;
    #else
    typedef int ptrdiff_t;
    #endif
    #endif /* _PTRDIFF_T_DEFINED */
    
    #ifndef _SIZE_T_DEFINED
    #define _SIZE_T_DEFINED
    #if __POCC_TARGET__ == 3
    typedef unsigned long long size_t;
    #else
    typedef unsigned int size_t;
    #endif
    #endif /* _SIZE_T_DEFINED */
    since POCC_TARGET is about architecture : 3 = x64, 2 = x86, etc... we can deduce that it's about providing consistent types across differing architectures. As in a uniform definition of something that's actually compiler/platform dependent.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by manasij7479 View Post
    The idea as it seems to me is to find out the distance (in bytes(?)) between two addresses.
    Straight subtraction will give you the distance in units, by type:

    Code:
    	int n[2];
    	printf("%p - %p = %d bytes\n", &n[1], &n[0], (&n[1] - &n[0]) * sizeof(n[0]));
    Now try w/ a cast: ((void*)&n[1] - (void*)&n[0]).

    Why would the `difference` between different types of pointers have different types ?
    I guess for convenience. That way, p++ will always take you to, eg, the next int in an array, and not just the second byte of the current one.

    The next paragraph talks about a macro called offsetof for finding the offset of structure members. What is the difference between using it and simply ( *object - *member ) ?
    That's backwards (it's member - struct), but you are right, that is the same thing. However, note that you cannot subtract a struct address from a member address without casting, because they are different types. So offsetof() is a little tidier:

    Code:
    #include <stddef.h>
    struct x {
    	int a;
    	int b;
    };   
    
    	struct x eg;
    	printf("using difference: %d bytes\n", (void*)&(eg.b) - (void*)&eg);
    	printf("using offsetof: %d bytes\n", offsetof(struct x, b));
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by MK27 View Post
    Now try w/ a cast: ((void*)&n[1] - (void*)&n[0]).
    So that you get a compiler warning, or what?


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by MK27 View Post
    I guess for convenience. That way, p++ will always take you to, eg, the next int in an array, and not just the second byte of the current one.
    It's not for that. It's because a pointer can be of many different sizes: 16 bit pointers are somewhat common, 32 and 64 bit pointers are extremely common. So what type do you use to hold the difference between 64 bit pointers? It needs at least 64 bits! But you can't use the same type for 16 bit pointers as they might not even have support for 64 bit registers.
    So it's likely the difference will be the same size as the pointers itself. Whatever size that is depends on the architecture.

    Quote Originally Posted by MK27 View Post
    That's backwards (it's member - struct), but you are right, that is the same thing. However, note that you cannot subtract a struct address from a member address without casting, because they are different types. So offsetof() is a little tidier:
    I think it's the same as casting both to a "const char*", and taking their differences (as a char is defined to be 1 byte in size), assuming that is strictly legal according to the standard.

    Edit: the offsetof implementation in my header files are a bit more intelligent though:
    Code:
    #define offsetof(type, member) ( (int) & ((type*)0) -> member )

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 14
    Last Post: 11-08-2010, 12:47 AM
  2. "*x + *x++" Address/Pointer "?"
    By Marth_01 in forum C Programming
    Replies: 10
    Last Post: 11-05-2008, 03:33 AM
  3. "Pointer" plus "Number"
    By Petike in forum C Programming
    Replies: 11
    Last Post: 10-17-2008, 12:24 AM
  4. "itoa"-"_itoa" , "inp"-"_inp", Why some functions have "
    By L.O.K. in forum Windows Programming
    Replies: 5
    Last Post: 12-08-2002, 07:25 AM
  5. "CWnd"-"HWnd","CBitmap"-"HBitmap"...., What is mean by "
    By L.O.K. in forum Windows Programming
    Replies: 2
    Last Post: 12-04-2002, 06:59 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21