Thread: A question about pointer to constant declaration in C programming language

  1. #1
    Registered User dariyoosh's Avatar
    Join Date
    Nov 2012
    Location
    Iran / France
    Posts
    38

    Question A question about pointer to constant declaration in C programming language

    Hello everybody,

    I would like to ask a question about pointer to constant declaration in C programming language. Currently I'm reading the "C in a Nutshell" book and at the section "9.3.1. Constant Pointers and Pointers to Constant Objects"
    The author says:
    ...
    For any operator that requires operands with like types, the compiler implicitly converts a pointer to a given type T into a more qualified version of the type T. If you want to convert a pointer into a pointer to a less-qualified type, you must use an explicit type conversion.
    ...
    Based on what I understand from the above mentioned information I've written the following code and I would like to ask you to check whether my understandings are correct.
    Code:
    #include <stdio.h>
    
    
    int main(int argc, char *argv[])
    {
        // Therefore the value of MYCONSTANT cannot be changed because it is
        // declared as a constant.
        int const MYCONSTANT = 1247;      
        
        // Ok, but then *iPtr1 cannot be used to change indirectly the value
        // of MYCONSTANT.
        int const *iPtr1 = &MYCONSTANT;  
                
        int *iPtr2; 
        
        printf("The value of the constant is : %d\n", MYCONSTANT);
                             
        iPtr2 = (int *)iPtr1; // Ok, explicit type conversion (int const *) to (int *)  
    
        *iPtr2 = 8000;  // Undefined running behaviour?
        
        printf("Now, the value of the constant is : %d\n", MYCONSTANT);
        
        
        return 0;
    }
    If I run this code, here is the result that I obtain

    Code:
    $ gcc -Wall testscript.c -o testscript
    $ ./testscript 
    The value of the constant is : 1247
    Now, the value of the constant is : 8000
    $
    Albeit, I had declared MYCONSTANT as a constant, I managed to change its value indirectly via a less qualified type pointer (int *) instead of (const int *), that is, iPtr2 instead of iPtr1.

    Could someone, make some clarification about this? According to the C language semantic a constant means what it means, it cannot be changed. So why I don't get any runtime error while executing this program?

    Thanks in advance,
    Regards,
    Dariyoosh
    Last edited by dariyoosh; 11-18-2012 at 12:16 PM.

  2. #2
    Registered User
    Join Date
    Sep 2012
    Posts
    357
    Objects qualified with const are not really constants.
    They are variables whose value cannot be changed using the identifier with the const qualifier.

    In retrospect, const should have been named readonly to avoid confusion.

    Code:
    // This is not C
    readonly int x = 5;
    x = 7; /* oops */
    switch (foo) {
      case x: /* oops */
    }
    If you want a bonafide named constant you have two options:
    a) use #define for constants in preprocessor
    b) use an enum for constants in compiler (they are of type int)

    Code:
    #define CONSTANT_42 42
    enum dummy { CONSTANT_THOUSAND = 1000, CONSTANT_HUNDRED = 100 };
    Last edited by qny; 11-18-2012 at 12:40 PM.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    There is one const type which is rather more rigorously enforced.
    Code:
    #include <stdio.h>
    int main ( ) {
        const char *s = "hello";
        char *p = (char*)s;
        *p = 'w';
        printf("%s\n", s);
        return 0;    
    }
    
    $ gcc -Wall foo.c
    $ ./a.out 
    Segmentation fault
    Apart from that, qny is correct.
    The purpose of 'const' in C is really all about "warn me if I try to change this", rather than "this is immutable at run-time".

    You would see something rather different if you tried this in C++.
    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.

  4. #4
    Registered User dariyoosh's Avatar
    Join Date
    Nov 2012
    Location
    Iran / France
    Posts
    38
    Dear qny & Salem

    Thank you very much for your attention to my problem and for your clarification.


    Quote Originally Posted by qny
    If you want a bonafide named constant you have two options:
    a) use #define for constants in preprocessor
    b) use an enum for constants in compiler (they are of type int)
    As far as I know, elements of one of two above suggested types cannot be referenced by pointers. So, yes, as a matter of fact, it seems that there won't be any way of changing the value.

    Quote Originally Posted by qny
    Objects qualified with const are not really constants.They are variables whose value cannot be changed using the identifier with the const qualifier.
    Very interesting, I didn't know that.

    However, the code that I provided in my initial post showed that assigning a more qualified pointer type to a less qualified pointer type with explicit conversion resulted in this side effect. So, I think (please correct me if I'm wrong) that it can be considered as a general good practice for C programming that we should avoid as much as possible such conversion as there could be unknown behaviour?

    Less qualified type pointer assigned to more qualified type pointer --> OK, no problem
    More qualified type pointer assigned to less qualified type pointer (with casting) --> Very BAD (loss of information and control)


    Many thanks for your help.

    Regards,
    Dariyoosh

  5. #5
    Registered User
    Join Date
    Sep 2012
    Posts
    357
    Quote Originally Posted by dariyoosh View Post
    Less qualified type pointer assigned to more qualified type pointer --> OK, no problem
    More qualified type pointer assigned to less qualified type pointer (with casting) --> Very BAD (loss of information and control)
    You're absolutely correct.
    For the most part, casts in C are wrong (though there are many exceptions (maybe where you least expect them)).
    Let the compiler worry about converting when feasible, and, more importantly, let it complain when a bad conversion is required.

  6. #6
    Registered User
    Join Date
    Sep 2012
    Posts
    357
    Quote Originally Posted by dariyoosh View Post
    the code that I provided in my initial post showed that assigning a more qualified pointer type to a less qualified pointer type with explicit conversion resulted in this side effect.
    Also some compilers may put the storage area for const-qualified objects in read-only memory.
    Trying to change the value of a const-qualified object (through another identifier) is Undefined Behaviour: it may work, it may not work, it may work when testing and blow up when the client (or boss or teacher) is watching.

    Code:
    const int i = 42;
    int *j = &i;
    *j = 8000; /* may work, may fail, may format hard disk, ..., ... */

  7. #7
    Registered User dariyoosh's Avatar
    Join Date
    Nov 2012
    Location
    Iran / France
    Posts
    38
    Thank you very much for your help and particularly the last example you gave, it's pretty clear now

    Regards,
    Dariyoosh

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Question addressing the c programming language.
    By errigour in forum General Discussions
    Replies: 9
    Last Post: 04-30-2012, 06:08 PM
  2. Help with a pointer exercise in the C programming language
    By cb0ardpr0gr^mm3r in forum C Programming
    Replies: 2
    Last Post: 11-07-2010, 01:56 AM
  3. not constant satic array declaration
    By fcommisso in forum C Programming
    Replies: 6
    Last Post: 12-14-2009, 03:01 PM
  4. Replies: 8
    Last Post: 07-30-2008, 05:37 AM
  5. Declaration of constant-compiler error
    By Noah in forum C Programming
    Replies: 1
    Last Post: 10-10-2001, 10:05 PM