Thread: Using pointer address as a value

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    68

    Using pointer address as a value

    Say I have
    Code:
    void *var_ptr;
    I can initialize it with some address
    Code:
    var_ptr = (int *) 100;
    and use the address as a value in math expressions
    Code:
    int val1, val2 = 5;
    val1 = val2 + (int)var_ptr ;
    Right? Is it gonna cause a problem in the program?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    What are you really trying to do?

    You can mash your way through anything with sufficient amounts of casting.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2011
    Posts
    68
    Quote Originally Posted by Salem View Post
    What are you really trying to do?

    You can mash your way through anything with sufficient amounts of casting.
    I 'm very short on space.
    So instead allocating
    Code:
    typedef struct 
    {
        void *ptr;
        int val;
    }
    I can allocate only
    Code:
    typedef struct 
    {
        void *ptr;
    }
    And use a pointer address as a value.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Are ints and pointers the same size on your machine?

    If you want to make sure your ints can hold a pointer, then use an intptr_t.
    Fixed width integer types (since C99) - cppreference.com

    Perhaps a union, if you're just trying to economise on space.
    Code:
    typedef union
    {
        void *ptr;
        int val;
    } int_or_ptr_t;
    You can store either an int or a pointer.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Depends on your architecture.

    Suppose, for your processor, the int type is 32 bits long. And suppose that an memory address is 64 bits long (for example, on x86-64 mode on Intel/AMD processors).

    That expression in your example will strip the upper 32 bits of var_ptr (because of the int casting) and add the resulting value to val2, assigning to val1.

    Take a look in this example:
    Code:
    /* test.c */
    #include <stdio.h>
    
    int main( void )
    {
      int val1, val2, val3;
      void *p, *q;
    
      val3 = -1;  // all bits 1
      p = main;   // p is the address of main.
    
      val1 = val3 + (int)p; // strip upper bits from p.
    
      val2 = val3 + p;      // promote val3 to (long),
                            // but strip upper bits on assignment.
    
      q = p + val3;         // promote val3 to (long).
                            // no stripping.
    
      // using "%lx" because I know a ptr and a long are the same size
      // on x86-64.
      printf( "%x, %x, %lx\n", val1, val2, (long)q );
    }
    Compiling and linking:
    $ cc -o test test.c
    test.c: In function ‘main’:
    test.c:11:17: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    val1 = val3 + (int)p; // strip upper bits from p.
    ^
    test.c:13:8: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
    val2 = val3 + p; // promote val3 to (long),
    ^
    $ ./test
    74b40649, 74b40649, 563f74b40649
    Notice the 0x563f00000000 difference and the warnings?

    In x86-64 the pointer types have 64 bits. But other architectures can use different sizes for pointers and int.

    If you want to deal with integers and pointers this way you can use the intptr_t (or uintptr_t) defined in stdint.h. You won't get rid of the warnings, but it is garanteed not to have these side effects on the results (the size of intptr_t and a pointer are the same).

    But, be warned: the size of a pointer can be smaller then of an int as well... depends on the processor!

  6. #6
    Registered User
    Join Date
    May 2011
    Posts
    68
    Quote Originally Posted by Salem View Post
    Are ints and pointers the same size on your machine?

    If you want to make sure your ints can hold a pointer, then use an intptr_t.
    Fixed width integer types (since C99) - cppreference.com

    Perhaps a union, if you're just trying to economise on space.
    Code:
    typedef union
    {
        void *ptr;
        int val;
    } int_or_ptr_t;
    You can store either an int or a pointer.
    This variant will do. I always work with 32-bit platform. int will cover all values I ever need. Thank you.

    or even better
    Code:
    typedef union
    {
        uint8_t *ptr;
        int16_t *ptr;
        int32_t *ptr;
        int val;
    } int_or_ptr_t;
    this way I need no field holding data type information. I can cast to exact pointer I need.
    Last edited by john7; 05-16-2019 at 06:04 AM.

  7. #7
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by john7 View Post
    This variant will do. I always work with 32-bit platform. int will cover all values I ever need. Thank you.

    or even better
    Code:
    typedef union
    {
        uint8_t *ptr;
        int16_t *ptr;
        int32_t *ptr;
        int val;
    } int_or_ptr_t;
    this way I need no field holding data type information. I can cast to exact pointer I need.
    You'll find that that union code won't even compile. Each field in a union or struct must have a unique name, such as ptr8, ptr16, and ptr32. Then if you know what type is pointed to, you won't need a cast. Just use the correct pointer (or val if it's an integer rather than a pointer to data).

  8. #8
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    I 'm very short on space.
    It is exactly what a union is designed to do, to save space by having 2 different ways that the memory can be used.
    Fact - Beethoven wrote his first symphony in C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointer's address
    By Vsky in forum C Programming
    Replies: 8
    Last Post: 01-02-2016, 08:24 AM
  2. Replies: 1
    Last Post: 08-24-2015, 07:43 AM
  3. pointer and smart pointer address
    By l2u in forum C++ Programming
    Replies: 14
    Last Post: 12-26-2006, 05:00 PM
  4. Should i pass address of pointer or just pointer???
    By howhy in forum C++ Programming
    Replies: 11
    Last Post: 09-02-2005, 04:05 AM
  5. Pointer to address.
    By Hulag in forum C Programming
    Replies: 6
    Last Post: 12-16-2004, 06:11 AM

Tags for this Thread