cannot convert char** to const char**

Discussion in 'C++' started by Brad Moore, Oct 13, 2004.

  1. Brad Moore

    Brad Moore Guest

    Hey all,

    I'm getting the following compiler error from my code. I was wondering
    if anyone could help me understand the concept behind it (I actually did
    try and compile this degenerate example).

    int foo(const char* argv[]) { return 0; }

    int main(int argc, char* argv[])
    {
    foo(argv);
    return 0;
    }

    Error: cannot convert parameter 1 from char** to const char**


    I tried using an explicit type cast, and it worked. However, I'd like
    to know the difference between the above code and the following (which
    did compile):

    int goo(const int x) { return 0; }
    int main(int argc, char* argv[])
    {
    int x;
    goo(x);
    }

    I've been reading that using const in your args list is a useful way of
    noting that an argument isn't changed. If foo(const char* argv[]) is
    bad form in some way, please let me know.

    To reiterate, I did get the above code to work. I was just wondering
    what the good programming practice is (and the concept behind it).

    Thanks for your expertise and time,
    -Brad
     
    Brad Moore, Oct 13, 2004
    #1
    1. Advertising

  2. Brad Moore wrote:
    > Hey all,
    >
    > I'm getting the following compiler error from my code. I was wondering
    > if anyone could help me understand the concept behind it (I actually did
    > try and compile this degenerate example).
    >
    > int foo(const char* argv[]) { return 0; }
    >
    > int main(int argc, char* argv[])
    > {
    > foo(argv);
    > return 0;
    > }
    >
    > Error: cannot convert parameter 1 from char** to const char**


    You need to consider the meaning of "**" - in this case it means a
    pointer to a pointer to a [const] char. This is a double level of
    indirection which allows the pointer to be modified in one place and the
    object to be modified in another.

    If the conversion from char** to const char** was allowed, then you
    could write this code.

    const char * A[2] = { "A", "B" };
    char * B[2];

    int main()
    {
    char ** b = B;
    const char ** a = b; // illegal
    //const char ** a = ( const char ** ) b; // BAD work-around (1)
    //const char * const * a = b; // better option (2)

    a[0] = A[0]; // illegal if you use (2) ok if you use (1)

    b[0][0] = 'X'; // const violation - big probs if you use (1)
    }

    This would implicity allow const objects to be accessed in a non-const way.


    >
    >
    > I tried using an explicit type cast, and it worked. However, I'd like
    > to know the difference between the above code and the following (which
    > did compile):
    >
    > int goo(const int x) { return 0; }
    > int main(int argc, char* argv[])
    > {
    > int x;
    > goo(x);
    > }


    This is a very different issue, the earlier one had a level of
    indirection, this one has none. In this case x is "copied" to a const
    value parameter.

    >
    > I've been reading that using const in your args list is a useful way of
    > noting that an argument isn't changed. If foo(const char* argv[]) is
    > bad form in some way, please let me know.
    >
    > To reiterate, I did get the above code to work. I was just wondering
    > what the good programming practice is (and the concept behind it).


    What you did was probably not what you wanted to do.
     
    Gianni Mariani, Oct 13, 2004
    #2
    1. Advertising

  3. "Brad Moore" <-state.edu> wrote in message
    news:ckidim$itf$-state.edu...
    > Hey all,
    >
    > I'm getting the following compiler error from my code. I was wondering if
    > anyone could help me understand the concept behind it (I actually did try
    > and compile this degenerate example).
    >
    > int foo(const char* argv[]) { return 0; }
    >
    > int main(int argc, char* argv[])
    > {
    > foo(argv);
    > return 0;
    > }
    >
    > Error: cannot convert parameter 1 from char** to const char**
    >
    >
    > I tried using an explicit type cast, and it worked. However, I'd like to
    > know the difference between the above code and the following (which did
    > compile):
    >
    > int goo(const int x) { return 0; }
    > int main(int argc, char* argv[])
    > {
    > int x;
    > goo(x);
    > }
    >
    > I've been reading that using const in your args list is a useful way of
    > noting that an argument isn't changed. If foo(const char* argv[]) is bad
    > form in some way, please let me know.


    OK, first thing to note is that foo(char* argv[]) is just another way of
    writing foo(char** argv). C and C++ allows you to use array notation in
    function parameters but its a lie. The compiler always converts to array to
    a pointer. So its better to use the pointer notation, its more truthful.

    C++ says its ok to convert char* to const char* because this it harmless.
    char* is a pointer to char, and const char* is a pointer to constant char
    (note its the char that is constant not the pointer). Adding a const can't
    do any harm. So sometimes people think that char** should be convertible to
    const char** but this conversion is most definitely not harmless. Here's why

    const char a = 'a'; // this is a constant it should never change
    char* x;
    const char** y = &x; // in reality this is illegal
    *y = &a; // now x points to a
    *x = 'b'; // now we have modified a

    By allowing a conversion from char** to const char** we've managed to write
    a sequence of statements which have modified a constant. This is obviously a
    bad thing

    john
     
    John Harrison, Oct 13, 2004
    #3
  4. Brad Moore

    Brad Moore Guest

    I want to thank everyone who responded. I understand the error in my
    reasoning.

    Thanks,
    -Brad
     
    Brad Moore, Oct 13, 2004
    #4
  5. Brad Moore

    Default User Guest

    John Harrison wrote:


    > OK, first thing to note is that foo(char* argv[]) is just another way
    > of writing foo(char** argv).


    This is true.

    > C and C++ allows you to use array
    > notation in function parameters but its a lie. The compiler always
    > converts to array to a pointer. So its better to use the pointer
    > notation, its more truthful.


    This is your personal opinion, not an objective fact. Many people
    prefer the other notation, and their programs are none the less for it.



    Brian Rodenborn
     
    Default User, Oct 13, 2004
    #5
  6. "Default User" <> wrote in message
    news:...
    > John Harrison wrote:
    >
    >
    >> OK, first thing to note is that foo(char* argv[]) is just another way
    >> of writing foo(char** argv).

    >
    > This is true.
    >
    >> C and C++ allows you to use array
    >> notation in function parameters but its a lie. The compiler always
    >> converts to array to a pointer. So its better to use the pointer
    >> notation, its more truthful.

    >
    > This is your personal opinion, not an objective fact. Many people
    > prefer the other notation, and their programs are none the less for it.
    >


    OK, well perhaps we can at least agree that people should be aware of the
    real meaning of the array notation in a function parameter. Its my
    experience in this group that some newbies are not.

    John
     
    John Harrison, Oct 13, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Abhijit Bhadra
    Replies:
    2
    Views:
    7,464
    Ron Natalie
    Dec 1, 2004
  2. Alfonso Morra
    Replies:
    3
    Views:
    1,789
    Christopher Benson-Manica
    Aug 12, 2005
  3. Replies:
    24
    Views:
    836
    Netocrat
    Oct 30, 2005
  4. lovecreatesbeauty
    Replies:
    1
    Views:
    1,058
    Ian Collins
    May 9, 2006
  5. Replies:
    3
    Views:
    5,639
    Frederick Gotham
    Aug 17, 2006
Loading...

Share This Page