0
0

6.3 Conversions CN3054:2022 (5) p45.c

Last updated at Posted at 2022-10-15

はじめに(Introduction)

N3054 Working Draft, Standard for Programming Language C

http://www.open-std.org/jtc1/sc22/wg14/docs/papers/2022/n3054.pdf
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3054.pdf

C++ nは、ISO/IEC JTC1 SC22 WG14の作業原案(Working Draft)です。
公式のISO/IEC 9899原本ではありません。

ISO/IEC JTC1 SC22 のWG14を含むいくつかのWGでは、可能な限り作業文書を公開し、幅広い意見を求めています。

ISO/IEC JTC1 SC7からISO/IEC JTC1 SC22リエゾンとして、2000年頃、C/C++の品質向上に貢献しようとした活動をしていたことがあります。その頃は、まだISO/IEC TS 17961の原案が出る前です。Cの精神が優勢で、セキュリティ対策は補助的な位置付けでした。ISO/IEC TS 17961の制定と、C/C++のライブラリ類の見直しと、C++の進化はどんどん進んでいきます。 

進化の具合が、どちらに行こうとしているかは、コンパイルて実行させてみないとわかりません。C/C++の規格案の電子ファイルは、そのままコンパイルできる形式であるとよいと主張してきました。MISRA-C/C++, CERTC/C++でも同様です。MISRA-C/C++は、Example Suiteという形で、コード断片をコンパイルできる形で提供するようになりました。

一連の記事はコード断片をコンパイルできる形にする方法を検討してコンパイル、リンク、実行して、規格案の原文と処理系(gcc, clang)との違いを確認し、技術内容を検討し、ISO/IEC JTC1 SC22 WG21にフィードバックするために用います。
また、CERT C/C++, MISRA C/C++等のコーディング標準のコード断片をコンパイルする際の参考にさせていただこうと考えています。CERT C++, MISRA C++が標準化の動きとの時間的なずれがあれば確認できれば幸いです。また、boostライブラリとの関連、Linux OS, 箱庭プロジェクト、g++(GCC), clang++(LLVM)との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。

背景(back ground)

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

過去に何度か、自分のネットでの記録に助けられたことがあります。

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

作業方針(sequence)

clangでは--std=c11, -std=C17 -std=c2xの3種類
gccでは-std=c11, -std=C17 -std=c2xの3種類
でコンパイルし、

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

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

bash
$ docker run -v /Users/ogawakiyoshi/n4910/n3540:/Users/ogawakiyoshi/n4910/n3540 -it kaizenjapan/n3540 /bin/bash

読書感想文

CコンパイラによるC言語規格の読書感想文として掲載しています。

コンパイル実験が、CN3242に対する、gccとclangによる感想文だということご理解いただけると幸いです。

読書感想文は人間かAIだけが作るものとは限りません。
本(電子書籍を含む)を入力として、その内容に対する文字列を読書感想文として受け止めましょう。
元の文章をあり方、コンパイルできるように電子化しておくこと、コンパイラが解釈可能な断片の作り方など。

個人開発

Cコンパイラの試験を一人でもくもくとやっているのは個人開発の一つの姿です。

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

編纂器(Compiler)

clang --version

Debian clang version 14.0.6-++20220622053050+f28c006a5895-1~exp1~20220622173135.152
Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin

gcc --version

