Const Function Overload

I am confused why the following code does not cause any errors because the arguments passed to the display are of the same type ie char .Does const really make a difference?

 #include<iostream> using namespace std; void display(char *p) { cout<<p; } void display(const char *p) { cout<<p; } int main() { display("Hello"); display("World"); } 

EDIT According to the answers, the first display is never called, which is correct, and is also an output.

But suppose I do it like this:

 int main() { char *p="Hello"; display(p);//now first display is called. display("World"); } 

The compiler gives warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings] , but then it calls the first impression. Does this mean that the string is no longer considered constant?

+6
source share
6 answers

const char* and char * not really the same. Later versions allow you to modify a pointed char , while the first of them will prevent this.

Also note that if these were class methods, void display() and void display() const also be valid overloads. Later it will be understood that the method should not change the state of the object.

Consider this code:

 void display(char *s) { std::cout << "Display" << std::endl; } void display(const char *s) { std::cout << "Display with const" << std::endl; } int main() { char *str = strdup("boap"); const char *str2 = "toto"; /* It is a string literral "bound" as a char *. Compiler will issue warning, but it still compiles. Avoid to do that, it just an exemple */ char *not_safe = "not_safe"; display("llama"); display(str2); display(str); display(not_safe); } 

This will print Display with const twice and then Display twice. See there . Now let's see why:

  • "llama" is a string literal, and then resolves as const char * .
  • str2 is a pointer to a string literal. Since its type is const char* , this also applies to overloading const .
  • not_safe also a pointer to a string literal. However, its type char * : is incorrect . The memory it points to is read-only, and attempting to modify it will fail. However, the type of the variable is still char * , so this will not overload const .
  • str is a char * pointer, and the string that it points to is not read-only. Changing its contents is permissible, and since its type is char * , it will be allowed to non-constant overload.
+11
source

The problem is that string literals such as "Hello" and "World" are of type const char[6] . This may fade to const char* , but not to char* . So overload taking const char* ,

  void display(const char *p); 

is the best match. As @JamesKanze points out, it would be possible for a function that takes char* to accept a string literal, but trying to modify the given data would lead to undefined behavior. For this reason, it is unsafe to pass string literals to such functions. With appropriate alert settings, GCC generates the following:

warning: deprecated conversion from string constant to 'char *

In any case, if there are two overloads like the ones you showed, the one that takes const char* wins.

+3
source

The arguments passed to the two functions do not actually match.

The first takes char* : a pointer to char .

The second accepts const char* : a pointer to const char .

So you see that the difference here is whether the pointer points to an object that can be changed or not. This is definitely the property you want to overload the function on.

0
source

Is it possible to change the object or not, this is useful information, depending on which you can use other behavior! Consider this:

 void foo(int * p) { ++(*p); } void foo(int const * p) { std::cout << *p << '\n'; } 
0
source

The sizes of the "Hello" and "World" strings are known at compile time and cannot be changed. They are constant arrays of compile time characters.

In C and C ++ an array, for example. char a[6] can be referenced using a pointer, that is, a is actually a char * . Since arrays for "Hello" and "World" should not be modified at run time, their type is essentially const char * .

The compiler recognizes this and correctly performs overload resolution for display , since only one of the functions ( display(const char* p) ) takes const char* as an argument. This is why there is no ambiguity in both functions, and you will not get the error you expect to receive.

0
source

"because the arguments passed for display are of the same type ie char."

No argument here is "const char *". the data type is this, but the const specifier indicates that the literal string you hardcoded is not something that can be changed.

"Does a constant really matter?"

Yes, the constant determinant matters. in Display (char *) you can update the contents of the zero-terminated string you passed, but not in Display (const char *). This fact allows us to optimize the compiler.

But read that http://www.possibility.com/Cpp/const.html is a good source for using const effectively.

0
source

Source: https://habr.com/ru/post/950331/


All Articles