Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is C++17 std::to_chars adding a null terminator?

http://en.cppreference.com/w/cpp/utility/to_chars

Reference does not say anything about that, but the example is (for me) clearly using a null-terminated string, otherwise how could it know where to end, since std::array::data returns only a pointer.

#include <iostream>
#include <charconv>
#include <array>

int main()
{
    std::array<char, 10> str{};
    std::to_chars(str.data(), str.data()+str.size(), 42);
    std::cout << str.data();
}

Unfortunately I can't test it myself because AFAIK no compiler supports it yet: https://en.cppreference.com/w/cpp/compiler_support

Edit: Forgot that str is initialized with zeros, however question is still relevant.

like image 452
Poeta Kodu Avatar asked Mar 04 '18 18:03

Poeta Kodu


People also ask

Does std::string add null terminator?

Actually, as of C++11 std::string is guaranteed to be null terminated. Specifically, s[s. size()] will always be '\0' .

Do C++ strings end with a null terminator?

Well, yes. C++ strings are always null terminated.

What is the null terminator in C++?

The null terminated strings are basically a sequence of characters, and the last element is one null character (denoted by '\0'). When we write some string using double quotes (“…”), then it is converted into null terminated strings by the compiler.

Do all strings have null terminators?

All character strings are terminated with a null character. The null character indicates the end of the string. Such strings are called null-terminated strings. The null terminator of a multibyte string consists of one byte whose value is 0.


2 Answers

The C++17 specification does not state that to_chars adds a NUL terminator:

All functions named to_chars convert value into a character string by successively filling the range [first, last) , where [first, last) is required to be a valid range. If the member ec of the return value is such that the value, when converted to bool, is false, the conversion was successful and the member ptr is the one-past-the-end pointer of the characters written. Otherwise, the member ec has the value errc::value_too_large, the member ptr has the value last, and the contents of the range [first, last) are unspecified.

Nothing is stated about a NUL terminator in that paragraph or in the paragraphs that specifically define the behavior of the individual to_chars overloads. Therefore, it does not write one.

The example works, so long as to_chars does not produce more than 9 characters. Since str is initialized to all NUL characters, anything that is not written into str will be left as NUL characters.


To add to this, the original paper P0067R0 that proposed it explicitly states that the to_chars functions should not NUL-terminate the strings.

like image 78
Nicol Bolas Avatar answered Oct 16 '22 18:10

Nicol Bolas


As stated by cpprefrence (your first link)

value is converted to a string as if by std::sprintf in the default ("C") locale.

So no it doesn't add a null terminator, as sprintf doesn't either (when inserting the values).

like image 23
Timo Avatar answered Oct 16 '22 18:10

Timo