Thread: pointer struggles ???

  1. #1
    Registered User
    Join Date
    Mar 2020
    Posts
    75

    pointer struggles ???

    Pointers continually elude me.....See below two 'supposedly' equivalent examples:

    int A;
    int *pA;
    pA = &A;


    int A;
    int *pA = (int *)A;

    I am doing an online course and the instructor uses the second method. I understand the first method but every time I see the '*' I think of dereferencing so the typecasting (int *)A does not seem equiv. to &A. Can someone explain in a very basic way?

    Thanks

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,309
    They are not equivalent, so you might want to change instructor if that's what the instructor told you.

    To elaborate: the second method treats the int value as the address of an int. So pA does not point to A, unlike the first method. There's no dereferencing involved; rather the type of the object named A has been reinterpreted to be an int* instead of an int.
    Last edited by laserlight; 04-16-2021 at 02:46 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,905
    I think that there is something missing there, because they are in no way the same

  4. #4
    Registered User
    Join Date
    Mar 2020
    Posts
    75
    This is an embedded block of code looking at a register on an STM32 processor. The following compiles without error:

    Code:
    #include <stdint.h>
    
    #define RCC_BASE_ADDR	0x40023800U
    
    
    int main(void)
    {
    	uint32_t *p;
    	p = (uint32_t *)RCC_BASE_ADDR;
        /* Loop forever */
    	for(;;);
    }
    The following compiles with error:
    Code:
    #include <stdint.h>
    
    #define RCC_BASE_ADDR	0x40023800U
    
    
    int main(void)
    {
    	uint32_t *p;
    	p = (uint32_t *)(&RCC_BASE_ADDR);
        /* Loop forever */
    	for(;;);
    }
    What I am failing to understand is I thought that a pointer in this case p should be pointing to an address (aka use of &). Why is the second block of code not correct? Or for that matter why does the first block of code work without the &?

    Thank you

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,309
    RCC_BASE_ADDR is a macro, so after macro replacement, it is as if you had written:
    Code:
    p = (uint32_t *)(&0x40023800U);
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Apr 2021
    Posts
    8
    It's already been "pointed" out that the two examples are not equivalent. But you can initialize a pointer variable using a typecast integer value.

    That second example only makes sense if the integer variable A contains a valid memory address of an int object. Since you haven't given A a value to convert, though, the result of (int*)A is "undefined behavior". It will probably compile without even a warning, though. Beware.

    C allows a typecast to convert pointers to and from integer values. This isn't used much in applications that run under a modern OS, since the addresses of data objects aren't known at compile time. Also, except for the case of an integer 0 value (which converts to a null pointer), integer-to-pointer conversions are highly non-portable.

    You'll see it in embedded code, in OS kernel code, device drivers, etc. to get a pointer, say, to memory-mapped I/O ports or data stored in some sort of read-only memory. You'll also see it in assembly-level debuggers, converting hexadecimal input to a pointer into the program being debugged.

    So, converting integers to pointers isn't unheard of, but it's not common either. I would not teach it as a first method, and I wouldn't teach it at all without stressing, LOUDLY, that A must be initialized to a valid memory address.
    Last edited by husoski; 04-17-2021 at 03:07 AM.

  7. #7
    Registered User
    Join Date
    Feb 2019
    Posts
    851
    ridderunnersjw, think of pointers as types that hold an address and addresses are unsigned integers (linke indices of an array). In C there are a difference in declaring an object and using it. If you do:
    Code:
    int *pa;
    You are asking the compiler to reserve space for a pointer identified as pa and what goes inside pa is an unsigned integer which will be interpreted as an address when you use the indirection operator * in an expression using this object, as in:
    Code:
    *pa = 0;
    When declaring the object the * isn't the indirection operator, it only tells the compiler that pa is a pointer to an specified type (int, in this case).

    The & operator takes the address of other objects, as in:
    Code:
    int a;
    int *pa;
    
    pa = &a;  // assign the "address of" a to pa
    Since pa is an unsigned integer, but not necessarily of unsigned int type -- it depends of the address size -- it is risky to assume any integer type will fit in the pointer object as an address. The standard library provides some typedefs to allow you to assign integers at pointer types directly: size_t, for example, has the same size as a pointer (not necessarily). And, in stdint.h, there is a uintptr_t type.

    Notice your previous example is wrong. It's not possible to take an address from a literal:
    Code:
    p=(uint32_t *) &RCC_BASE_ADDR;
    This should be:
    Code:
    p=(uint32_t *)RCC_BASE_ADDR;

  8. #8
    Registered User
    Join Date
    Mar 2020
    Posts
    75
    Thank you all for the help!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. f open struggles
    By Ronius in forum C Programming
    Replies: 5
    Last Post: 03-26-2019, 11:12 AM
  2. Replies: 9
    Last Post: 02-07-2017, 12:10 PM
  3. Homework Struggles
    By dolfaniss in forum C Programming
    Replies: 5
    Last Post: 05-04-2011, 01:05 PM
  4. Help With Struggles
    By dolfaniss in forum C Programming
    Replies: 4
    Last Post: 04-25-2011, 07:55 AM
  5. Replies: 3
    Last Post: 10-30-2009, 04:41 PM

Tags for this Thread