Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

g++ treats returned string literal as const char pointer not const char array

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?

like image 952
mikebell Avatar asked Feb 26 '14 22:02

mikebell


People also ask

Why does a string literal need to be constant in C?

"" 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.

What is the difference between const char * and char * const?

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:

How to sum up a char *STR pointer?

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 ...

How to delete a string literal from a class?

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.


1 Answers

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

like image 125
Brian Bi Avatar answered Oct 06 '22 00:10

Brian Bi