0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

22.13 Primitive numeric conversions [charconv] C++N4910:2022 (631) p768.cpp

Posted at

はじめに(Introduction)

N4910 Working Draft, Standard for Programming Language C++

n4910は、ISO/IEC JTC1 SC22 WG21の作業原案(Working Draft)です。
公式のISO/IEC 14882原本ではありません。
ISO/IEC JTC1 SC22 WG21では、可能な限り作業文書を公開し、幅広い意見を求めています。
一連の記事はコード断片をコンパイルできる形にする方法を検討してコンパイル、リンク、実行して、規格案の原文と処理系(g++, Clang++)との違いを確認し、技術内容を検討し、ISO/IEC JTC1 SC22 WG21にフィードバックするために用います。
また、CERT C++, MISRA C++等のコーディング標準のコード断片をコンパイルする際の参考にさせていただこうと考えています。CERT C++, MISRA C++が標準化の動きとの時間的なずれがあれば確認できれば幸いです。また、boostライブラリとの関連、Linux OS, TOPPERSカーネル、g++(GCC), clang++(LLVM)との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。

<この項は書きかけです。順次追記します。>

背景(back ground)

C/C++でコンパイルエラーが出ると、途方にくれることがしばしばあります。
何回かに1回は、該当するエラーが検索できます。
ただ、条件が違っていて、そこでの修正方法では目的を達成しないこともしばしばです。いろいろな条件のコンパイルエラーとその対応方法について、広く記録することによって、いつか同じエラーに遭遇した時にやくに立つことを目指しています。

この半年の間で、三度、自分のネットでの記録に助けられたことがあります。
また過去に解決できなかった記録を10種類以上、最近になって解決できたことがあります。それは、主に次の3つの情報に基づいています。

cpprefjp - C++日本語リファレンス

コンパイラの実装状況

また
https://researchmap.jp/joub9b3my-1797580/#_1797580
に記載したサイトのお世話になっています。

作業方針(sequence)

Clang++では-std=c++03, C++2bの2種類
g++では-std=c++03, c++2bの2種類
でコンパイルし、

1)コンパイルエラーを収集する。
2)コンパイルエラーをなくす方法を検討する。
コンパイルエラーになる例を示すだけが目的のコードは、コンパイルエラーをなくすのではなく、コンパイルエラーの種類を収集するだけにする。
文法を示すのが目的のコード場合に、コンパイルエラーをなくすのに手間がかかる場合は、順次作業します。
3)リンクエラーをなくす方法を検討する。
文法を示すのが目的のコード場合に、リンクエラーをなくすのに手間がかかる場合は、順次作業します。
4)意味のある出力を作る。
コンパイル、リンクが通っても、意味のある出力を示そうとすると、コンパイル・リンクエラーが出て収拾できそうにない場合がある。順次作業します。

1)だけのものから4)まで進んだものと色々ある状態です。一歩でも前に進むご助言をお待ちしています。「検討事項」の欄に現状を記録するようにしています。

C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list

C++N4741, 2018 Standard Working Draft on ISO/IEC 14882 sample code compile list

C++N4606, 2016符号断片編纂一覧(example code compile list)

C++N4606, 2016 Working Draft 2016, ISO/IEC 14882, C++ standard(1) Example code compile list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/

C++N3242, 2011 sample code compile list on clang++ and g++

編纂器(Compiler)

clang++ --version

Debian clang version 14.0.5-++20220610033153+c12386ae247c-1~exp1~20220610153237.151
Target: x86_64-pc-linux-gnu, Thread model: posix, InstalledDir: /usr/bin

g++- --version

g++ (GCC) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

22.13 Primitive numeric conversions [charconv] C++N4910:2022 (631) p768.cpp

算譜(source code)

p768.cpp
// C++N4910 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf
const char * n4910 = "22.13 Primitive numeric conversions [charconv] C++N4910:2022 (631) p768.cpp";
// Debian clang version 14.0.5-++20220610033153+c12386ae247c-
// g++ (GCC) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc.
// Edited by Dr. OGAWA Kiyoshi. Compile procedure and results record.
// C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list
// https://qiita.com/kaizen_nagoya/items/fc957ddddd402004bb91

#include "N4910.h"

using namespace std;

#define see_below int
// 22.13.1 Header <charconv> synopsis [charconv.syn]
namespace std {
// floating-point format for primitive numerical conversion
enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
                        };
