I'm seeing some odd behaviour when returning a string literal from a function that should perform an implicit conversion with g++ (version 4.7.3). Can anyone explain why the following code:
#include <stdio.h>
class Test
{
public:
template <unsigned int N>
Test(const char (&foo)[N])
{
printf("Template const char array constructor\n");
}
Test(char* foo)
{
printf("char* constructor\n");
}
};
Test fn()
{
return "foo";
}
int main()
{
Test t("bar");
Test u = fn();
return 0;
}
produces the result:
Template const char array constructor
char* constructor
on g++? The surprising thing being that the char* constructor is chosen in preference to the const char array constructor when generating the return value from fn(). Admittedly there is a warning, "deprecated conversion from string constant to 'char*'"
Even more surprisingly if you remove the char* constructor then the code doesn't compile with g++.
It works as expected with clang (Template constructor used both times), which makes me think this is a compiler bug, but maybe it's just a weird corner of the C++ spec - could anyone confirm?
"" denotes the string literal that is an empty string. const char * b = ""; declares a pointer to a const char, and initialises it to the address of that empty string literal. And also, why does it need to be constant? Literals are held in reserved areas of memory, that are not supposed to be changed by code.
While const char * makes your string immutable and the pointer location still can flexibly change, char * const is the reversion. You can essentially change the content of a string/character which pointed to by char * const, but the pointer’s location cannot be changed:
Summing up char *str The address of this pointer can be chang ... const char * Only the address of this pointer might b ... char * const The content of the string this pointer p ... const char * const Both the location of this pointer and th ...
A string literal exists for the whole duration of the program and can't be deleted. What you might want to do in your constructor is to create a copy of the string. Otherwise you will have problems if the string that is passed to the constructor is not a string literal because it could be destroyed before the class object is destroyed.
It appears that this is a bug affecting several versions of gcc which has been reported over and over again, most recently about a month ago against the most recent version, 4.8.2. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24666
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With