2

(I am a beginner in C, maybe my question is not very smart, but I did google before I ask.)

I saw following code in git source code:

int main(int argc, char **av) {
    const char **argv = (const char **) av;
    // ... more code ...
}

It converts char **av to const char **argv, I thought it meant to make the argument immutable, but I wrote a program and found that both argv and argv[i] are mutable.

Question 1: What is the purpose & goodness of that line of code?

Question 2: What is the behavior of a const pointer? I did google but didn't find a good answer.


@Update

I test more according to the answers, and it seems that argv[i][j] is immutable, but argv and argv[i] is mutable.

So the const on pointer makes the original value immutable, but the pointer itself is still mutable.

Thus I guess the major purpose of the code from git is also to prevent change of the original arguments.

testing code:

#include <stdio.h>

int main(int argc, char * av[]) {
    // modify value pointed by a non-const pointer - ok
    av[0][0] = 'h';
    printf("argv[0] = %s\n", av[0]);

    // modify const pointer itself - ok
    const char **argv = (const char **) av;
    argv[0] = "fake";
    printf("argv[0] = %s\n", argv[0]);
    char *arr[] = {"how", "are", "you"};
    argv = (const char **)arr;
    printf("argv[0] = %s\n", argv[0]);


    // modify the value itself which is pointed by a const pointer - bad, an error will be thrown,
    /*
    argv[0][0] = 'x';
    printf("argv[0] = %s\n", argv[0]);
     */

    return 0;
}

The current code could compile & run without warning or error, but if un-comment the 2 commented lines at end, then it will throw following error when compile:

error: assignment of read-only location ‘**argv’

Eric
  • 22,183
  • 20
  • 145
  • 196

2 Answers2

3

In practice it is not very useful here (and the generated code won't change much, if the compiler is optimizing).

However, argv is not mutable, so the compiler would for instance catch as an error an assignment like

argv[1][0] = '_'; // wrong

A const thing cannot be assigned to. So a const pointer can't be assigned, and a pointer to const means that the dereferenced pointer is a location which cannot be assigned. (and you can mix both: having a const pointer to const)

BTW, main  -in standard C99- is a very special function. You cannot declare it in arbitrary ways (it almost always should be declared int main(int, char**) or int main(void) ....) and you perhaps cannot call it (e.g. it cannot be recursive), but that may be different in C and in C++. So declaring int main (int, const char**) would be illegal.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • It seems that the pointed value itself is immutable, but the pointers are mutable. – Eric Oct 14 '14 at 05:41
  • a const pointer is immutable. It can only be set when defined. – Joao Oct 14 '14 at 05:46
  • @Joao I did a test, and found that const pointer itself is mutable, but the value it point to is not. – Eric Oct 14 '14 at 05:49
  • 1
    how did you test it? could you please post the code? – Joao Oct 14 '14 at 05:50
  • 1
    [Calling main in main is alloved.](http://stackoverflow.com/questions/4238179/calling-main-in-main-in-c) – 2501 Oct 14 '14 at 06:33
  • 2
    The actual prototype for main is `int main(int argc, char* argv[]);`, but many operating systems use `int main(int argc, const char* argv[]);` because they are (technically) allowed to (the C standard doesn't specify if argv has to be writable). – yyny Apr 04 '16 at 08:10
3

1) There is really no point in using a const pointer to access the parameters later on, except to make sure they are not changed.

2) The purpose of const pointers is to make sure that they are not changed throughout the code. You can live without them, but it helps avoiding bugs.

Joao
  • 619
  • 1
  • 5
  • 14