This is a snippet from OpenGL Super Bible 7th edition:
GLint log_length; glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &log_length); std::string str; str.reserve(log_length); glGetShaderInfoLog(fs, log_length, NULL, str.c_str());
At a first glance it seemed weird to me to pass
str.c_str() as an argument to this function, and of course clang immediatelly protested:
cannot initialize a parameter of type 'GLchar *' (aka 'char *') with an rvalue of type 'const char *'.
So I tried to investigate and changed
str.data(), which should provide a pointer to the internal data array, but this produces the same error message. Edit:
data() are actually the same thing (in c++11 at least), so it doesn’t matter which one we use.
I did some searches, but didn’t find a solution (although I’m quite new to C++ and some things are still not obvious to me).
Is this an error in the book? And is there a way to make it work with std::string?
string::data() return a
const char* until C++17. Since C++17,
string::data() has an overload that will return a
char*. This means this code snippet is invalid.
Edit: An easier and as efficient solution is to use
&str. The subscript operator will return a
If you cannot use C++17, you could use a
std::vector<char>, which does have a non-const
data(), but this will cause a copy when constructing a
// ... std::vector<char> v(log_length); glGetShaderInfoLog(fs, log_length, NULL, v.data()); std::string s(begin(v), end(v));
reserve() isn’t sufficient, because the actual
size() is not changed. If
c_str() returned a
char*, the snippet would actually also cause undefined behavior.
Answered By – Asu
Answer Checked By – Willingham (BugsFixing Volunteer)