Constant Pointers and Pointers to Constants

In the CodeGuru newsletter, I brought up the topic of constant pointers and pointers to constants. While this is a beginning level topic, it is one that some advanced-level people goof up in their code.

Pointer contants and contant pointers are also something that many people simply don't use. If you have a value in your program and it should not change, or if you have a pointer and you don't want it to be pointed to a different value, you should make it a constant with the const keyword.

There are generally two places that the const keyword can be used when declaring a pointer. Consider the following declaration:

char A_char = 'A';
char * myPtr = &A_char;

This is a simple declaration of the variable myPtr. myPtr is a pointer to a character variable and in this case points to the character 'A'.

Don't be confused about the fact that a character pointer is being used to point to a single character—this is perfectly legal! Not every character pointer has to point to a string.

Now consider the following three declarations assuming that char_A has been defined as a type char variable.:

const char * myPtr = &char_A;
char * const myPtr = &char_A;
const char * const myPtr = &char_A;

What is the difference between each of the valid ones? Do you know?

They are all three valid and correct declarations. Each assigns the addres of char_A to a character pointer. The difference is in what is constant.

The first declaration:

const char * myPtr

declares a pointer to a constant character. You cannot use this pointer to change the value being pointed to:

char char_A = 'A';
const char * myPtr = &char_A;
*myPtr = 'J';    // error - can't change value of *myPtr

The second declaration,

char * const myPtr

declares a constant pointer to a character. The location stored in the pointer cannot change. You cannot change where this pointer points:

char char_A = 'A';
char char_B = 'B';

char * const myPtr = &char_A;
myPtr = &char_B;    // error - can't change address of myPtr

The third declares a pointer to a character where both the pointer value and the value being pointed at will not change.

Pretty simple, but as with many things related to pointers, a number of people seem to have trouble.

# # #



About the Author

Bradley Jones

Bradley Jones, in addition to managing CodeGuru, Brad! oversees the Developer.com Newtwork of sites including Codeguru, Developer.com, DevX, VBForums, and over a dozen more with a focus on software development and database technologies. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days, Web 2.0 Heroes, and Windows Live Essentials and Services.
Google+ Profile | Linked-In Profile | Facebook Page

