Является ли С++ 17 std :: to_chars добавлением нулевого терминатора?

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

Ссылка ничего не говорит об этом, но пример (для меня) явно использует строку с завершающим нулевым символом, иначе как он мог знать, где остановиться, поскольку std::array::data возвращает только указатель.

#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();
}

К сожалению, я не могу проверить его сам, потому что AFAIK не поддерживает его компилятор: https://en.cppreference.com/w/cpp/compiler_support

Изменение: Забыл, что str инициализируется нулями, однако вопрос по-прежнему имеет значение.

Ответы

Ответ 1

В спецификации С++ 17 не to_chars что to_chars добавляет терминатор NUL:

Все функции с именем to_chars преобразуют value в строку символов, последовательно заполняя диапазон [ first, last ], где [ first, last ] требуется, чтобы быть допустимым диапазоном. Если элемент ec возвращаемого значения таков, что значение, преобразованное в bool, является false, преобразование было успешным, а член ptr указателем одного конца в конец написанных символов. В противном случае член ec имеет значение errc::value_too_large, член ptr имеет значение last, а содержимое диапазона [ first, last) не указано.

Ничего не говорится о терминаторе NUL в этом параграфе или в параграфах, которые конкретно определяют поведение отдельных перегрузок to_chars. Поэтому он не записывает один.

Пример работает, если to_chars не содержит более 9 символов. Поскольку str инициализируется всеми символами NUL, все, что не записано на str останется в виде символов NUL.


Чтобы добавить к этому, оригинальная статья P0067R0, в которой она была предложена, явно указывает, что функции to_chars не должны NUL-завершать строки.

Ответ 2

Как указано cpprefrence (ваша первая ссылка)

значение преобразуется в строку, как если бы по std :: sprintf в локали по умолчанию ("C").

Таким образом, нет, он не добавляет нулевой ограничитель, так как sprintf также не является (при вставке значений).