Consequence of const-ifying a function parameter

This is a discussion on Consequence of const-ifying a function parameter within the C Programming forums, part of the General Programming Boards category; Correct me if I am wrong, declaring formal parameters to functions as const, if they should not be/is not changed, ...

  1. #1
    Registered User
    Join Date
    Jul 2005
    Posts
    98

    Consequence of const-ifying a function parameter

    Correct me if I am wrong, declaring formal parameters to functions as const, if they should not be/is not changed, has 2 benefits;
    1. It tells the program that calls this function that the parameter will not be changed - so don't worry.
    2. It tells the implementor and the maintainer of this function that the parameter should not be changed inside the function. And it is for this reason that some people advocate that it is a good idea to const-ify even a non-pointer parameter:
    void my_func(const int i) { ... }
    because if the original programmer or a subsequent maintainer accidentally change the value of the parameter, the compiler can catch it.
    A third benefit may be that the compiler can optimize the program if it knows for sure that the parameter is not changed inside the function. I am not sure about this though.
    Now, I would like to benefit from the const-ification of the function parameter. Let's say I have this:
    Code:
    typedef struct s_fifoItem t_fifoItem;
    struct s_fifoItem {
      t_fifoItem *next;
      t_fifoItem *prev;
      void *elem;
    };
    typedef t_fifoItem t_fifoQueue;
    
    void enqueue(t_fifoQueue *q, void *elem)
    {
      t_fifoItem *i, *last;
       
      i = (t_fifoItem *) malloc(sizeof(t_fifoItem));
      i->elem = elem;
      last = q->prev;
      last->next = i;
      i->next = q;
      q->prev = i;
    }
    elem appears to be a good candidate for const-ification. Intutitively the program calling enqueue() normally does not expect that the item to be enqueued is to be changed. And the implementor of enqueue() would not want to change elem either; and actually elem is not changed in the above implementation. But if I const-ify elem, gcc would complain (in a warning) that the assignment
    i->elem = elem;
    would discard the const qualifier because the type of "i->elem" is "void *", not "const void *". One solution is to cast away the const-ness of elem in that assignment:
    i->elem = (void *)elem;
    Another solution is to change the declaration of elem in struct s_fifoItem to be:
    const void *elem;
    The latter solution is not practical because there are other places that will change *elem.
    However, the former solution of casting away the const-ness is not very appealing. It is kind of cheating.
    So, how do people resolve this? And to a deeper level, gcc seems to be caught bewteen 2 conflicting goals: ensuring type correctness (a double cannot be assigned to an int, a const void * cannot be assigned to a void *, etc) and ensuring the unmodifiability of a variable. From the point of view of language design, what are the issues involved and how do other programming languages deal with it?

  2. #2
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    I would actually leave it as non const. Theoretically, you are changing the state of that parameter by changing who is in charge of cleaning up the memory ( I'm assuming that somewhere t_fifoQueue deletes its memory).

  3. #3
    Registered User
    Join Date
    Jul 2005
    Posts
    98
    So, the state of a variable includes who is responsible for disposing it?
    Even so, the memory deallocation of the item may not be the responsibility of the queue ADT. I may call dequeue() to get the item, and then call free to deallocate its memory.
    I know nothing about C++. But in its queue STL, there is a function
    void push(const T &val)
    that is to add an element with the value specified by val to the end of the queue.
    Does the const here mean that the element is a const parameter?

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    Yes, it means that the push() function can't change the parameter you pass to it.

    BTW, this is the C forum. You should either not cast malloc (for C) or use new (for C++).
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 04-25-2008, 03:45 PM
  2. Replies: 28
    Last Post: 07-17-2006, 12:35 AM
  3. Replies: 20
    Last Post: 11-12-2005, 03:10 PM
  4. Half-life SDK, where are the constants?
    By bennyandthejets in forum Game Programming
    Replies: 29
    Last Post: 08-25-2003, 12:58 PM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 12:54 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21