// 22.13.2, primitive numerical output conversion
struct to_chars_result {
    char* ptr;
    errc ec;
    friend bool operator==(const to_chars_result&, const to_chars_result&) = default;
};
to_chars_result to_chars(char* first, char* last, see_below value, int base = 10);
to_chars_result to_chars(char* first, char* last, bool value, int base = 10) = delete;
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);
// 22.13.3, primitive numerical input conversion
struct from_chars_result {
    const char* ptr;
    errc ec;
    friend bool operator==(const from_chars_result&, const from_chars_result&) = default;
};
from_chars_result from_chars(const char* first, const char* last,
                             see_below& 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);
}
//  The type chars_format is a bitmask type (16.3.3.3.4) with elements scientific, fixed, and hex.
//  The types to_chars_result and from_chars_result have the data members and special members specified above. They have no base classes or members other than those specified.
// 22.13.2 Primitive numeric output conversion [charconv.to.chars]
//  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 is equal to the value of a value-initialized errc, 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.
//  The functions that take a floating-point value but not a precision parameter ensure that the string representation consists of the smallest number of characters such that there is at least one digit before the radix point (if present) and parsing the representation using the corresponding from_chars function recovers value exactly.
// [Note 1 : This guarantee applies only if to_chars and from_chars are executed on the same implementation.  If there are several such representations, the representation with the smallest difference from the floating- point argument value is chosen, resolving any remaining ties using rounding according to round_to_- nearest (17.3.4.1).
//  The functions taking a chars_format parameter determine the conversion specifier for printf as follows: The conversion specifier is f if fmt is chars_format::fixed, e if fmt is chars_format::scientific, a (without leading "0x" in the result) if fmt is chars_format::hex, and g if fmt is chars_format::general.
to_chars_result to_chars(char* first, char* last, see_below value, int base = 10);
// Preconditions: base has a value between 2 and 36 (inclusive).
// Effects: The value of value is converted to a string of digits in the given base (with no redundant leading zeroes). Digits in the range 10..35 (inclusive) are represented as lowercase characters a..z. If value is less than zero, the representation starts with ’-’.
// Throws: Nothing.
// Remarks: The implementation shall provide overloads for all signed and unsigned integer types and char as the type of the parameter value.
//  All functions named from_chars analyze the string [first,last) for a pattern, where [first,last) is required to be a valid range. If no characters match the pattern, value is unmodified, the member ptr of the return value is first and the member ec is equal to errc::invalid_argument.
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);
// Effects: value is converted to a string in the style of printf in the "C" locale. The conversion specifier is f or e, chosen according to the requirement for a shortest representation (see above); a tie is resolved in favor of f.
// Throws: Nothing.
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);
// Preconditions: fmt has the value of one of the enumerators of chars_format.
// Effects: value is converted to a string in the style of printf in the "C" locale.
// Throws: Nothing.
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);
// Preconditions: fmt has the value of one of the enumerators of chars_format.
// Effects: value is converted to a string in the style of printf in the "C" locale with the given precision. Throws: Nothing.
// See also: ISO C 7.21.6.1
// 22.13.3 Primitive numeric input conversion [charconv.from.chars]
// [Note 1: If the pattern allows for an optional sign, but the string has no digit characters following the sign, no characters match the pattern.
// Otherwise, the characters matching the pattern are interpreted as a representation of a value of the type of value. The member ptr of the return value points to the first character not matching the pattern, or has the value last if all characters match. If the parsed value is not in the range representable by the type of value, value is unmodified and the member ec of the return value is equal to errc::result_out_of_range.
// Otherwise, value is set to the parsed value, after rounding according to round_to_nearest (17.3.4.1), and the member ec is value-initialized.
from_chars_result from_chars(const char* first, const char* last, see_below & value, int base = 10);
// Preconditions: base has a value between 2 and 36 (inclusive).
// Effects: The pattern is the expected form of the subject sequence in the "C" locale for the given nonzero base, as described for strtol, except that no "0x" or "0X" prefix shall appear if the value of base is 16, and except that ’-’ is the only sign that may appear, and only if value has a signed type.
// Throws: Nothing.
// Remarks: The implementation shall provide overloads for all signed and unsigned integer types and char as the referenced type of the parameter value.
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);
// Preconditions: fmt has the value of one of the enumerators of chars_format.
// Effects: The pattern is the expected form of the subject sequence in the "C" locale, as described for strtod, except that
// — the sign ’+’ may only appear in the exponent part;
// — if fmt has chars_format::scientific set but not chars_format::fixed, the otherwise optional exponent part shall appear;
// — if fmt has chars_format::fixed set but not chars_format::scientific, the optional exponent part shall not appear; and
// — if fmt is chars_format::hex, the prefix "0x" or "0X" is assumed.
// [Example 1: The string 0x123 is parsed to have the value 0 with remaining characters x123.
// In any case, the resulting value is one of at most two floating-point values closest to the value of the string matching the pattern.
// Throws: Nothing.
// See also: ISO C 7.22.1.3, 7.22.1.4
int main() {
    cout  <<  n4910 << endl;
    return EXIT_SUCCESS;
}

