In C++ you can initialize an std::string object from a char * and a const char * and this implicitly assumes that the string will end at first NUL character found after the pointer.
In C++ string literals are however arrays and a template constructor could be used to get the correct size even if the string literal contains embedded NULs. See for example the following toy implementation:
#include <stdio.h>
#include <string.h>
#include <vector>
#include <string>
struct String {
std::vector<char> data;
int size() const { return data.size(); }
template<typename T> String(const T s);
// Hack: the array will also possibly contain an ending NUL
// we don't want...
template<int N> String(const char (&s)[N])
: data(s, s+N-(N>0 && s[N-1]=='\0')) {}
// The non-const array removed as probably a lot of code
// builds strings into char arrays and the convert them
// implicitly to string objects.
//template<int N> String(char (&s)[N]) : data(s, s+N) {}
};
// (one tricky part is that you cannot just declare a constructor
// accepting a `const char *` because that would win over the template
// constructor... here I made that constructor a template too but I'm
// no template programming guru and may be there are better ways).
template<> String::String(const char *s) : data(s, s+strlen(s)) {}
int main(int argc, const char *argv[]) {
String s1 = "Hello\0world\n";
printf("Length s1 -> %i\n", s1.size());
const char *s2 = "Hello\0world\n";
printf("Length s2 -> %i\n", String(s2).size());
std::string s3 = "Hello\0world\n";
printf("std::string size = %i\n", int(s3.size()));
return 0;
}
Is there any specific technical reason for which this approach wasn't considered for the standard and instead a string literal with embedded NULs ends up being truncated when used to initialize an std::string object?
char a[100] = "foo"; std::string s = a;,s.length()probably shouldn't be 100.std::string. Removed the non-const version...std::stringobject from a literal containing embeddedNULs ?