0

I can’t tell the effective difference between these exactly, the first one seems to work more robustly. The second one works with the adjustment, but has issues with incomplete multibyte strings, and when I remove the resize bytesWritten - 1, it doesn’t work right at all. I would love to know why these work differently. Thanks!

First:

size_t maxBytes = JSStringGetMaximumUTF8CStringSize(str);
std::vector<char> buffer(maxBytes);
JSStringGetUTF8CString(str, buffer.data(), maxBytes);
return std::string(buffer.data());

Second:

std::string result;
size_t maxBytes = JSStringGetMaximumUTF8CStringSize(str);
result.resize(maxBytes);
size_t bytesWritten = JSStringGetUTF8CString(str, &result[0], maxBytes);
// JSStringGetUTF8CString writes the null terminator, so we want to resize
// to `bytesWritten - 1` so that `result` has the correct length.
result.resize(bytesWritten - 1);
return result;
Eric Lewis
  • 41
  • 1
  • Based on the comments in these code snippets, both alternatives appear to be logically equivalent. If you believe that the second one has "issues", you will need to provide a specific example of those issues, including the dump of what `JSStringGetUTF8CString` produces in the output buffer and returns, for both code snippets. I expect it to be identical in both cases, and provided that the return value is correct, the end result is the same. The only possible way for "issues" would be a bug in `JSStringGetUTF8CString` that returns an incorrect return value that the 2nd example relies on. – Sam Varshavchik Feb 23 '19 at 17:52
  • Possible duplicate of [Is it legal to write to std::string?](https://stackoverflow.com/questions/760790/is-it-legal-to-write-to-stdstring) – Superlokkus Feb 23 '19 at 17:53
  • @SamVarshavchik this is actually specifically a problem in the react-native library, and what happens is when it tries to process something like: “”.substring(0,1), it causes an exception to be thrown on resize in the second example. The first example works fine (with no noticeable issues elsewhere either). This is likely due to multibyte characters, but I don’t understand why the first example wouldn’t suffer from the same fate. – Eric Lewis Feb 23 '19 at 17:58
  • The first example doesn't form a `std::string` until it's in its final form, and then forms it from a null-terminated string. – Sam Varshavchik Feb 23 '19 at 18:25

1 Answers1

1

It is not legal to write the character array of a std::string, not via c_str(), not via data() (at least until C++17) and especially not via getting the address of the first element as you did. Thats the difference, in the first one you use a std::vector<char> where all these things are allowed, the second code is just undefined behaviour. It has nothing to do with javascript core btw.

Superlokkus
  • 4,731
  • 1
  • 25
  • 57