編纂・実行結果(compile and go)

bash
$ clang++ p768.cpp -std=03 -o p768l -I. -Wall
In file included from p768.cpp:10:
In file included from ./N4910.h:11:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/atomic:38:
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/c++0x_warning.h:32:2: error: This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support \
 ^
p768.cpp:18:6: warning: scoped enumerations are a C++11 extension [-Wc++11-extensions]
enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
     ^
p768.cpp:18:40: error: use of undeclared identifier 'unspecified'
enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
                                       ^
p768.cpp:18:61: error: use of undeclared identifier 'unspecified'
enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
                                                            ^
p768.cpp:18:80: error: use of undeclared identifier 'unspecified'
enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
                                                                               ^
p768.cpp:23:10: error: unknown type name 'errc'
         errc ec;
         ^
p768.cpp:24:83: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions]
         friend bool operator==(const to_chars_result&, const to_chars_result&) = default;
                                                                                  ^
p768.cpp:24:83: warning: defaulted comparison operators are a C++20 extension [-Wc++20-extensions]
p768.cpp:27:80: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
to_chars_result to_chars(char* first, char* last, bool value, int base = 10) = delete;
                                                                               ^
p768.cpp:43:10: error: unknown type name 'errc'
         errc ec;
         ^
p768.cpp:44:87: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions]
         friend bool operator==(const from_chars_result&, const from_chars_result&) = default;
                                                                                      ^
p768.cpp:44:87: warning: defaulted comparison operators are a C++20 extension [-Wc++20-extensions]
p768.cpp:49:56: warning: use of enumeration in a nested name specifier is a C++11 extension [-Wc++11-extensions]
                                    chars_format fmt = chars_format::general);
                                                       ^
p768.cpp:51:56: warning: use of enumeration in a nested name specifier is a C++11 extension [-Wc++11-extensions]
                                    chars_format fmt = chars_format::general);
                                                       ^
p768.cpp:53:56: warning: use of enumeration in a nested name specifier is a C++11 extension [-Wc++11-extensions]
                                    chars_format fmt = chars_format::general);
                                                       ^
p768.cpp:98:49: warning: use of enumeration in a nested name specifier is a C++11 extension [-Wc++11-extensions]
                             chars_format fmt = chars_format::general);
                                                ^
p768.cpp:100:49: warning: use of enumeration in a nested name specifier is a C++11 extension [-Wc++11-extensions]
                             chars_format fmt = chars_format::general);
                                                ^
p768.cpp:102:49: warning: use of enumeration in a nested name specifier is a C++11 extension [-Wc++11-extensions]
                             chars_format fmt = chars_format::general);
                                                ^
12 warnings and 6 errors generated.
$ clang++ p768.cpp -std=2b -o p768l -I. -Wall
p768.cpp:18:40: error: use of undeclared identifier 'unspecified'
enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
                                       ^
p768.cpp:18:61: error: use of undeclared identifier 'unspecified'
enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
                                                            ^
p768.cpp:18:80: error: use of undeclared identifier 'unspecified'
enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
                                                                               ^
3 errors generated.

$ g++ p768.cpp -std=03 -o p768g -I. -Wall
In file included from /usr/local/include/c++/12.1.0/atomic:38,
                 from N4910.h:11,
                 from p768.cpp:10:
/usr/local/include/c++/12.1.0/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
   32 | #error This file requires compiler and library support \
      |  ^~~~~
p768.cpp:18:1: warning: scoped enums only available with '-std=c++11' or '-std=gnu++11' [-Wc++11-extensions]
   18 | enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
      | ^~~~
p768.cpp:18:40: error: 'unspecified' was not declared in this scope
   18 | enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
      |                                        ^~~~~~~~~~~
