Thread: char** conversion to const char**

  1. #1
    Registered User
    Join Date
    Mar 2005
    Posts
    2

    char** conversion to const char**

    As I understand it, __argv returns a 'char**'. Based on that, it makes since that the below code works.
    Code:
    char** argv = __argv; //works
    I would expect the below code to also work but it doesn't.
    Code:
    const char** argv = __argv; //fails
    I was googling and found the below code. It works. I would very much appreciate and explanation of why this works. What does '(const char**)' do?
    Code:
    const char** argv = (const char**) __argv; //works
    Thanks

  2. #2
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Here's what I 've found in the Standard and it explains your problem:

    Code:
    const char **cpp;
    char *p;
    const char c = 'A';
    cpp = &p; // constraint violation
    *cpp = &c; // valid
    *p = 0; // valid
    The first assignment is unsafe because it would allow the
    following valid code to attempt to change the value of the
    const object c.

    As you can see your program could inadvertently modify a const object.

    That is why you're getting that error.

    As I understand it, __argv returns a 'char**'.
    This construction is not familiar with me.
    What is exactly __argv
    is it form
    int main(int argc char** argv)
    or it is some global constant?
    I must admit that __argv is strange to me.

  3. #3
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    Ah...that makes some sense. I knew that the following was illegal:
    Code:
    const char **pConst = 0;
    char **pNotConst = pConst;
    After all, you wouldn't want a non-const pointer pointing to something that you'd already declared as const. The other way was just a little backwards, but still made sense once I'd looked at it:
    Code:
    char **pNotConst = 0;
    const char **pConst = pNotConst;
    The reason why (const char**) will work is because you are casting the pointer to say that it is const. However, I wouldn't use casts to get around const compiler errors. That could make for some bad bugs.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  4. #4
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by Micko
    This construction is not familiar with me.
    What is exactly __argv
    is it form
    int main(int argc char** argv)
    or it is some global constant?
    I must admit that __argv is strange to me.

    I wasn't familiar with it myself until I looked it up. It apparently is a char** that points to the command-line arguments. I tried it out with a sample program:

    Code:
    #include <iostream>
    
    int main()
    {
        int indx = 0;
        std::cout << "The command-line arguments are as follows: " << std::endl;
        while( __argv[indx] )
        {
            std::cout << "__argv[" << indx << "] is: " << __argv[indx] << std::endl;
            ++indx;
        }
        return 0;
    }
    Note I did not specify the typical int main(int argc,char**argv) when one usually needs access to the command-line args. Running the sample program and specifying an additional argument of "1024" I got this as output:

    Code:
    The command-line arguments are as follows:
    __argv[0] is: C:\MiscSrc\Test5\Release\Test5.exe
    __argv[1] is: 1024
    Seems you can use int main() and still access the command-line arguments. Cool, I learned something new today!
    Last edited by hk_mp5kpdw; 03-10-2005 at 10:19 AM.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  5. #5
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Quote Originally Posted by hk_mp5kpdw
    Cool, I learned something new today!
    And thanks to you, me too!

  6. #6
    Registered User
    Join Date
    Mar 2005
    Posts
    2

    Thanks for the responses

    Sorry for the late reply and thanks for the responses.

    Micko’s explanation clearly explained why the code didn’t work as I expected. I must admit it took a few minutes for me to rap my brain around it. The pointer to pointer thing really screws it up in my mind. I’m very new to C++. I hope I grasp things quicker in the near future.

    The reason why (const char**) will work is because you are casting the pointer to say that it is const. However, I wouldn't use casts to get around const compiler errors. That could make for some bad bugs.
    Thanks so much. I have read about old-style casts but I dumped the info.

    What is exactly __argv
    is it form
    int main(int argc char** argv)
    or it is some global constant?
    I must admit that __argv is strange to me.
    I learned about __argv when I was converting a console application to a Win32 application. By using ‘__argv’ you don’t have to parse ‘char* cmdLine’ passed by the WinMain function. Since the console application already handled ‘char** argv’ passed by the Main function, I found ‘__argv’ especially useful. I found out about ‘__argv’ when I saw it used in code. I couldn’t find any documentation about it. I think its Microsoft Visual C++ thing.

  7. #7
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    What is exactly __argv
    Well its not standard thats for sure

  8. #8
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Quote Originally Posted by Thantos
    Well its not standard thats for sure
    Yes, Thantos, you're right. It's not standard, that's for sure. It seems that __argv is available when
    include iostream header. So it is defined somewhere but hard to find where. I tested it with Visual C++.net and Dev-C++ and it works, so it's not Microsoft specific only.

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    __argv is specific to the MS C runtime library - which Dev-C++ uses.

    gg

  10. #10
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Thanks for correcting me Codeplug!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Polynomials and ADT's
    By Emeighty in forum C++ Programming
    Replies: 20
    Last Post: 08-19-2008, 08:32 AM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. Drawing Program
    By Max_Payne in forum C++ Programming
    Replies: 21
    Last Post: 12-21-2007, 05:34 PM
  4. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 01:26 AM
  5. Half-life SDK, where are the constants?
    By bennyandthejets in forum Game Programming
    Replies: 29
    Last Post: 08-25-2003, 11:58 AM