gcc (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.

6.3 Conversions CN3054:2022 (5) p45.c

算譜(source code)

p45.c
// CN3054 Committee Draft, Standard for Programming Language C
// http://www.open-std.org/jtc1/sc22/wg14/docs/papers/2022/n3054.pdf
const char * n3054 = "6.3 Conversions CN3054:2022 (5) p45.c";
// Debian clang version 14.0.5-++20220610033153+c12386ae247c-
// gcc (GCC) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc.
// Edited by Dr. OGAWA Kiyoshi. Compile procedure and results record.
// CN3054:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list

#include "N3054.h"


// 6.3 Conversions
//  Several operators convert operand values from one type to another automatically. This subclause specifies the result required from such an implicit conversion, as well as those that result from a cast operation (an explicit conversion). The list in 6.3.1.8 summarizes the conversions performed by most ordinary operators; it is supplemented as required by the discussion of each operator in 6.5.
//  Unless explicitly stated otherwise, conversion of an operand value to a compatible type causes no change to the value or the representation.
// Forward references: cast operators (6.5.4).
// 61)Every over-aligned type is, or contains, a structure or union type with a member to which an extended alignment has been applied.
// 6.3.1 Arithmetic operands
// 6.3.1.1 Boolean, characters, and integers
//  Every integer type has an integer conversion rank defined as follows:
// — No two signed integer types shall have the same rank, even if they have the same representation.
// — The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision.
// — The rank of long long int shall be greater than the rank of long int, which shall be greater thantherankofint,whichshallbegreaterthantherankofshort int,whichshallbegreater thantherankofsigned char.
// — The rank of a bit-precise signed integer type shall be greater than the rank of any standard integer type with less width or any bit-precise integer type with less width.
// — The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any.
// — The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width or bit-precise integer type with the same width.
// — The rank of any bit-precise integer type relative to an extended integer type of the same width is implementation-defined.
// — The rank of char shall equal the rank of signed char and unsigned char.
// — The rank of bool shall be less than the rank of all other standard integer types.
// — The rank of any enumerated type shall equal the rank of the compatible integer type (see 6.7.2.2).
// — The rank of any extended signed integer type relative to another extended signed integer type with the same precision is implementation-defined, but still subject to the other rules for determining the integer conversion rank.
// — For all integer types T1, T2, and T3, if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 has greater rank than T3.
//  Thefollowingmaybeusedinanexpressionwhereveranintorunsigned intmaybeused:
// — An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.
// — A bit-field of type bool, int, signed int, or unsigned int.
// The value from a bit-field of a bit-precise integer type is converted to the corresponding bit-precise integer type. If the original type is not a bit-precise integer type (6.2.5): if an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int62);otherwise,itisconvertedtoanunsigned int.Thesearecalledtheintegerpromotions63).All other types are unchanged by the integer promotions.
//  The integer promotions preserve value including sign. As discussed earlier, whether a "plain" char can hold negative values is implementation-defined.
// Forward references: enumeration specifiers (6.7.2.2), structure and union specifiers (6.7.2.1).
// 62)E.g.,unsigned _BitInt(7): 2isabit-fieldthatcanholdthevalues0,1,2,3,andconvertstounsigned _BitInt(7).
// 63)The integer promotions are applied only: as part of the usual arithmetic conversions, to certain argument expressions, to the operands of the unary +, −, and ~ operators, and to both operands of the shift operators, as specified by their respective subclauses.
// 6.3.1.2 Boolean type
// When any scalar value is converted to bool, the result is false if the value is a zero (for arithmetic types), null (for pointer types), or the scalar has type nullptr_t; otherwise, the result is true.
// 6.3.1.3 Signed and unsigned integers
//  When a value with integer type is converted to another integer type other than bool, if the value can be represented by the new type, it is unchanged.
//  Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.64) Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
// 6.3.1.4 Real floating and integer
//  When a finite value of standard floating type is converted to an integer type other than bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.65)
//  When a finite value of decimal floating type is converted to an integer type other than bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the "invalid" floating-point exception shall be raised and the result of the conversion is unspecified.
//  When a value of integer type is converted to a standard floating type, if the value being converted can be represented exactly in the new type, it is unchanged. If the value being converted is in the range of values that can be represented but cannot be represented exactly, the result is either the nearest higher or nearest lower representable value, chosen in an implementation-defined manner. If the value being converted is outside the range of values that can be represented, the behavior is undefined. Results of some implicit conversions may be represented in greater range and precision than that required by the new type (see 6.3.1.8 and 6.8.6.4).
//  When a value of integer type is converted to a decimal floating type, if the value being converted can be represented exactly in the new type, it is unchanged. If the value being converted cannot be represented exactly, the result shall be correctly rounded with exceptions raised as specified in IEC 60559.
// 6.3.1.5 Real floating types
//  When a value of real floating type is converted to a real floating type, if the value being converted can be represented exactly in the new type, it is unchanged.
//  When a value of real floating type is converted to a standard floating type, if the value being converted is in the range of values that can be represented but cannot be represented exactly, the result is either the nearest higher or nearest lower representable value, chosen in an implementation- defined manner. If the value being converted is outside the range of values that can be represented, the behavior is undefined.
//  When a value of real floating type is converted to a decimal floating type, if the value being converted cannot be represented exactly, the result is correctly rounded with exceptions raised as specified in IEC 60559.
//  Results of some implicit conversions may be represented in greater range and precision than that required by the new type (see 6.3.1.8 and 6.8.6.4).
// 64)The rules describe arithmetic on the mathematical value, not the value of a given type of expression.
// 65)The remaindering operation performed when a value of integer type is converted to unsigned type need not be performed when a value of real floating type is converted to unsigned type. Thus, the range of portable real floating values is (−1, Utype_MAX + 1).
// 6.3.1.6 Complex types
//  When a value of complex type is converted to another complex type, both the real and imaginary parts follow the conversion rules for the corresponding real types.
// 6.3.1.7 Real and complex
//  When a value of real type is converted to a complex type, the real part of the complex result value is determined by the rules of conversion to the corresponding real type and the imaginary part of the complex result value is a positive zero or an unsigned zero.
//  When a value of complex type is converted to a real type other than bool,66) the imaginary part of the complex value is discarded and the value of the real part is converted according to the conversion rules for the corresponding real type.
// 6.3.1.8 Usual arithmetic conversions
//  Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to determine a common real type for the operands and result. For the specified operands, each operand is converted, without change of type domain, to a type whose corresponding real type is the common real type. Unless explicitly stated otherwise, the common real type is also the corresponding real type of the result, whose type domain is the type domain of the operands if they are the same, and complex otherwise. This pattern is called the usual arithmetic conversions: If one operand has decimal floating type, the other operand shall not have standard floating, complex, or imaginary type.
// First, if the type of either operand is _Decimal128, the other operand is converted to _Decimal128. Otherwise, if the type of either operand is _Decimal64, the other operand is converted to _Decimal64. Otherwise, if the type of either operand is _Decimal32, the other operand is converted to _Decimal32. Otherwise,ifthecorrespondingrealtypeofeitheroperandislong double,theotheroperand is converted, without change of type domain, to a type whose corresponding real type is long double. Otherwise, if the corresponding real type of either operand is double, the other operand is converted, without change of type domain, to a type whose corresponding real type is double. Otherwise, if the corresponding real type of either operand is float, the other operand is converted, without change of type domain, to a type whose corresponding real type is float.67) Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands: If both operands have the same type, then no further conversion is needed. Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank. Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type. Otherwise, if the type of the operand with signed integer type can represent all the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
// 66)See 6.3.1.2.
// 67)Forexample,additionofadouble _Complexandafloatentailsjusttheconversionofthefloatoperandtodouble (andyieldsadouble _Complexresult). Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
//  The values of floating operands and of the results of floating expressions may be represented in greater range and precision than that required by the type; the types are not changed thereby. See 5.2.4.2.2 regarding evaluation formats.
//  EXAMPLE 1 One consequence of _BitInt being exempt from the integer promotion rules (6.3.1) is that a _BitInt operand of a binary operator is not always promoted to an int or unsigned int as part of the usual arithmetic conversions. Instead, a lower-ranked operand is converted to the higher-rank operand type and the result of the operation is the higher-ranked type.
_BitInt(2) a2 = 1;
_BitInt(3) a3 = 2;
_BitInt(33) a33 = 1;
char c = 3;
// a2 * a3 /* As part of the multiplication, a2 is converted to _BitInt(3) and the result type is _BitInt(3). */
// a2 * c /* As part of the multiplication, c is promoted to int, a2 is converted to int and the result type is int. */
// a33 * c /* As part of the multiplication, c is promoted to int, then converted to _BitInt(33) and the result type is _BitInt(33). */
void func(_BitInt(8) a1, _BitInt(24) a2) {
    /* Cast one of the operands to 32-bits to guarantee the
           }
       result of the multiplication can contain all possible
    values. */
    _BitInt(32) a3 = a1 * (_BitInt(32))a2;
// 6.3.2 Other operands
// 6.3.2.1 Lvalues, arrays, and function designators
//  An lvalue is an expression (with an object type other than void) that potentially designates an object;68) if an lvalue does not designate an object when it is evaluated, the behavior is undefined. When an object is said to have a particular type, the type is specified by the lvalue used to designate the object. A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const-qualified type.
//  Except when it is the operand of the sizeof operator, or the typeof operators, the unary & operator, the ++ operator, the -- operator, or the left operand of the . operator or an assignment operator, an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue); this is called lvalue conversion. If the lvalue has qualified type, the value has the unqualified version of the type of the lvalue; additionally, if the lvalue has atomic type, the value has the non-atomic version of the type of the lvalue; otherwise, the value has the type of the lvalue. If the lvalue has an incomplete type and does not have array type, the behavior is undefined. If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.
//  Except when it is the operand of the sizeof operator, or typeof operators, or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.
// 68)Thename"lvalue"comesoriginallyfromtheassignmentexpressionE1 = E2,inwhichtheleftoperandE1isrequiredto be a (modifiable) lvalue. It is perhaps better considered as representing an object "locator value". What is sometimes called "rvalue" is in this document described as the "value of an expression". An obvious example of an lvalue is an identifier of an object. As a further example, if E is a unary expression that is a pointer to an object, *E is an lvalue that designates the object to which E points.
// A function designator is an expression that has function type. Except when it is the operand of the sizeof operator69), a typeof operator, or the unary & operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".
// Forward references: address and indirection operators (6.5.3.2), assignment operators (6.5.16), common definitions <stddef.h> (7.21), initialization (6.7.10), postfix increment and decrement operators (6.5.2.4), prefix increment and decrement operators (6.5.3.1), the sizeof and alignof operators (6.5.3.4), structure and union members (6.5.2.3).
// 6.3.2.2 void
//  The (nonexistent) value of a void expression (an expression that has type void) shall not be used in any way, and implicit or explicit conversions (except to void) shall not be applied to such an expression. If an expression of any other type is evaluated as a void expression, its value or designator is discarded. (A void expression is evaluated for its side effects.)
// 6.3.2.3 Pointers
//  A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.
//  For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to the q-qualified version of the type; the values stored in the original and converted pointers shall compare equal.
//  An integer constant expression with the value 0, such an expression cast to type void *, or the predefined constant nullptr is called a null pointer constant70). If a null pointer constant or a value of the type nullptr_t (which is necessarily the value nullptr) is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
//  Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.
//  An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might produce an indeterminate representation when stored into an object.71)
//  Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.
// A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned72) for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.
// A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.
// 69)Because this conversion does not occur, the operand of the sizeof operator remains a function designator and violates the constraints in 6.5.3.4
// 70)The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant; see 7.21.
// 71)The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to be consistent with the addressing structure of the execution environment.
// 72)In general, the concept "correctly aligned" is transitive: if a pointer to type A is correctly aligned for a pointer to type B, which in turn is correctly aligned for a pointer to type C, then a pointer to type A is correctly aligned for a pointer to type C.
//  6.3.2.4 nullptr_t
//  The type nullptr_t may be converted to bool or to a pointer type. The result is false or a null pointer value, respectively.
//  The type nullptr_t may be converted to itself.
// Forward references: cast operators (6.5.4), equality operators (6.5.9), integer types capable of holding object pointers (7.22.1.4), simple assignment (6.5.16.1), the nullptr_t type (7.21.2).
    int main() {
        cout  <<  n4910 << endl;
        return EXIT_SUCCESS;
    }

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

bash

$ clang p45.c -std=11 -o p45l -I. -Wall
p45.c:106:12: error: function definition is not allowed here
int main() {
           ^
p45.c:109:2: error: expected '}'
}
 ^
p45.c:73:42: note: to match this '{'
void func(_BitInt(8) a1, _BitInt(24) a2) {
                                         ^
2 errors generated.

$ clang p45.c -std=17 -o p45l -I. -Wall
p45.c:106:12: error: function definition is not allowed here
int main() {
           ^
p45.c:109:2: error: expected '}'
}
 ^
p45.c:73:42: note: to match this '{'
void func(_BitInt(8) a1, _BitInt(24) a2) {
                                         ^
2 errors generated.

$ clang p45.c -std=2x -o p45l -I. -Wall
p45.c:106:12: error: function definition is not allowed here
int main() {
           ^
p45.c:109:2: error: expected '}'
}
 ^
p45.c:73:42: note: to match this '{'
void func(_BitInt(8) a1, _BitInt(24) a2) {
                                         ^
2 errors generated.

$ gcc p45.c -std=11 -o p45g -I. -Wall
p45.c:69:9: error: expected declaration specifiers or '...' before numeric constant
   69 | _BitInt(2) a2 = 1; _BitInt(3) a3 = 2; _BitInt(33) a33 = 1; char c = 3;
      |         ^
p45.c:69:28: error: expected declaration specifiers or '...' before numeric constant
   69 | _BitInt(2) a2 = 1; _BitInt(3) a3 = 2; _BitInt(33) a33 = 1; char c = 3;
      |                            ^
p45.c:69:47: error: expected declaration specifiers or '...' before numeric constant
   69 | _BitInt(2) a2 = 1; _BitInt(3) a3 = 2; _BitInt(33) a33 = 1; char c = 3;
      |                                               ^~
p45.c:73:11: error: unknown type name '_BitInt'
   73 | void func(_BitInt(8) a1, _BitInt(24) a2) {
      |           ^~~~~~~
p45.c:73:26: error: unknown type name '_BitInt'
   73 | void func(_BitInt(8) a1, _BitInt(24) a2) {
      |                          ^~~~~~~

$ gcc p45.c -std=c17 -o p45g -I. -Wall
p45.c:69:9: error: expected declaration specifiers or '...' before numeric constant
   69 | _BitInt(2) a2 = 1; _BitInt(3) a3 = 2; _BitInt(33) a33 = 1; char c = 3;
      |         ^
p45.c:69:28: error: expected declaration specifiers or '...' before numeric constant
   69 | _BitInt(2) a2 = 1; _BitInt(3) a3 = 2; _BitInt(33) a33 = 1; char c = 3;
      |                            ^
p45.c:69:47: error: expected declaration specifiers or '...' before numeric constant
   69 | _BitInt(2) a2 = 1; _BitInt(3) a3 = 2; _BitInt(33) a33 = 1; char c = 3;
      |                                               ^~
p45.c:73:11: error: unknown type name '_BitInt'
   73 | void func(_BitInt(8) a1, _BitInt(24) a2) {
      |           ^~~~~~~
p45.c:73:26: error: unknown type name '_BitInt'
   73 | void func(_BitInt(8) a1, _BitInt(24) a2) {
      |                          ^~~~~~~

$ gcc p45.c -std=c2x -o p45g -I. -Wall
p45.c:69:9: error: expected declaration specifiers or '...' before numeric constant
   69 | _BitInt(2) a2 = 1; _BitInt(3) a3 = 2; _BitInt(33) a33 = 1; char c = 3;
      |         ^
p45.c:69:28: error: expected declaration specifiers or '...' before numeric constant
   69 | _BitInt(2) a2 = 1; _BitInt(3) a3 = 2; _BitInt(33) a33 = 1; char c = 3;
      |                            ^
p45.c:69:47: error: expected declaration specifiers or '...' before numeric constant
   69 | _BitInt(2) a2 = 1; _BitInt(3) a3 = 2; _BitInt(33) a33 = 1; char c = 3;
      |                                               ^~
p45.c:73:11: error: unknown type name '_BitInt'
   73 | void func(_BitInt(8) a1, _BitInt(24) a2) {
      |           ^~~~~~~
p45.c:73:26: error: unknown type name '_BitInt'
   73 | void func(_BitInt(8) a1, _BitInt(24) a2) {
      |                          ^~~~~~~

検討事項(agenda)

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

応用例1 MISRA C/C++

MISRA C まとめ #include

MISRA C++ 5-0-16

応用例2 CERT C/C++

SEI CERT C++ Coding Standard AA. Bibliography 確認中。

MISRA C/C++, AUTOSAR C++, CERT C/C++とC/C++工業標準をコンパイルする

自己参考資料(self reference)

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

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

C言語教育はCコンパイラの写経で

C2011コンパイル一覧@researchmap

https://researchmap.jp/jownvh0ye-1797580/#_1797580

[C][C++]の国際規格案の例題をコンパイルするときの課題7つ。

C Puzzle Bookの有り難み5つ、C言語規格及びCコンパイラの特性を認識

dockerにclang

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

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

astyle 使ってみた

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

文書履歴(document history)

ver. 0.01 初稿  20221015
ver. 0.02 N3054 URLリンク切れ 変更 20221029

最後までおよみいただきありがとうございました。

いいね 💚、フォローをお願いします。

Thank you very much for reading to the last sentence.

Please press the like icon 💚 and follow me for your happy life.

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