p768.cpp:18:61: error: 'unspecified' was not declared in this scope
   18 | enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
      |                                                             ^~~~~~~~~~~
p768.cpp:18:80: error: 'unspecified' was not declared in this scope
   18 | enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
      |                                                                                ^~~~~~~~~~~
p768.cpp:23:10: error: 'errc' does not name a type
   23 |          errc ec;
      |          ^~~~
p768.cpp:24:83: warning: defaulted and deleted functions only available with '-std=c++11' or '-std=gnu++11' -Wc++11-extensions]
   24 |          friend bool operator==(const to_chars_result&, const to_chars_result&) = default;
      |                                                                                   ^~~~~~~
p768.cpp:24:22: error: defaulted 'bool std::operator==(const to_chars_result&, const to_chars_result&)' only available with '-std=c++20' or '-std=gnu++20'
   24 |          friend bool operator==(const to_chars_result&, const to_chars_result&) = default;
      |                      ^~~~~~~~
p768.cpp:27:80: warning: defaulted and deleted functions only available with '-std=c++11' or '-std=gnu++11' -Wc++11-extensions]
   27 | to_chars_result to_chars(char* first, char* last, bool value, int base = 10) = delete;
      |                                                                                ^~~~~~
p768.cpp:43:10: error: 'errc' does not name a type
   43 |          errc ec;
      |          ^~~~
p768.cpp:44:87: warning: defaulted and deleted functions only available with '-std=c++11' or '-std=gnu++11' -Wc++11-extensions]
   44 |          friend bool operator==(const from_chars_result&, const from_chars_result&) = default;
      |                                                                                       ^~~~~~~
p768.cpp:44:22: error: defaulted 'bool std::operator==(const from_chars_result&, const from_chars_result&)' only available with '-std=c++20' or '-std=gnu++20'
   44 |          friend bool operator==(const from_chars_result&, const from_chars_result&) = default;
      |                      ^~~~~~~~
p768.cpp:49:56: error: 'chars_format' is not a class or namespace
   49 |                                     chars_format fmt = chars_format::general);
      |                                                        ^~~~~~~~~~~~
p768.cpp:51:56: error: 'chars_format' is not a class or namespace
   51 |                                     chars_format fmt = chars_format::general);
      |                                                        ^~~~~~~~~~~~
p768.cpp:53:56: error: 'chars_format' is not a class or namespace
   53 |                                     chars_format fmt = chars_format::general);
      |                                                        ^~~~~~~~~~~~
p768.cpp:98:49: error: 'chars_format' is not a class or namespace
   98 |                              chars_format fmt = chars_format::general);
      |                                                 ^~~~~~~~~~~~
p768.cpp:100:49: error: 'chars_format' is not a class or namespace
  100 |                              chars_format fmt = chars_format::general);
      |                                                 ^~~~~~~~~~~~
p768.cpp:102:49: error: 'chars_format' is not a class or namespace
  102 |                              chars_format fmt = chars_format::general);
      |                                                 ^~~~~~~~~~~~

$ g++ p768.cpp -std=2b -o p768g -I. -Wall
p768.cpp:18:40: error: 'unspecified' was not declared in this scope
   18 | enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
      |                                        ^~~~~~~~~~~
p768.cpp:18:61: error: 'unspecified' was not declared in this scope
   18 | enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
      |                                                             ^~~~~~~~~~~
p768.cpp:18:80: error: 'unspecified' was not declared in this scope
   18 | enum class chars_format { scientific = unspecified, fixed = unspecified, hex = unspecified, general = fixed | scientific
      |                                                                                ^~~~~~~~~~~

検討事項(agenda)

コンパイルエラーを取るか、コンパイルエラーの理由を解説する。

参考資料(reference)

関連する自己参照以外は、こちらの先頭に移転。

C言語(C++)に対する誤解、曲解、無理解、爽快。

#include "N4910.h"

C++N4910資料の改善点

dockerにclang

docker gnu(gcc/g++) and llvm(clang/clang++)

コンパイル用shell script C版(clangとgcc)とC++版(clang++とg++)

C++N4910:2022 tag follower 300人超えました。ありがとうございます。

astyle 使ってみた

DoCAP(ドゥーキャップ)って何ですか?

小川メソッド 覚え(書きかけ)

<この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。>

文書履歴(document history)

ver. 0.01 初稿  20220731

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?