Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/header/charconv"

From cppreference.com
< cpp‎ | header
Line 19: Line 19:
 
<charconv> is a huge mistake. There are no algorithms in the world to implement to_chars/from_chars effectively or even correctly. The API encourages buffer overflow since it manipulates through raw pointers and buffer size is not deterministic. It also cannot be used under constexpr context.
 
<charconv> is a huge mistake. There are no algorithms in the world to implement to_chars/from_chars effectively or even correctly. The API encourages buffer overflow since it manipulates through raw pointers and buffer size is not deterministic. It also cannot be used under constexpr context.
  
The fundamental problems are that <cstdio> and <iostream> are notoriously dangerous for tons of security vulnerability (like buffer overflow, type confusion) and also notoriously slow. Everyone can easily write their own integers to strings with at least a 10x performance boost. C++ desperately needs a new IO library to replace stdio and iostream to fix the C/C++ historical problems for at least 50 years.
+
The fundamental problems are that <cstdio> and <iostream> are notoriously dangerous for tons of security vulnerability (like buffer overflow, vtable pointer injection, type confusion) and also notoriously slow. Everyone can easily write their own integers to strings with at least a 10x performance boost. C++ desperately needs a new IO library to replace stdio and iostream to fix the C/C++ historical problems for at least 50 years.
  
 
Though the library is locale-dependent, the result is still not deterministic on EBCDIC machines. The results are nowhere near portable.
 
Though the library is locale-dependent, the result is still not deterministic on EBCDIC machines. The results are nowhere near portable.

Revision as of 13:07, 5 January 2020

 
 
Standard library headers
General utilities
<any> (C++17)
<bitset>
<bit> (C++20)
<charconv> (C++17)
<expected> (C++23)
<format> (C++20)
<functional>
<optional> (C++17)
<tuple> (C++11)
<typeindex> (C++11)
<utility>
<variant> (C++17)
Containers
<array> (C++11)
<deque>
<flat_map> (C++23)
<flat_set> (C++23)
<forward_list> (C++11)
<inplace_vector> (C++26)   
<list>
<map>
<mdspan> (C++23)
<queue>
<set>
<span> (C++20)
<stack>
<unordered_map> (C++11)
<unordered_set> (C++11)
<vector>
Iterators
<iterator>
Ranges
<generator> (C++23)
<ranges> (C++20)
 

Contents

Classes

specifies formatting for std::to_chars and std::from_chars
(enum) [edit]

Functions

converts a character sequence to an integer or floating-point value
(function) [edit]
(C++17)
converts an integer or floating-point value to a character sequence
(function) [edit]

Warning

libstdc++ and libc++ do not support from_chars/to_chars for floating points. VC's implementation assumes long double is as long as double (64 bits). Ryu algorithm does not support 128 bits fixed/precision floating points or etc. In general, it is questionable why ISO C++ committee decides to add something which is theoretically impossible and useless.

<charconv> is a huge mistake. There are no algorithms in the world to implement to_chars/from_chars effectively or even correctly. The API encourages buffer overflow since it manipulates through raw pointers and buffer size is not deterministic. It also cannot be used under constexpr context.

The fundamental problems are that <cstdio> and <iostream> are notoriously dangerous for tons of security vulnerability (like buffer overflow, vtable pointer injection, type confusion) and also notoriously slow. Everyone can easily write their own integers to strings with at least a 10x performance boost. C++ desperately needs a new IO library to replace stdio and iostream to fix the C/C++ historical problems for at least 50 years.

Though the library is locale-dependent, the result is still not deterministic on EBCDIC machines. The results are nowhere near portable.

In general, charconv considered harmful.


Synopsis

namespace std {
    // floating-point format for primitive numerical conversion
    enum class chars_format {
        scientific = /*unspecified*/ ,
        fixed = /*unspecified*/ ,
        hex = /*unspecified*/ ,
        general = fixed | scientific
    };
    // primitive numerical output conversion
    struct to_chars_result {
        char* ptr;
        errc ec;
    };
    to_chars_result to_chars(char* first, char* last,
                             /*see description*/ value, int base = 10);
    to_chars_result to_chars(char* first, char* last, float value);
    to_chars_result to_chars(char* first, char* last, double value);
    to_chars_result to_chars(char* first, char* last, long double value);
    to_chars_result to_chars(char* first, char* last, float value,
                             chars_format fmt);
    to_chars_result to_chars(char* first, char* last, double value, 
                             chars_format fmt);
    to_chars_result to_chars(char* first, char* last, long double value,
                             chars_format fmt);
    to_chars_result to_chars(char* first, char* last, float value,
                             chars_format fmt, int precision);
    to_chars_result to_chars(char* first, char* last, double value,
                             chars_format fmt, int precision);
    to_chars_result to_chars(char* first, char* last, long double value,
                             chars_format fmt, int precision);
    // primitive numerical input conversion
    struct from_chars_result {
        const char* ptr;
        errc ec;
    };
    from_chars_result from_chars(const char* first, const char* last,
                                 /*see description*/ & value, int base = 10);
    from_chars_result from_chars(const char* first, const char* last, float& value,
                                 chars_format fmt = chars_format::general);
    from_chars_result from_chars(const char* first, const char* last, double& value,
                                 chars_format fmt = chars_format::general);
    from_chars_result from_chars(const char* first, const char* last, long double& value,
                                 chars_format fmt = chars_format::general);
}