Comments

  • Programmer

    Posted by C Coder on 10/02/2014 10:42am

    Simply way to understand is to read from left to right: 1) const char * a --> Pointer to character constant. Can point to another constant but value of constant cannot be changed using pointer. 2) char * const a --> Constant pointer to character. Cannot be pointed to another address but can change value pointed by pointer.

    Reply
  • Type Cast Pointer constant and then change the value.

    Posted by DUS on 04/05/2013 10:26pm

    int i = 9; const int *p = &i; *p = 30; // This would result in ERROR *((int *)p) = 40; // This allows me to change the Value of i. Why? Does the type cast create its own variable and then allow to change the value of i? And another case is if declaration of i is changed to cont int i = 9; then the code gets compiled and in run time the value of i is not changed. Can you explain me this. please Thanks

    • C style cast

      Posted by Alan on 04/15/2013 04:14am

      The C style cast removes the const modifier therefore allowing you to change the variable. In this case *((int*)p) = 40; is equivalent to const_cast(p) = 40; Using C++ style casts removes ambiguity and is to be preferred (unless you're actually writing C of course!)

      • oops!

        Posted by Alan on 04/15/2013 07:02am

        Except that the bit of the const_cast statement in angle brackets has been stripped out. There doesn't seem to be any help, nor a preview facility, so all I can do is hope that this will display correctly: *((int*)p) = 40; is equivalent to const_cast(p) = 40;

        • I give up

          Posted by Alan on 04/15/2013 10:24am

          :-\

          Reply
        Reply
      Reply
    Reply
  • hi

    Posted by wubo on 11/09/2012 12:07am

    thanks for sharing! I have a proplem to report when programing.so look code first: const int test = 5; const int *pm = &test; int *pn = pm; printf("%d\n",(*pn)++); printf("%d\n",*pm); printf("%d\n",test); Than I use gcc(version:4.6.1) compiler to make it.But there is no error happened,and output the result:5,6,6.so I want to ask for your help. the code use a const pointer to modify a const.so why???

    Reply
  • hi

    Posted by bowu on 11/09/2012 12:04am

    thanks for sharing! I have a proplem to report when programing.so look code first: const int test = 5; const int *pm = &test; int *pn = pm; printf("%d\n",(*pn)++); printf("%d\n",*pm); printf("%d\n",test); Than I use gcc(version:4.6.1) compiler to make it.But there is no error happened,and output the result:5,6,6.so I want to ask for your help. the code use a const pointer to modify a const.so why???

    Reply
  • a problem

    Posted by wubo on 11/09/2012 12:03am

    thanks for sharing! I have a proplem to report when programing.so look code first: const int test = 5; const int *pm = &test; int *pn = pm; printf("%d\n",(*pn)++); printf("%d\n",*pm); printf("%d\n",test); Than I use gcc(version:4.6.1) compiler to make it.But there is no error happened,and output the result:5,6,6.so I want to ask for your help. the code use a const pointer to modify a const.so why???

    Reply
  • thanks

    Posted by NAGENDRA HEGDE on 09/06/2012 09:29am

    thanks for helping me to prepare my seminar

    Reply
  • a doubt

    Posted by san45 on 06/23/2012 10:07am

    you said char char_A = 'A'; const char * myPtr = &char;_A; *myPtr = 'J'; // error - can't change value of *myPtr do this work: char char_A = 'A'; const char * myPtr = &char;_A; char_A = 'J'; //do this work?

    • reply

      Posted by bluetiger9 on 08/19/2012 11:09am

      In this case you are modifying the character, not using the declared pointer, so it works.

      Reply
    • yes

      Posted by manmohan garg on 08/06/2012 09:14am

      it will work. compiler wont allow to change the value of char_A via pointer. but anyway you can directly change value of char_A

      Reply
    Reply
  • can't able to type tast for const in C++

    Posted by ramya on 06/06/2012 03:54am

    Error 2 error C2259: 'CSecureObject' : cannot instantiate abstract class C:\43132\dfsCommonAppBaseClasses\SecureObject.cpp 208 While doing casting i ma getting above error plz help me out for this....

    • Linux FTW!

      Posted by Derp-enguin on 07/14/2012 03:24am

      Switch to Linux, it'll make your development life easier.

      • citation needed

        Posted by Alan on 04/15/2013 04:09am

        :)

        Reply
      Reply
    Reply
  • Thanks....

    Posted by Sankara Narayanan on 05/22/2012 07:15am

    Clear defn. with example. Takes only few seconds to Identify the diff.

    Reply
  • code optimization using const

    Posted by cscos on 10/26/2011 11:08am

    Hello,
    
    I want to use this to optimize my program.
    Let's say I have a structure like this that I use for many stuff.
    
    typedef struct
    {
      unsigned char workspace[1024*1024];
      unsigned int flags;
    } my_stuff_t;
    
    I have this declared in my_stuff.c :
    
    my_stuff_t my_stuff;
    
    and in my_stuff.h:
    
    extern my_stuff_t my_stuff;
    
    What I want to do is to have another data type points into this structure, in another file.
    
    For example, in my_data.c:
    
    #include "mystuff.h"
    
    typedef struct
    {
      ...
    } custom_t;
    
    custom_t* const data =(custom_t *) (my_stuff.workspace[2*1024]);
    
    and in my_data.h:
    
    extern custom_t* const data;
    
    What I want is that the compiler directly compute the value of data when dealing with it in external code. But when I generate the assembly code, it seems that gcc is still using a load instruction to read "data" address  from the pointer in memory. Off course, any code in my_data.c that use "data" is fine (assembly code is as expected, with direct use of my_stuff address), I'm talking about external object files that include my_data.h
    
    So, is that possible to force the compiler to assume the address is contant and thus not reading it from the pointer address but use a precomputed symbol (later resolved by linker) ?

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • Relying on outside companies to manage your network and server environments for your business and applications to meet the needs and demands of your users can be stressful. This is especially true as many Managed Hosting organizations fail to meet their service level agreements. Read this Forrester total economic impact report and learn what makes INetU different and how they exceed their customers' managed hosting expectations.

Most Popular Programming Stories

More for Developers

RSS Feeds