Thread: const pointers

  1. #1
    Registered User
    Join Date
    Dec 2015
    Posts
    13

    const pointers

    Hi everyone!


    I have some doubts about const arrays and pointers in C.


    Given the following code


    Code:
     #include <stdio.h>
     #include <stdlib.h>
     
    
     
    
     
    
     int main(int argc, char** argv)
     {
         const char array[] = "this is an array";
          
         //    array[0] = 'j';//error: assignment of read-only location ‘array[0]’
          
         char *p = (char*)array;//warning: initialization discards ‘const’ qualifier from pointer target type
     
    
         p[0] ='j';
         printf("array = %s\n",array);
         return (EXIT_SUCCESS);
     }

    If 'array' is declared as constant I can not change the array. But why can I use a pointer to the array 'p' and alter it the original array 'array'?


    Another question is that if I cast the assignation to the array


    Code:
     char *p = (char*)array;

    The warning disappears. Why?


    Thank you all very much!
    Last edited by hebrerillo; 12-29-2015 at 04:40 PM. Reason: error

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    If 'array' is declared as constant I can not change the array. But why can I use a pointer to the array 'p' and alter it the original array 'array'?
    Because C does not prevent you from doing incorrect things, or at least doesn't make it hard to do incorrect things. The warning is correct and required: if you assign a const pointer to a non-const pointer, you now have a pointer that can write where it's not supposed to. That's why the warning exists (it could also be made an error: your compiler just decided that it's not severe enough. I disagree, but there's probably lots of garbage legacy code that would fail otherwise).

    When you cast, you're basically telling the compiler that you know what you're doing. What you're doing is undefined behavior, which means it may do what you expect, or it may not. I built your code with clang, for example, and it segfaulted, because clang decided to put your array in a read-only location. So the cast allowed you to do something that looks wrong, becuase it is wrong.

    Casts should be used sparingly, and you should know why you're adding a cast. Silencing a warning is typically not the right reason to use a cast, as you see here: the code built without warnings, but is broken.

  3. #3
    Registered User
    Join Date
    Dec 2015
    Posts
    13
    Hi cas!


    Thank you very much for your response!


    I am very surprised as I did not know C allows you to do such a nasty things....


    If I write this


    Code:
     array[0] = 'j';

    The compiler complaints with


    Code:
     array[0] = 'j';//error: assignment of read-only location ‘array[0]’

    Which sounds good to me as I am trying to alter a const array. But I can use a pointer to the const array and alter it... This makes no sense.


    Thanks again for your help

  4. #4
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    Quote Originally Posted by hebrerillo View Post
    This makes no sense.
    It makes absolutely perfect sense because that's what you asked for by casting to a non-const pointer. If you wanted to preserve the constness then why did you cast it away? Consider:
    Code:
    #include <stdio.h>
    
    int main(int argc, char** argv) {
        const char array[] = "this is an array";
        const char *p = array;  // no cast necessary
        p[0] ='j'; //error: assignment of read-only location '*pí
        return 0;
    }

  5. #5
    Registered User
    Join Date
    Dec 2015
    Posts
    68
    But I can use a pointer to the const array and alter it... This makes no sense.

    The compiler can do a precompile and see that the rules of const are followed or not.
    When the code start using pointers that will get changed during runtime, it can not longer warn about read-only.
    As C is not a runtime language but a compiled to asm language.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,839
    Quote Originally Posted by tonyp12
    The compiler can do a precompile and see that the rules of const are followed or not.
    When the code start using pointers that will get changed during runtime, it can not longer warn about read-only.
    As C is not a runtime language but a compiled to asm language.
    The compiler can indeed do such static analysis, and did do such static analysis, until you insisted that you knew better with the cast. This casting away of const-ness is sometimes useful to silence spurious warnings when working with a library that is not const-correct, i.e., you know for sure via documentation that a function does not modify something, yet the parameter is a pointer to non-const. But if you are not working with such a case silencing the warning is a mistake on your part.
    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

  7. #7
    Registered User
    Join Date
    Dec 2015
    Posts
    13
    Quote Originally Posted by algorism View Post
    It makes absolutely perfect sense because that's what you asked for by casting to a non-const pointer. If you wanted to preserve the constness then why did you cast it away? Consider:
    In Java and other languages, once you declare a const variable, you can not change it (which makes sense). And I am perfectly aware this is what asked for, and that's why I posted this question here, because I got surprise when C allowed me to change the const pointer. This is just an example and not a real program.

    As laserlight noted, it could be dangerous to rely on a library that could change your const pointer.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,839
    Quote Originally Posted by hebrerillo
    In Java and other languages, once you declare a const variable, you can not change it (which makes sense).
    That is not actually true: the final keyword in Java as applied to variables of class type declares that the object reference cannot be replaced. However, unless the class is designed to be immutable, this does not necessarily prevent changes to the object, e.g., through a method that changes one of the object's non-final data members.

    On the other hand, the const keyword in C modifies the type of the object such that an attempted modification to an object of that modified type will result in at least a warning, if not an error. Consider this program:
    Code:
    #include <stdio.h>
    
    struct X
    {
        int n;
    };
    
    void foo(struct X *p)
    {
        p->n = 123;
    }
    
    int main(void)
    {
        const struct X x = {0};
        foo(&x);
        return 0;
    }
    foo would be the rough C equivalent of a Java method that modifies a data member. Whereas the call to foo in Java would be permitted if x were declared final, in C, my compiler emits a warning that "passing argument 1 of ‘foo’ discards ‘const’ qualifier from pointer target type" because it "expected ‘struct X *’ but argument is of type ‘const struct X *’".
    Last edited by laserlight; 12-31-2015 at 05:15 AM.
    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

  9. #9
    Registered User
    Join Date
    Dec 2015
    Posts
    13
    In php, it is impossible to alter the constant defined in this class

    Code:
    <?php
    
    class Useless {
    
      const Vvar = 9;
    
    }

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,839
    That is true, but that does not change my point: different languages have different semantics for const, final or whatever else they come up with, so you need to know what are the semantics if you wish to program in that programming language. For example, I can say the same for this static const member variable in C++:
    Code:
    class X
    {
    public:
        static const auto N = 9;
    };
    But C++ is not C.

    EDIT:
    Also, I recall that since PHP5, PHP objects actually are reference variables like Java objects, whereas in PHP4 they were values as in C++. However, if I remember correctly class constants in PHP cannot be initialised with a constructor invocation, hence the example that I mentioned in Java would not apply. If they could, then the semantics may well allow for the same loophole as with Java.
    Last edited by laserlight; 01-09-2016 at 11:07 AM.
    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

  11. #11
    Registered User
    Join Date
    Dec 2015
    Posts
    13
    Hi laserlight,

    I agree with you in that you should learn the semantics if you wish to program in a specific language.

    To sum up, this post has been very useful, because I learned to be very careful when silencing the compiler warning:

    Code:
    warning: initialization discards ‘const’ qualifier from pointer target type
    As you said laserlight, this should be done when I know for sure that a function will not modify my pointer.

    Thank you all very much for your help!!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Array of const pointers to const struct
    By albundy in forum C Programming
    Replies: 4
    Last Post: 08-24-2011, 09:16 PM
  2. question about const pointers and const ints
    By WarDoGG in forum C Programming
    Replies: 9
    Last Post: 01-08-2011, 02:11 PM
  3. Const pointers/references
    By +Azazel+ in forum C++ Programming
    Replies: 11
    Last Post: 09-15-2009, 03:07 AM
  4. Need help with const pointers
    By slickshoes in forum C++ Programming
    Replies: 9
    Last Post: 08-02-2007, 06:03 PM
  5. c++ Pointers and the const keyword
    By ncallaway in forum C++ Programming
    Replies: 6
    Last Post: 10-24-2006, 05:07 PM