A question regarding const
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13

Thread: A question regarding const

  1. #1
    Join Date
    Jul 2005
    Posts
    894

    A question regarding const

    Here is the code,
    Code:
    void foo(const char* s)
    {
    	s = "mary";
    }
    
    int main()
    {
    	char* s = "john";
    	foo(s);
    
    	cout<<s<<endl;
    
    	return 0;
    }
    It compiles just fine. But if I change the definition of the function foo a little bit like this,
    Code:
    void foo(const char* &s)
    {
    	s = "mary";
    }
    Then I got compiler errors like "cannot convert parameter 1 from 'char *' to 'const char *&'". It looks like it is fine convert char* to const char* but it is not fine to convert char* to const char *&. Why? Thanks.

  2. #2
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,266

    Re: A question regarding const

    Using MSVS this produces the output john.
    Code:
    #include <iostream>
    using namespace std;
    
    void foo(const char* s)
    {
    	s = "mary";
    }
    
    int main()
    {
    char* s = "john";
    
    	foo(s);
    	cout << s << endl;
    
    	return 0;
    }
    And this produces mary

    Code:
    #include <iostream>
    using namespace std;
    
    void foo(const char*& s)
    {
    	s = "mary";
    }
    
    int main()
    {
    char* s = "john";
    
    	foo(s);
    	cout << s << endl;
    
    	return 0;
    }
    What compiler are you using?
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  3. #3
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Posts
    12,050

    Re: A question regarding const

    In foo, s is a pointer to a const char. The pointer isn't const. What it points to is. Since you're passing by value, s in foo is only in scope for the life of foo. You assign it the the address of the string literal "mary" and it goes out of scope. s in main is unchanged. If you try to modify the string s points to in foo, the compiler won't let you because the char it points to is const.

    In the second example, you're trying to pass a reference to a const char*, but s in main is not a const char*, so the compiler is bellyaching.

    Somebody with 8 years of C++ experience should be answering questions like that, not asking them.

  4. #4
    Join Date
    Jul 2005
    Posts
    894

    Re: A question regarding const

    Quote Originally Posted by 2kaud View Post
    Using MSVS this produces the output john.
    Code:
    #include <iostream>
    using namespace std;
    
    void foo(const char* s)
    {
    	s = "mary";
    }
    
    int main()
    {
    char* s = "john";
    
    	foo(s);
    	cout << s << endl;
    
    	return 0;
    }
    And this produces mary

    Code:
    #include <iostream>
    using namespace std;
    
    void foo(const char*& s)
    {
    	s = "mary";
    }
    
    int main()
    {
    char* s = "john";
    
    	foo(s);
    	cout << s << endl;
    
    	return 0;
    }
    What compiler are you using?
    I am using visual C++ 2010 express.

  5. #5
    Join Date
    Jul 2005
    Posts
    894

    Re: A question regarding const

    Quote Originally Posted by GCDEF View Post
    In foo, s is a pointer to a const char. The pointer isn't const. What it points to is. Since you're passing by value, s in foo is only in scope for the life of foo. You assign it the the address of the string literal "mary" and it goes out of scope. s in main is unchanged. If you try to modify the string s points to in foo, the compiler won't let you because the char it points to is const.

    In the second example, you're trying to pass a reference to a const char*, but s in main is not a const char*, so the compiler is bellyaching.

    Somebody with 8 years of C++ experience should be answering questions like that, not asking them.
    I don't quite understand your logic. Based on the same reasoning, in the first example, I am trying to pass const char*, but s in main is not a const char*, so the compiler is bellyaching but actually the compiler is not. I haven't used C++ all the time during the past eight years.

  6. #6
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Posts
    12,050

    Re: A question regarding const

    Quote Originally Posted by LarryChen View Post
    I don't quite understand your logic. Based on the same reasoning, in the first example, I am trying to pass const char*, but s in main is not a const char*, so the compiler is bellyaching but actually the compiler is not. I haven't used C++ all the time during the past eight years.
    Okay, I'll try again. In the first example, const refers to the char, not to the pointer. So, you're passing a pointer to a const char by value. What this means is a copy of the pointer is passed to foo. Since the pointer isn't const, you can modify its value. Since it's passed by value, the s in foo is a different s than the one in main, and main's s remains unmodified. The char it points to however is const, so you can't modify what it points to.

    In the second example, foo is expecting a const char*&, however s is a non const char*, so the type you're passing doesn't match the argument type the function is expecting, which is what the compiler is trying to tell you.

  7. #7
    Join Date
    Jul 2005
    Posts
    894

    Re: A question regarding const

    Quote Originally Posted by GCDEF View Post
    Okay, I'll try again. In the first example, const refers to the char, not to the pointer. So, you're passing a pointer to a const char by value. What this means is a copy of the pointer is passed to foo. Since the pointer isn't const, you can modify its value. Since it's passed by value, the s in foo is a different s than the one in main, and main's s remains unmodified. The char it points to however is const, so you can't modify what it points to.

    In the second example, foo is expecting a const char*&, however s is a non const char*, so the type you're passing doesn't match the argument type the function is expecting, which is what the compiler is trying to tell you.
    I am not concerned about whether s in main is going to be modified or not. I am only concerned about why there is compiler errors in second example? Why would you always bring these two irrelevant aspects together?
    Back to your explanation, "In the second example, foo is expecting a const char*&, however s is a non const char*, so the type you're passing doesn't match the argument type the function is expecting". But in the first example, foo is expecting a const char*, however s is a non const char*, so the type I am passing looks like doesn't match the argument type the function is expecting either. Thanks.

  8. #8
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Posts
    12,050

    Re: A question regarding const

    Quote Originally Posted by LarryChen View Post
    I am not concerned about whether s in main is going to be modified or not. I am only concerned about why there is compiler errors in second example? Why would you always bring these two irrelevant aspects together?
    Back to your explanation, "In the second example, foo is expecting a const char*&, however s is a non const char*, so the type you're passing doesn't match the argument type the function is expecting". But in the first example, foo is expecting a const char*, however s is a non const char*, so the type I am passing looks like doesn't match the argument type the function is expecting either. Thanks.
    I don't know how else to put it. In the second example, foo is expecting a reference to a pointer to a const char. s in main is not a pointer to a const char yet you're passing it to a function that expects one, so the compiler is complaining. It's complaining because you're passing it as a reference. In the first example, adding const just means you can't modify what s points to.

  9. #9
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,266

    Re: A question regarding const

    Interesting. I originally tried the posted code on a version of MSVS prior to 2010 and as it compiled cleanly I didn't look too closely at the code. However, it certainly doesn't compile with MSVS2010 for the reasons correctly stated by GCDEF. To make it compile under MSVS2010 one way is make s in main a const char * as in

    Code:
    #include <iostream>
    using namespace std;
    
    void foo(const char*& s)
    {
    	s = "mary";
    }
    
    int main()
    {
    const char* s = "john";
    
    	foo(s);
    	cout << s << endl;
    
    	return 0;
    }
    so that you are passing a const char * to foo rather than a char *.

    In your first example, you are passing by value. So a copy of the value of the char * pointer is passed to foo and is assigned to the more restrictive const char * pointer. The s in foo is not the same s as in main. In the second, the foo argument is a reference so no copy of the pointer is made and the s in foo is the same s in main - hence the need for the type of argument passed to foo to be the same as the type of argument expected by foo in its declaration.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  10. #10
    Join Date
    Jul 2005
    Posts
    894

    Re: A question regarding const

    Quote Originally Posted by GCDEF View Post
    I don't know how else to put it. In the second example, foo is expecting a reference to a pointer to a const char. s in main is not a pointer to a const char yet you're passing it to a function that expects one, so the compiler is complaining. It's complaining because you're passing it as a reference. In the first example, adding const just means you can't modify what s points to.
    What I don't understand is first example. The function foo expects const char*, but the passed argument is of type char*. Even though the argument passed to foo is a copy but the copy is still of type char*. So my question is why the compiler doesn't complain "can't convert char* to const char*"? Thanks.

  11. #11
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Posts
    12,050

    Re: A question regarding const

    Quote Originally Posted by LarryChen View Post
    What I don't understand is first example. The function foo expects const char*, but the passed argument is of type char*. Even though the argument passed to foo is a copy but the copy is still of type char*. So my question is why the compiler doesn't complain "can't convert char* to const char*"? Thanks.
    In the first case, all it does is make the char, not the pointer, const in the function foo. Adding const to functions that don't modify the argument passed to them is a common practice.

  12. #12
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,011

    Re: A question regarding const

    Quote Originally Posted by LarryChen View Post
    What I don't understand is first example. The function foo expects const char*, but the passed argument is of type char*. Even though the argument passed to foo is a copy but the copy is still of type char*. So my question is why the compiler doesn't complain "can't convert char* to const char*"? Thanks.
    Because a conversion from char* to const char* is an implicit conversion. Hence, the compiler is allowed to make that conversion in order to match the argument list.
    The example from your OP is pretty much the same as this.
    Code:
    void foo(double lf) {}
    void bar(double& lf) {}
    
    int main()
    {
        int n;
        foo(n); // ok, implicit conversion from int to double
        bar(n); // error, cannot convert from int to double&
    }
    Only in your case the implicit conversion is from char* to const char*. The second case is exactly the same; you cannot take a reference to a variable of a different type than the reference.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  13. #13
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,266

    Re: A question regarding const

    A cautionary note about setting ref memory pointer values in functions.

    The following code (which looks very similar to that of the OP) seems to compile and run OK and produces the expected output of mary.

    Code:
    #include <stdio.h>
    
    void foobar(char* s)
    {
    	s = "zxcv";
    }
    
    void foo(const char*& s)
    {
    const char ss[] = "mary";
    
    	s = ss;
    	printf("foo s = %p\n", s);
    }
    
    int main()
    {
    const char* s = "john";
    
    	foo(s);
    	foobar("asdf");
    	printf("main s = %p\n%s\n", s, s);
    
    	return 0;
    }
    However, if the functon foo is changed to include another printf statement as in

    Code:
    void foo(const char*& s)
    {
    const char ss[] = "mary";
    
    	printf("foo ss = %p\n", ss);
    	s = ss;
    	printf("foo s = %p\n", s);
    }
    then the output is garbage as ss is local to function foo. The first case only gives the impression of working properly (but isn't) as the memory corruption is only apparent in the second case. Changing foo again to

    Code:
    void foo(const char*& s)
    {
    static const char ss[] = "mary";
    
    	printf("foo ss = %p\n", ss);
    	s = ss;
    	printf("foo s = %p\n", s);
    }
    now gives the correct answer without memory corruption.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center