0

In my C++/Linux application I want to create a temp folder.

The code is very simple:

std::string tempFolder(mkdtemp("foo"));

To my surprise I received a warning message:

warning: ISO C++11 does not allow conversion from string literal to 'char *'

Ok, as I remember C++ treats string literals as std::string, not a char*. I also know that I can avoid this message by declaring char * as const char*. So my code might look like the following:

const char *tpl = "foo";
std::string tempFolder(mkdtemp(tpl));

if not for the fact that mkdtemp requires char * and not const char*. So explicit casting required here and now my code should look like that:

const char *tpl = "foo";
std::string tempFolder(mkdtemp(const_cast<char *>(tpl)));

In my opinion that looks absolutely ridiculous, the code looks absolutely incomprehensible and overloaded.

So my question - what am I doing wrong?

folibis
  • 12,048
  • 6
  • 54
  • 97

2 Answers2

4

mkdtemp(3) - Linux manual page says:

The mkdtemp() function generates a uniquely named temporary directory from template. The last six characters of template must be XXXXXX and these are replaced with a string that makes the directory name unique. The directory is then created with permissions 0700. Since it will be modified, template must not be a string constant, but should be declared as a character array.

As you see, passing string literal to mkdtemp() is not allowed and you have to pass character array with string that end with XXXXXX.

char tpl[] = "fooXXXXXX";
std::string tempFolder(mkdtemp(tpl));
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
2

Your belief that

C++ treats string literals as std::string, not a char*

is wrong. String literals in C++ are really arrays of constant characters, ie "foo" is a const char[4]. An array decays into a pointer to its 1st element. So a pointer to such a string must be const char*.

mkdtemp() modifies the string, so you can't use a string literal as the argument, you must use a non-const array.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • FYI, in C++14 a string literal *can* be treated as a `std::string`, if it has the `s` suffix on it, eg: `”foo”s`, see [`std::literals::string_literals::operator””s`](https://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s) – Remy Lebeau Dec 07 '20 at 03:09