はじめに(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)まで進んだものと色々ある状態です。一歩でも前に進むご助言をお待ちしています。「検討事項」の欄に現状を記録するようにしています。
$ docker run -v /Users/ogawakiyoshi/n4910/n3540:/Users/ogawakiyoshi/n4910/n3054 -it kaizenjapan/n3054 /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.4 Lexical elements CN3054:2022 (6) p51.c
算譜(source code)
// 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.4 Lexical elements CN3054:2022 (6) p51.c";
// 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++N3054:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list
#include "n3054.h"
// 6.4 Lexical elements
// Syntax
// token:
// preprocessing-token: header-name
// Constraints
// keyword identifier constant string-literal punctuator
// identifier pp-number character-constant string-literal punctuator
// each universal-character-name that cannot be one of the above each non-white-space character that cannot be one of the above
// Each preprocessing token that is converted to a token shall have the lexical form of a keyword, an identifier, a constant, a string literal, or a punctuator. A single universal character name shall match one of the other preprocessing token categories.
// Semantics
// A token is the minimal lexical element of the language in translation phases 7 and 8. The categories of tokens are: keywords, identifiers, constants, string literals, and punctuators. A preprocessing token is the minimal lexical element of the language in translation phases 3 through 6. The categories of preprocessing tokens are: header names, identifiers, preprocessing numbers, character constants, string literals, punctuators, and both single universal character names as well as single non-white- space characters that do not lexically match the other preprocessing token categories.73) If a ’ or a " character matches the last category, the behavior is undefined. Preprocessing tokens can be separated by white space; this consists of comments (described later), or white-space characters (space, horizontal tab, new-line, vertical tab, and form-feed), or both. As described in 6.10, in certain circumstances during translation phase 4, white space (or the absence thereof) serves as more than preprocessing token separation. White space may appear within a preprocessing token only as part of a header name or between the quotation characters in a character constant or string literal.
// If the input stream has been parsed into preprocessing tokens up to a given character, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token. There is one exception to this rule: header name preprocessing tokens are recognized only within # include and #embed preprocessing directives, in __has_include and __has_embed expressions, as well as in implementation-defined locations within #pragma directives. In such contexts, a sequence of characters that could be either a header name or a string literal is recognized as the former.
// EXAMPLE 1 The program fragment 1Ex is parsed as a preprocessing number token (one that is not a valid floating or integer constant token), even though a parse as the pair of preprocessing tokens 1 and Ex might produce a valid expression (for example, if Ex were a macro defined as +1). Similarly, the program fragment 1E1 is parsed as a preprocessing number (one that is a valid floating constant token), whether or not E is a macro name.
// EXAMPLE 2 The program fragment x+++++y is parsed as x ++ ++ + y, which violates a constraint onincrementoperators,eventhoughtheparsex ++ + ++ ymightyieldacorrectexpression.
// 73)An additional category, placemarkers, is used internally in translation phase 4 (see 6.10.4.3); it cannot occur in source files.
// Forward references: character constants (6.4.4.4), comments (6.4.9), expressions (6.5), floating constants (6.4.4.2), header names (6.4.7), macro replacement (6.10.4), postfix increment and decrement operators (6.5.2.4), prefix increment and decrement operators (6.5.3.1), preprocessing directives (6.10), preprocessing numbers (6.4.8), string literals (6.4.5).
// 6.4.1 Keywords Syntax
// Semantics
/* alignas
alignof
auto
bool
break
case
char
const
constexpr
continue
default
do
double else
enum
extern
false
float
for
goto
if
inline
int
long
nullptr
register
restrict
return
short
signed
sizeof
static
static_assert
struct
switch
thread_local
true
typedef
typeof
typeof_unqual
union
unsigned
void
volatile
while
_Atomic
_BitInt
_Complex
_Decimal128
_Decimal32
_Decimal64
_Generic
_Imaginary
_Noreturn
Keyword
alignas
alignof
bool
static_assert
thread_local
Alternative Spelling
_Alignas
_Alignof
_Bool
_Static_assert
_Thread_local
identifier:
identifier-start:*/
// The spelling of these keywords, their alternate forms, and of false and true inside expressions that are subject to the # and ## preprocessing operators is unspecified.76)
// 6.4.2 Identifiers
// 6.4.2.1 General Syntax
// identifier-start
// identifier identifier-continue
// nondigit
// XID_Start character universal-character-name of class XID_Start
// 74)One possible specification for imaginary types appears in Annex G.
// 75)These alternative keywords are obsolescent features and should not be used for new code and development.
// 76)The intent of this specification is to allow but not force the implementation of the corresponding feature by means of a predefined macro.
// identifier-continue:
// digit
// nondigit
// XID_Continue character universal-character-name of class XID_Continue _abcdefghijklm nopqrstuvwxyz ABCDEFGHIJKLM NOPQRSTUVWXYZ0123456789
// nondigit: one of
// digit: one of
// Semantics
// An XID_Start character is an implementation-defined character whose corresponding code point in ISO/IEC 10646 has the XID_Start property. An XID_Continue character is an implementation- defined character whose corresponding code point in ISO/IEC 10646 has the XID_Continue property. An identifier is a sequence of one identifier start character followed by 0 or more identifier continue characters, which designates one or more entities as described in 6.2.1. Lowercase and uppercase letters are distinct. There is no specific limit on the maximum length of an identifier.
// The character classes XID_Start and XID_Continue are Derived Core Properties as described by UAX #4477). Each character and universal character name in an identifier shall designate a character whose encoding in ISO/IEC 10646 has the XID_Continue property. The initial character (which may be a universal character name) shall designate a character whose encoding in ISO/IEC 10646 has the XID_Start property. An identifier shall conform to Normalization Form C as specified in ISO/IEC 10646. Annex D provides an overview of the conforming identifiers.
// NOTE 1 Uppercase and lowercase letters are considered different for all identifiers.
// NOTE 2 In translation phase 4 (4), the term identifier also includes those preprocessing tokens (6.4.8) differentiated as keywords (6.4.1) in the later translation phase 7 (7).
// When preprocessing tokens are converted to tokens during translation phase 7, if a preprocessing token could be converted to either a keyword or an identifier, it is converted to a keyword except in an attribute token.
// Some identifiers are reserved.
// — All identifiers that begin with a double underscore (__) or begin with an underscore (_) followed by an uppercase letter are reserved for any use, except those identifiers which are lexically identical to keywords.78)
// — All identifiers that begin with an underscore are reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
// Other identifiers may be reserved, see 7.1.3.
// If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), the behavior is undefined.
// 77)On systems that cannot accept extended characters in external identifiers, an encoding of the universal-character-name may be used in forming such identifiers. For example, some otherwise unused character or sequence of characters may be used to encode the u in a universal character name.
// 78)This allows a reserved identifier that matches the spelling of a keyword to be used as a macro name by the program.
// If the program defines a reserved identifier or attribute token described in 6.7.12.1 as a macro name, or removes (with #undef) any macro definition of an identifier in the first group listed above or attribute token described in 6.7.12.1, the behavior is undefined.
// Some identifiers may be potentially reserved. A potentially reserved identifier is an identifier which is not reserved unless made so by an implementation providing the identifier (7.1.3) but is anticipated to become reserved by an implementation or a future version of this document.
// Recommended Practice
// Implementations are encouraged to issue a diagnostic message when a potentially reserved identifier is declared or defined for any use that is not implementation-compatible (see below) in a context where the potentially reserved identifier may be reserved under a conforming implementation. This brings attention to a potential conflict when porting a program to a future revision of this document.
// An implementation-compatible use of a potentially reserved identifier is a declaration of an external name where the name is provided by the implementation as an external name and where the declaration declares an object or function with a type that is compatible with the type of the object or function provided by the implementation under that name.
// Implementation limits
// As discussed in 5.2.4.1, an implementation may limit the number of significant initial characters in an identifier; the limit for an external name (an identifier that has external linkage) may be more restrictive than that for an internal name (a macro name or an identifier that does not have external linkage). The number of significant characters in an identifier is implementation-defined.
// Any identifiers that differ in a significant character are different identifiers. If two identifiers differ only in nonsignificant characters, the behavior is undefined.
// Forward references: universal character names (6.4.3), macro replacement (6.10.4), reserved library identifiers (7.1.3), use of library functions (7.1.4), attributes (6.7.12.1).
// 6.4.2.2 Predefined identifiers
// Semantics
// The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration
// static const char __func__[] = "function-name";
// error: p51.c:137:19: error: expected identifier or '(' before '__func__'
// 137 | static const char __func__[] = "function-name";
// | ^~~~~~~~
// appeared, where function-name is the name of the lexically-enclosing function.79)
// This name is encoded as if the implicit declaration had been written in the source character set and then translated into the execution character set as indicated in translation phase 5.
// EXAMPLE Consider the code fragment: Each time the function is called, it will print to the standard output stream: myfunc
// Forward references: function definitions (6.9.1).
// 79)Since the name __func__ is reserved for any use by the implementation (7.1.3), if any other identifier is explicitly declared using the name __func__, the behavior is undefined.
#include <stdio.h>
void myfunc(void) {
printf("%s\n", __func__);
/* ... */
}
// 6.4.3 Universal character names
// Syntax
// universal-character-name:
// \u hex-quad
// hex-quad:
// Constraints
// \U hex-quad hex-quad
// hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit
// A universal character name shall not designate a code point where the hexadecimal value is:
// — less than 00A0 other than 0024 ($), 0040 (@), or 0060 (` ); — in the range D800 through DFFF inclusive; or
// — greater than 10FFFF80).
// Description
// Universal character names may be used in identifiers, character constants, and string literals to designate characters that are not in the basic character set.
// Semantics
// The universal character name \Unnnnnnnn designates the character whose eight-digit short identifier (as specified by ISO/IEC 10646) is nnnnnnnn.81) Similarly, the universal character name \unnnn designates the character whose four-digit short identifier is nnnn (and whose eight-digit short identifier is 0000nnnn).
// 80)The disallowed characters are the characters in the basic character set and the code positions reserved by ISO/IEC 10646 for control characters, the character DELETE, the S-zone (reserved for use by UTF-16), and characters too large to be encoded by ISO/IEC 10646. Disallowed universal character escape sequences can still be specified with hexadecimal and octal escape sequences (6.4.4.4).
// 81)Short identifiers for characters were first specified in ISO/IEC 10646–1:1993/Amd 9:1997.
// constant:
// Constraints
// integer-constant floating-constant enumeration-constant character-constant predefined-constant
// 6.4.4 Constants Syntax
// Each constant shall have a type and the value of a constant shall be in the range of representable values for its type.
// Semantics
// Each constant has a type, determined by its form and value, as detailed later.
// 6.4.4.1 Integer constants Syntax
/* integer-constant:
decimal-constant:
octal-constant:
decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt binary-constant integer-suffixopt
nonzero-digit decimal-constant ’opt digit
octal-constant ’opt octal-digit
hexadecimal-constant:
hexadecimal-prefix hexadecimal-digit-sequence
binary-constant:
hexadecimal-prefix: one of 0x 0X
binary-prefix: one of
0b 0B
binary-prefix binary-digit binary-constant ’opt binary-digit
nonzero-digit: one of
octal-digit: one of
123456789
01234567
hexadecimal-digit-sequence: hexadecimal-digit
hexadecimal-digit-sequence ’opt hexadecimal-digit
hexadecimal-digit: one of 0123456789
abcdef ABCDEF
binary-digit: one of 01
integer-suffix:
unsigned-suffix long-suffixopt unsigned-suffix long-long-suffix unsigned-suffix bit-precise-int-suffix long-suffix unsigned-suffixopt long-long-suffix unsigned-suffixopt bit-precise-int-suffix unsigned-suffixopt
bit-precise-int-suffix: one of wb WB
unsigned-suffix: one of uU
long-suffix: one of
lL
long-long-suffix: one of ll LL
Description */
// An integer constant begins with a digit, but has no period or exponent part. It may have a prefix that specifies its base and a suffix that specifies its type. An optional separating single quote character (’) in an integer or floating constant is called a digit separator. Digit separators are ignored when determining the value of the constant.
// EXAMPLE The following integer constants use digit separators; the comment associated with each constant shows the equivalent constant without digit separators.
// A decimal constant begins with a nonzero digit and consists of a sequence of decimal digits. An octal constant consists of the prefix 0 optionally followed by a sequence of the digits 0 through 7 only. A hexadecimal constant consists of the prefix 0x or 0X followed by a sequence of the decimal digits and the letters a (or A) through f (or F) with values 10 through 15 respectively. A binary constant consists of the prefix 0b or 0B followed by a sequence of the digits 0 or 1.
// Semantics
// The value of a decimal constant is computed base 10; that of an octal constant, base 8; that of a hexadecimal constant, base 16; that of a binary constant, base 2. The lexically first digit is the most significant.
// The type of an integer constant is the first of the corresponding list in which its value can be represented.
// 0b11’10’11’01 /* 0b11101101 */
// ’1’2 /* character constant ’1’ followed by integer constant 2, not the integer constant 12 */
// 11’22 /* 1122 */
// 0x’FFFF’FFFF /* invalid hexadecimal constant (’ cannot appear after 0x) */ 0x1’2’3’4AB’C’D /* 0x1234ABCD */
/* Suffix none
uorU lorL
Both u or U and lor L
ll or LL Both u or U
and ll or LL wb or WB
Both u or U and wb or WB
Octal, Hexadecimal or Binary Constant
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
unsigned int
int unsigned
Decimal Constant
int
long int
long long int
unsigned
unsigned
unsigned
long int
long long int
unsigned long
unsigned long
long long int
unsigned long
int long long
long int
int
long int
long int
long int
long long int
unsigned
long int
unsigned
long long int
unsigned long long int
unsigned long int
unsigned long long int
long long int
unsigned long long int
unsigned long long int
long int
_BitInt(N) where the width N
is the smallest N greater than */
// which can accommodate the value and the sign bit. unsigned _BitInt(N)wherethe unsigned _BitInt(N)wherethe _BitInt(N) where the width N is the smallest N greater than
// which can accommodate
// the value and the sign bit.
// width N is the smallest N greater than 0 which can accommodate the value. width N is the smallest N greater than 0 which can accommodate the value.
// If an integer constant cannot be represented by any type in its list, it may have an extended integer type, if the extended integer type can represent its value. If all the types in the list for the constant are signed, the extended integer type shall be signed. If all the types in the list for the constant are unsigned, the extended integer type shall be unsigned. If the list contains both signed and unsigned types, the extended integer type may be signed or unsigned. If an integer constant cannot be represented by any type in its list and has no extended integer type, then the integer constant has no type.
// EXAMPLE 1 The wb suffix results in an _BitInt that includes space for the sign bit even if the value of the constant is positive or was specified in hexadecimal or octal notation.
// Forward references: preprocessing numbers (6.4.8), numeric conversion functions (7.24.1).
// 6.4.4.2 Floating constants Syntax
// floating-constant:
// decimal-floating-constant hexadecimal-floating-constant
// decimal-floating-constant:
// fractional-constant exponent-partopt floating-suffixopt
// digit-sequence exponent-part floating-suffixopt
// hexadecimal-floating-constant:
// hexadecimal-prefix hexadecimal-fractional-constant
// -3wb /* Yields an _BitInt(3) that is then negated; two value bits, one sign bit */
// -0x3wb /* Yields an _BitInt(3) that is then negated; two value bits, one sign bit */
// 3wb /* Yields an _BitInt(3); two value bits, one sign bit */ 3uwb /* Yields an unsigned _BitInt(2) */
// -3uwb /* Yields an unsigned _BitInt(2) that is then negated, resulting in wraparound */ 1
/* fractional-constant:
binary-exponent-part floating-suffixopt hexadecimal-prefix hexadecimal-digit-sequence
binary-exponent-part floating-suffixopt
digit-sequenceopt . digit-sequence digit-sequence .
e signopt digit-sequence E signopt digit-sequence
+-
exponent-part:
sign: one of
digit-sequence:
digit
digit-sequence ’opt digit
hexadecimal-fractional-constant:
hexadecimal-digit-sequenceopt . hexadecimal-digit-sequence
hexadecimal-digit-sequence .
binary-exponent-part:
p signopt digit-sequence
P signopt digit-sequence floating-suffix: one of
f l F L df dd dl DF DD DL */
// Constraints
// A floating suffix df, dd, dl, DF, DD, or DL shall not be used in a hexadecimal floating constant. Description
// A floating constant has a significand part that may be followed by an exponent part and a suffix that specifies its type. The components of the significand part may include a digit sequence representing the whole-number part, followed by a period ( .), followed by a digit sequence representing the fraction part. Digit separators (6.4.4.1) are ignored when determining the value of the constant. The components of the exponent part are an e, E, p, or P followed by an exponent consisting of an optionally signed digit sequence. Either the whole-number part or the fraction part has to be present; for decimal floating constants, either the period or the exponent part has to be present.
// Semantics
// The significand part is interpreted as a (decimal or hexadecimal) rational number; the digit sequence in the exponent part is interpreted as a decimal integer. For decimal floating constants, the exponent indicates the power of 10 by which the significand part is to be scaled. For hexadecimal floating constants, the exponent indicates the power of 2 by which the significand part is to be scaled. For decimal floating constants, and also for hexadecimal floating constants when FLT_RADIX is not a power of 2, the result is either the nearest representable value, or the larger or smaller representable value immediately adjacent to the nearest representable value, chosen in an implementation-defined manner. For hexadecimal floating constants when FLT_RADIX is a power of 2, the result is correctly rounded.
// An unsuffixed floating constant has type double. If suffixed by a floating suffix it has a type according to the following table: Suffixes for floating constants
// The values of floating constants may be represented in greater range and precision than that required by the type (determined by the suffix); the types are not changed thereby. See 5.2.4.2.2 regarding evaluation formats. 82)
// 82)Hexadecimal floating constants can be used to obtain exact values in the semantic type that are independent of the
/* Suffix
Type
f, F
float
l, L
long double
df, DF
_Decimal32
dd, DD
_Decimal64
dl, DL
_Decimal128 */
// Floating constants of decimal floating type that have the same numerical value but different quantum exponents have distinguishable internal representations. The value shall be correctly rounded as specified in IEC 60559. The coefficient c and the quantum exponent q of a finite converted decimal floating-point number (see 5.2.4.2.3) are determined as follows:
// — q is set to the value of signopt digit-sequence in the exponent part, if any, or to 0, otherwise.
// — If there is a fractional constant, q is decreased by the number of digits to the right of the period and the period is removed to form a digit sequence.
// — c is set to the value of the digit sequence (after any period has been removed).
// — Rounding required because of insufficient precision or range in the type of the result will round c to the full precision available in the type, and will adjust q accordingly within the limits of the type, provided the rounding does not yield an infinity (in which case the result is an appropriately signed internal representation of infinity). If the full precision of the type would require q to be smaller than the minimum for the type, then q is pinned at the minimum and c is adjusted through the subnormal range accordingly, perhaps to zero.
// Floating constants are converted to internal format as if at translation-time. The conversion of a floating constant shall not raise an exceptional condition or a floating-point exception at execution time. All floating constants of the same source form 83) shall convert to the same internal format with the same value.
// EXAMPLE Following are floating constants of type _Decimal64 and their values as triples (s, c, q). Note that for _Decimal64, the precision (maximum coefficient length) is 16 and the quantum exponent range is −398 ≤ q ≤ 369.
/* 0.dd
0.00dd
123.dd
1.23E3dd
1.23E+3dd
12.3E+7dd
12.0dd
12.3dd
0.00123dd
1.23E-12dd
1234.5E-4dd
0E+7dd
12345678901234567890.dd
1234E-400dd
1234E-402dd
1000.dd
.0001dd
1000.e0dd
.0001e0dd
1000.0dd
0.0001dd
1000.00dd
00.0001dd
(+1, 0, 0)
(+1, 0, −2) (+1, 123, 0) (+1, 123, 1) (+1, 123, 1) (+1, 123, 6) (+1, 120, −1) (+1, 123, −1) (+1, 123, −5) (+1, 123, −14) (+1, 12345, −5) (+1, 0, 7)
assuming
default
rounding and
(+1, 1234567890123457, 4)
DEC_EVAL_METHOD is 0 or 184)
(+1, 12, −398) assuming default rounding and DEC_EVAL_METHOD is 0 or 1
(+1, 0, −398) assuming default rounding and DEC_EVAL_METHOD is 0 or 1
(+1, 1000, 0)
(+1, 1, −4)
(+1, 1000, 0)
(+1, 1, −4)
(+1, 10000, −1)
(+1, 1, −4)
(+1, 100000, −2)
(+1, 1, −4) */
// evaluation format. Casts produce values in the semantic type, though depend on the rounding mode and may raise the inexact floating-point exception.
// 83)1.23, 1.230, 123e-2, 123e-02, and 1.23L are all different source forms and thus need not convert to the same internal format and value.
// The implementation should produce a diagnostic message if a hexadecimal constant cannot be represented exactly in its evaluation format; the implementation should then proceed with the translation of the program.
// The translation-time conversion of floating constants should match the execution-time conversion of character strings by library functions, such as strtod, given matching inputs suitable for both conversions, the same result format, and default execution-time rounding. 85)
// NOTE 1 Floating constants do not include a sign and are negated by the unary − operator (6.5.3.3) which negates the rounded value of the constant. In contrast, the numeric conversion functions in the strto family (7.24.1.5, 7.24.1.6) may include the sign as part of the input value and convert and round the negated input; Annex F requires this behavior. Negating before rounding and negating after rounding might yield different results, depending on the rounding direction and whether the results are correctly rounded. For example, the results are the same when both are correctly rounded using rounding to nearest or rounding toward zero, but the results are different when they are inexact and correctly rounded using rounding toward positive infinity or rounding toward negative infinity.
// Conversions yielding exact results require no rounding, so are not affected by the order of negating and rounding. For types with radix 10, decimal floating constants expressed within the precision and range of the evaluation format convert exactly. For types whose radix is a power of 2, hexadecimal floating constants expressed within the precision and range of the evaluation format convert exactly.
// Forward references: preprocessing numbers (6.4.8), numeric conversion functions (7.24.1), the strto function family (7.24.1.5, 7.24.1.6).
// 6.4.4.3 Enumeration constants Syntax
// enumeration-constant: identifier
// Semantics
// An identifier declared as an enumeration constant for an enumeration without a fixed underlying type has either type int or the enumerated type, as defined in 6.7.2.2. An identifier declared as an enumeration constant for an enumeration with a fixed underlying type has the associated enumeration type.
// An enumeration constant may be used in an expression (or constant expression) wherever a value of an integer type may be used.
// Forward references: enumeration specifiers (6.7.2.2).
// 6.4.4.4 Character constants Syntax
// character-constant: encoding-prefixopt ’ c-char-sequence ’
// 84)That is, assuming the default translation rounding-direction mode is not changed by an FENV_DEC_ROUND pragma (7.6.3).
// 85)The specification for the library functions recommends more accurate conversion than required for floating constants (see 7.24.1.5).
// 001000.dd 001000.0dd 001000.00dd 00.00dd 00.dd .00dd 00.00e-5dd 00.e-5dd .00e-5dd
// Recommended practice
// (+1, 1000, 0) (+1, 10000, −1) (+1, 100000, −2) (+1, 0, −2) (+1, 0, 0) (+1, 0, −2) (+1, 0, −7) (+1, 0, −5) (+1, 0, −7)
// encoding-prefix: one of u8
// uUL
// c-char-sequence:
// c-char
// c-char:
// escape-sequence:
// c-char-sequence c-char
// any member of the source character set except
// the single-quote ’, backslash \, or new-line character
// escape-sequence
// simple-escape-sequence octal-escape-sequence hexadecimal-escape-sequence // universal-character-name
// simple-escape-sequence: one of \’ \" \? \\ \a \b \f \n \r \t \v
// octal-escape-sequence:
// \ octal-digit
// \ octal-digit octal-digit
// \ octal-digit octal-digit octal-digit
// hexadecimal-escape-sequence:
// \x hexadecimal-digit
// hexadecimal-escape-sequence hexadecimal-digit
// Description
// An integer character constant is a sequence of one or more multibyte characters enclosed in single- quotes, as in ’x’. A UTF-8 character constant is the same, except prefixed by u8. A wchar_t character constant is prefixed by the letter L. A UTF-16 character constant is prefixed by the letter u. A UTF-32 character constant is prefixed by the letter U. Collectively, wchar_t, UTF-16, and UTF-32 character constants are called wide character constants. With a few exceptions detailed later, the elements of the sequence are any members of the source character set; they are mapped in an implementation- defined manner to members of the execution character set.
// The single-quote ’, the double-quote ", the question-mark ?, the backslash \, and arbitrary integer values are representable according to the following table of escape sequences:
// single quote’
// double quote " question mark ? backslash \
// octal character hexadecimal character
// \’
// \"
// \?
// \\
// \octal digits
// \x hexadecimal digits
// The double-quote " and question-mark ? are representable either by themselves or by the escape sequences \" and \?, respectively, but the single-quote ’ and the backslash \ shall be represented, respectively, by the escape sequences \’ and \\.
// The octal digits that follow the backslash in an octal escape sequence are taken to be part of the construction of a single character for an integer character constant or of a single wide character for a wide character constant. The numerical value of the octal integer so formed specifies the value of the desired character or wide character.
// The hexadecimal digits that follow the backslash and the letter x in a hexadecimal escape sequence are taken to be part of the construction of a single character for an integer character constant or of a single wide character for a wide character constant. The numerical value of the hexadecimal integer so formed specifies the value of the desired character or wide character.
// Each octal or hexadecimal escape sequence is the longest sequence of characters that can constitute the escape sequence.
// In addition, characters not in the basic character set are representable by universal character names and certain non-graphic characters are representable by escape sequences consisting of the back- slash \ followed by a lowercase letter: \a, \b, \f, \n, \r, \t, and \v.86)
// Constraints
// The value of an octal or hexadecimal escape sequence shall be in the range of representable values for the corresponding type: Prefix Corresponding Type none unsigned char u8 char8_t L the unsigned type corresponding to wchar_t u char16_t U char32_t
// A UTF-8, UTF-16, or UTF-32 character constant shall not contain more than one character.87) The value shall be representable with a single UTF-8, UTF-16, or UTF-32 code unit, respectively.
// Semantics
// An integer character constant has type int. The value of an integer character constant containing a single character that maps to a single value in the literal encoding (6.2.9) is the numerical value of the representation of the mapped character in the literal encoding interpreted as an integer. The value of an integer character constant containing more than one character (e.g., ’ab’), or containing a character or escape sequence that does not map to a single value in the literal encoding, is implementation-defined. If an integer character constant contains a single character or escape sequence, its value is the one that results when an object with type char whose value is that of the single character or escape sequence is converted to type int.
// A UTF-8 character constant has type char8_t. If the UTF-8 character constant is not produced through a hexadecimal or octal escape sequence, the value of a UTF-8 character constant is equal to its ISO/IEC 10646 code point value, provided that the code point value can be encoded as a single UTF-8 code unit. Otherwise, the value of the UTF-8 character constant is the numeric value specified in the hexadecimal or octal escape sequence.
// A UTF-16 character constant has type char16_t which is an unsigned integer types defined in the <uchar.h> header. If the UTF-16 character constant is not produced through a hexadecimal or octal escape sequence, the value of a UTF-16 character constant is equal to its ISO/IEC 10646 code point value, provided that the code point value can be encoded as a single UTF-16 code unit. Otherwise, the value of the UTF-16 character constant is the numeric value specified in the hexadecimal or octal escape sequence.
// A UTF-32 character constant has type char32_t which is an unsigned integer types defined in the <uchar.h> header. If the UTF-32 character constant is not produced through a hexadecimal or octal escape sequence, the value of a UTF-32 character constant is equal to its ISO/IEC 10646 code point value, provided that the code point value can be encoded as a single UTF-32 code unit. Otherwise, the value of the UTF-32 character constant is the numeric value specified in the hexadecimal or octal escape sequence.
// 86)The semantics of these characters were discussed in 5.2.2. If any other character follows a backslash, the result is not a token and a diagnostic is required. See "future language directions" (6.11.4).
// 87)For example u8’ab’ violates this constraint.
// A wchar_t character constant prefixed by the letter L has type wchar_t, an integer type defined in the <stddef.h> header. The value of a wchar_t character constant containing a single multibyte character that maps to a single member of the extended execution character set is the wide character corresponding to that multibyte character in the implementation-defined wide literal encoding (6.2.9). The value of a wchar_t character constant containing more than one multibyte character or a single multibyte character that maps to multiple members of the extended execution character set, or containing a multibyte character or escape sequence not represented in the extended execution character set, is implementation-defined.
// EXAMPLE 1 The construction ’\0’ is commonly used to represent the null character.
// EXAMPLE 2 Consider implementations that use eight bits for objects that have type char. In an implementation in which type char has the same range of values as signed char, the integer character constant ’\xFF’ has the value −1; if type char has the same range of values as unsigned char, the character constant ’\xFF’ has the value +255.
// EXAMPLE 3 Even if eight bits are used for objects that have type char, the construction ’\x123’ specifies an integer character constant containing only one character, since a hexadecimal escape sequence is terminated only by a non-hexadecimal character. To specify an integer character constant containing the two characters whose values are ’\x12’ and ’3’, the construction ’\0223’ can be used, since an octal escape sequence is terminated after three octal digits. (The value of this two- character integer character constant is implementation-defined.)
// EXAMPLE 4 Even if 12 or more bits are used for objects that have type wchar_t, the construction L’\1234’ specifies the implementation-defined value that results from the combination of the values 0123 and ’4’.
// Forward references: common definitions <stddef.h> (7.21), the mbtowc function (7.24.7.2), Uni- code utilities <uchar.h> (7.30).
// 6.4.4.5 Predefined constants
// Syntax
// predefined-constant: false
// true nullptr
// Description
// Some keywords represent constants of a specific value and type.
// The keywords false and true are constants of type bool with a value of 0 for false and 1 for true88) .
// The keyword nullptr represents a null pointer constant. Details of its type are described in 7.21.2.
// 6.4.5 String literals
// Syntax
// string-literal: encoding-prefixopt " s-char-sequenceopt "
// 88)The constants false and true promote to type int, see 6.3.1.1. When used for arithmetic, in translation phase 4, they are signed values and the result of such arithmetic is consistent with the results of later translation phases.
// s-char-sequence:
// s-char
// s-char:
// Constraints
// s-char-sequence s-char
// any member of the source character set except the double-quote ", backslash \, or new-line character escape-sequence
// If a sequence of adjacent string literal tokens includes prefixed string literal tokens, the prefixed tokens shall all have the same prefix.
// Description
// A character string literal is a sequence of zero or more multibyte characters enclosed in double-quotes, as in "xyz". A UTF-8 string literal is the same, except prefixed by u8. A wchar_t string literal is the same, except prefixed by L. A UTF-16 string literal is the same, except prefixed by u. A UTF-32 string literal is the same, except prefixed by U. Collectively, wchar_t, UTF-16, and UTF-32 string literals are called wide string literals.
// The same considerations apply to each element of the sequence in a string literal as if it were in an integer character constant (for a character or UTF-8 string literal) or a wide character constant (for a wide string literal), except that the single-quote ’ is representable either by itself or by the escape sequence \’, but the double-quote " shall be represented by the escape sequence \".
// Semantics
// In translation phase 6, the multibyte character sequences specified by any sequence of adjacent character and identically-prefixed string literal tokens are concatenated into a single multibyte character sequence. If any of the tokens has an encoding prefix, the resulting multibyte character sequence is treated as having the same prefix; otherwise, it is treated as a character string literal.
// In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. // 89) The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence corresponding to the literal encoding (6.2.9). For UTF-8 string literals, the array elements have type char8_t, and are initialized with the characters of the multibyte character sequence, as encoded in UTF-8. For wide string literals prefixed by the letter L, the array elements have type wchar_t and are initialized with the sequence of wide characters corresponding to the wide literal encoding. For wide string literals prefixed by the letter u or U, the array elements have type char16_t or char32_t, respectively, and are initialized sequence of wide characters corresponding to UTF-16 and UTF-32 encoded text, respectively. The value of a string literal containing a multibyte character or escape sequence not represented in the execution character set is implementation-defined. Any hexadecimal escape sequence or octal escape sequence specified in a u8, u, or U string specifies a single char8_t, char16_t, or char32_t value and may result in the full character sequence not being valid UTF-8, UTF-16, or UTF-32.
// It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.
// EXAMPLE
// This pair of adjacent character string literals "\x12" "3"
// 89)A string literal might not be a string (see 7.1.1), because a null character can be embedded in it by a \0 escape sequence.
// produces a single character string literal containing the two characters whose values are ’\x12’ and ’3’, because escape sequences are converted into single members of the execution character set just prior to adjacent string literal concatenation.
// EXAMPLE 2 Each of the sequences of adjacent string literal tokens is equivalent to the string literal L"abc" Likewise, each of the sequences is equivalent to u"abc"
// Forward references: common definitions <stddef.h> (7.21), the mbstowcs function (7.24.8.1), Unicode utilities <uchar.h> (7.30).
// 6.4.6 Punctuators
// Syntax
// punctuator: one of[ ] ( ) { } . -> ++ -- & * + - ~ ! / % << >> < > <= >= == != ^ | && || ? : :: ; ... = *= /= %= += -= <<= >>= &= ^= |= , # ## <: :> <% %> %: %:%:
// Semantics
// A punctuator is a symbol that has independent syntactic and semantic significance. Depending on context, it may specify an operation to be performed (which in turn may yield a value or a function designator, produce a side effect, or some combination thereof) in which case it is known as an operator (other forms of operator also exist in some contexts). An operand is an entity on which an operator acts.
// "a" "b" L"c" "a" L"b" "c" L"a" "b" L"c" L"a" L"b" L"c" "a" "b" u"c" "a" u"b" "c" u"a" "b" u"c" u"a" u"b" u"c"
// In all aspects of the language, the six tokens90) <: :> <% %> %: %:%: behave, respectively, the same as the six tokens [ ] { } # ##
// except for their spelling.91)
// 90)These tokens are sometimes called "digraphs".
// 91)Thus [ and <: behave differently when "stringized" (see 6.10.4.2), but can otherwise be freely interchanged. 68 Language
// references: expressions (6.5), declarations (6.7), preprocessing directives (6.10), statements
// 6.4.7 Header names
// Syntax
// header-name:
// h-char-sequence:
// h-char
// h-char:
// h-char-sequence h-char
// any member of the source character set except the new-line character and >
// q-char-sequence:
// q-char
// q-char:
// Semantics
// q-char-sequence q-char
// any member of the source character set except the new-line character and " < h-char-sequence > " q-char-sequence "
// The sequences in both forms of header names are mapped in an implementation-defined manner to headers or external source file names as specified in 6.10.2.
// If the characters ’, \, ", //, or /* occur in the sequence between the < and > delimiters, the behavior is undefined. Similarly, if the characters ’, \, //, or /* occur in the sequence between the " delimiters, the behavior is undefined.92) Header name preprocessing tokens are recognized only within #include preprocessing directives and in implementation-defined locations within #pragma directives.93)
// EXAMPLE The following sequence of characters: forms the following sequence of preprocessing tokens (with each individual preprocessing token delimited by a { on the left and a } on the right).
// 92)Thus, sequences of characters that resemble escape sequences cause undefined behavior. 93)For an example of a header name preprocessing token used in a #pragma directive, see 6.10.10.
// 0x3<1/a.h>1e2
// p51.c:497:10: error: expected identifier or '(' before numeric constant
// 497 | 0x3<1/a.h>1e2
// | ^~~
#include <1/a.h>
#define const.member@$
// p51.c:499:9: warning: ISO C99 requires whitespace after the macro name
// 499 | #define const.member@$
// | ^~~~~
// p51.c:499:21: error: stray '@' in program
// 499 | #define const.member@$
// | ^
// {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// errpr: p51.c:500:27: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:30: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:33: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:36: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:39: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:42: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:45: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:48: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:54: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:55: error: stray '#' in program
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:57: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:67: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// |
// {#}{define} {const}{.}{member}{@}{$}
// p51.c:501:1: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
// p51.c:501:2: error: stray '#' in program
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:4: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:13: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
// error:p51.c:501:14: note: in expansion of macro 'const'
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^~~~~
//p51.c:501:20: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:23: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:31: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:32: error: stray '@' in program
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:34: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
// Forward references: source file inclusion (6.10.2).
// 6.4.8 Preprocessing numbers
// Syntax
// pp-number:
// Description
// digit
// . digit
// pp-number identifier-continue pp-number ’ digit pp-number ’ nondigit pp-number e sign pp-number E sign pp-number p sign pp-number P sign pp-number .
// A preprocessing number begins with a digit optionally preceded by a period (.) and may be followed by valid identifier characters and the character sequences e+, e-, E+, E-, p+, p-, P+, or P-.
// Preprocessing number tokens lexically include all floating and integer constant tokens.
// Semantics
// A preprocessing number does not have type or a value; it acquires both after a successful conversion (as part of translation phase 7) to a floating constant token or an integer constant token.
// 6.4.9 Comments
// Except within a character constant, a string literal, or a comment, the characters /* introduce a comment. The contents of such a comment are examined only to identify multibyte characters and to find the characters */ that terminate it.94)
// Except within a character constant, a string literal, or a comment, the characters // introduce a comment that includes all multibyte characters up to, but not including, the next new-line character. The contents of such a comment are examined only to identify multibyte characters and to find the terminating new-line character.
// EXAMPLE
// "a//b"
// error:p51.c:518:2: error: expected identifier or '(' before string constant
// 518 | "a//b"
// | ^~~~~~
// #include "//e"
// error: p51.c:518:10: fatal error: //e: No such file or directory
// 518 | #include "//e"
// | ^~~~~
// */
void f1(void) {
int f;
int g = 1;
int h = 2;
f = g/**//h;
}
//\
void i() {}
void j() {}
void l() {}
i();
/\
/ j();
#define glue(x,y) x##y glue(/,/) k();
void f2(void) {
/*//*/ l();
int m;
int n=3;
int p=4;
m = n//**/o
+ p;
}
// four-character string literal // undefined behavior
// comment, not syntax error
// equivalent to f = g / h;
// part of a two-line comment
// part of a two-line comment
// syntax error, not comment // equivalent to l();
// equivalent to m = n + p;
int main() {
// From here, the codes are added by Dr. Kiyosi Ogawa
f1();
f2();
#ifdef __has_include
PR("include", s);
#endif
int x = 1;
int y = 2;
// x = x+++++y;
x = x++ + ++y;
PR(x,d);
// To here, the codes are added by Dr. Kiyosi Ogawa
printf("%s\n", n3054);
return EXIT_SUCCESS;
}
編纂・実行結果(compile and go)
$ clang p51.c -std=11 -o p51l -I. -Wall
p51.c:505:14: warning: ISO C99 requires whitespace after the macro name [-Wc99-extensions]
#define const.member@$
^
p51.c:611:3: warning: multi-line // comment [-Wcomment]
//\
^
p51.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
int f;
^
p51.c:615:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
i();
^
p51.c:621:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
int m;
^
p51.c:644:10: warning: multiple unsequenced modifications to 'x' [-Wunsequenced]
x = x++ + ++y;
~ ^
6 warnings generated.
"include" = include
x = 4
6.4 Lexical elements CN3054:2022 (6) p51.c
$ clang p51.c -std=17 -o p51l -I. -Wall
p51.c:505:14: warning: ISO C99 requires whitespace after the macro name [-Wc99-extensions]
#define const.member@$
^
p51.c:611:3: warning: multi-line // comment [-Wcomment]
//\
^
p51.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
int f;
^
p51.c:615:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
i();
^
p51.c:621:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
int m;
^
p51.c:644:10: warning: multiple unsequenced modifications to 'x' [-Wunsequenced]
x = x++ + ++y;
~ ^
6 warnings generated.
"include" = include
x = 4
6.4 Lexical elements CN3054:2022 (6) p51.c
$ clang p51.c -std=2x -o p51l -I. -Wall
p51.c:505:14: warning: ISO C99 requires whitespace after the macro name [-Wc99-extensions]
#define const.member@$
^
p51.c:611:3: warning: multi-line // comment [-Wcomment]
//\
^
p51.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
int f;
^
p51.c:615:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
i();
^
p51.c:621:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
int m;
^
p51.c:644:10: warning: multiple unsequenced modifications to 'x' [-Wunsequenced]
x = x++ + ++y;
~ ^
6 warnings generated.
"include" = include
x = 4
6.4 Lexical elements CN3054:2022 (6) p51.c
$ gcc p51.c -std=11 -o p51g -I. -Wall
p51.c:410:1: warning: multi-line comment [-Wcomment]
410 | // double quote " question mark ? backslash \
| ^
p51.c:415:1: warning: multi-line comment [-Wcomment]
415 | // \\
| ^
p51.c:505:9: warning: ISO C99 requires whitespace after the macro name
505 | #define const.member@$
| ^~~~~
p51.c: In function 'f1':
p51.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
606 | int f;
| ^
p51.c: At top level:
p51.c:611:1: warning: multi-line comment [-Wcomment]
611 | //\
| ^
p51.c:615:1: warning: data definition has no type or storage class
615 | i();
| ^
p51.c:615:1: warning: type defaults to 'int' in declaration of 'i' [-Wimplicit-int]
p51.c:616:1: warning: multi-line comment [-Wcomment]
616 | /\
| ^
p51.c: In function 'f2':
p51.c:621:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
621 | int m;
| ^
p51.c: In function 'main':
p51.c:644:7: warning: operation on 'x' may be undefined [-Wsequence-point]
644 | x = x++ + ++y;
| ~~^~~~~~~~~~~
"include" = include
x = 4
6.4 Lexical elements CN3054:2022 (6) p51.c
$ gcc p51.c -std=c17 -o p51g -I. -Wall
p51.c:410:1: warning: multi-line comment [-Wcomment]
410 | // double quote " question mark ? backslash \
| ^
p51.c:415:1: warning: multi-line comment [-Wcomment]
415 | // \\
| ^
p51.c:505:9: warning: ISO C99 requires whitespace after the macro name
505 | #define const.member@$
| ^~~~~
p51.c: In function 'f1':
p51.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
606 | int f;
| ^
p51.c: At top level:
p51.c:611:1: warning: multi-line comment [-Wcomment]
611 | //\
| ^
p51.c:615:1: warning: data definition has no type or storage class
615 | i();
| ^
p51.c:615:1: warning: type defaults to 'int' in declaration of 'i' [-Wimplicit-int]
p51.c:616:1: warning: multi-line comment [-Wcomment]
616 | /\
| ^
p51.c: In function 'f2':
p51.c:621:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
621 | int m;
| ^
p51.c: In function 'main':
p51.c:644:7: warning: operation on 'x' may be undefined [-Wsequence-point]
644 | x = x++ + ++y;
| ~~^~~~~~~~~~~
"include" = include
x = 4
6.4 Lexical elements CN3054:2022 (6) p51.c
$ gcc p51.c -std=c2x -o p51g -I. -Wall
p51.c:410:1: warning: multi-line comment [-Wcomment]
410 | // double quote " question mark ? backslash \
| ^
p51.c:415:1: warning: multi-line comment [-Wcomment]
415 | // \\
| ^
p51.c:505:9: warning: ISO C99 requires whitespace after the macro name
505 | #define const.member@$
| ^~~~~
p51.c: In function 'f1':
p51.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
606 | int f;
| ^
p51.c: At top level:
p51.c:611:1: warning: multi-line comment [-Wcomment]
611 | //\
| ^
p51.c:615:1: warning: data definition has no type or storage class
615 | i();
| ^
p51.c:615:1: warning: type defaults to 'int' in declaration of 'i' [-Wimplicit-int]
p51.c:616:1: warning: multi-line comment [-Wcomment]
616 | /\
| ^
p51.c: In function 'f2':
p51.c:621:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
621 | int m;
| ^
p51.c: In function 'main':
p51.c:644:7: warning: operation on 'x' may be undefined [-Wsequence-point]
644 | x = x++ + ++y;
| ~~^~~~~~~~~~~
"include" = include
x = 4
6.4 Lexical elements CN3054:2022 (6) p51.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.4 Lexical elements CN3054:2022 (6) p51.c";
// 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++N3054:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list
#include "n3054.h"
// 6.4 Lexical elements
// Syntax
// token:
// preprocessing-token: header-name
// Constraints
// keyword identifier constant string-literal punctuator
// identifier pp-number character-constant string-literal punctuator
// each universal-character-name that cannot be one of the above each non-white-space character that cannot be one of the above
// Each preprocessing token that is converted to a token shall have the lexical form of a keyword, an identifier, a constant, a string literal, or a punctuator. A single universal character name shall match one of the other preprocessing token categories.
// Semantics
// A token is the minimal lexical element of the language in translation phases 7 and 8. The categories of tokens are: keywords, identifiers, constants, string literals, and punctuators. A preprocessing token is the minimal lexical element of the language in translation phases 3 through 6. The categories of preprocessing tokens are: header names, identifiers, preprocessing numbers, character constants, string literals, punctuators, and both single universal character names as well as single non-white- space characters that do not lexically match the other preprocessing token categories.73) If a ’ or a " character matches the last category, the behavior is undefined. Preprocessing tokens can be separated by white space; this consists of comments (described later), or white-space characters (space, horizontal tab, new-line, vertical tab, and form-feed), or both. As described in 6.10, in certain circumstances during translation phase 4, white space (or the absence thereof) serves as more than preprocessing token separation. White space may appear within a preprocessing token only as part of a header name or between the quotation characters in a character constant or string literal.
// If the input stream has been parsed into preprocessing tokens up to a given character, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token. There is one exception to this rule: header name preprocessing tokens are recognized only within # include and #embed preprocessing directives, in __has_include and __has_embed expressions, as well as in implementation-defined locations within #pragma directives. In such contexts, a sequence of characters that could be either a header name or a string literal is recognized as the former.
// EXAMPLE 1 The program fragment 1Ex is parsed as a preprocessing number token (one that is not a valid floating or integer constant token), even though a parse as the pair of preprocessing tokens 1 and Ex might produce a valid expression (for example, if Ex were a macro defined as +1). Similarly, the program fragment 1E1 is parsed as a preprocessing number (one that is a valid floating constant token), whether or not E is a macro name.
// EXAMPLE 2 The program fragment x+++++y is parsed as x ++ ++ + y, which violates a constraint onincrementoperators,eventhoughtheparsex ++ + ++ ymightyieldacorrectexpression.
// 73)An additional category, placemarkers, is used internally in translation phase 4 (see 6.10.4.3); it cannot occur in source files.
// Forward references: character constants (6.4.4.4), comments (6.4.9), expressions (6.5), floating constants (6.4.4.2), header names (6.4.7), macro replacement (6.10.4), postfix increment and decrement operators (6.5.2.4), prefix increment and decrement operators (6.5.3.1), preprocessing directives (6.10), preprocessing numbers (6.4.8), string literals (6.4.5).
// 6.4.1 Keywords Syntax
// Semantics
/* alignas
alignof
auto
bool
break
case
char
const
constexpr
continue
default
do
double else
enum
extern
false
float
for
goto
if
inline
int
long
nullptr
register
restrict
return
short
signed
sizeof
static
static_assert
struct
switch
thread_local
true
typedef
typeof
typeof_unqual
union
unsigned
void
volatile
while
_Atomic
_BitInt
_Complex
_Decimal128
_Decimal32
_Decimal64
_Generic
_Imaginary
_Noreturn
Keyword
alignas
alignof
bool
static_assert
thread_local
Alternative Spelling
_Alignas
_Alignof
_Bool
_Static_assert
_Thread_local
identifier:
identifier-start:*/
// The spelling of these keywords, their alternate forms, and of false and true inside expressions that are subject to the # and ## preprocessing operators is unspecified.76)
// 6.4.2 Identifiers
// 6.4.2.1 General Syntax
// identifier-start
// identifier identifier-continue
// nondigit
// XID_Start character universal-character-name of class XID_Start
// 74)One possible specification for imaginary types appears in Annex G.
// 75)These alternative keywords are obsolescent features and should not be used for new code and development.
// 76)The intent of this specification is to allow but not force the implementation of the corresponding feature by means of a predefined macro.
// identifier-continue:
// digit
// nondigit
// XID_Continue character universal-character-name of class XID_Continue _abcdefghijklm nopqrstuvwxyz ABCDEFGHIJKLM NOPQRSTUVWXYZ0123456789
// nondigit: one of
// digit: one of
// Semantics
// An XID_Start character is an implementation-defined character whose corresponding code point in ISO/IEC 10646 has the XID_Start property. An XID_Continue character is an implementation- defined character whose corresponding code point in ISO/IEC 10646 has the XID_Continue property. An identifier is a sequence of one identifier start character followed by 0 or more identifier continue characters, which designates one or more entities as described in 6.2.1. Lowercase and uppercase letters are distinct. There is no specific limit on the maximum length of an identifier.
// The character classes XID_Start and XID_Continue are Derived Core Properties as described by UAX #4477). Each character and universal character name in an identifier shall designate a character whose encoding in ISO/IEC 10646 has the XID_Continue property. The initial character (which may be a universal character name) shall designate a character whose encoding in ISO/IEC 10646 has the XID_Start property. An identifier shall conform to Normalization Form C as specified in ISO/IEC 10646. Annex D provides an overview of the conforming identifiers.
// NOTE 1 Uppercase and lowercase letters are considered different for all identifiers.
// NOTE 2 In translation phase 4 (4), the term identifier also includes those preprocessing tokens (6.4.8) differentiated as keywords (6.4.1) in the later translation phase 7 (7).
// When preprocessing tokens are converted to tokens during translation phase 7, if a preprocessing token could be converted to either a keyword or an identifier, it is converted to a keyword except in an attribute token.
// Some identifiers are reserved.
// — All identifiers that begin with a double underscore (__) or begin with an underscore (_) followed by an uppercase letter are reserved for any use, except those identifiers which are lexically identical to keywords.78)
// — All identifiers that begin with an underscore are reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
// Other identifiers may be reserved, see 7.1.3.
// If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), the behavior is undefined.
// 77)On systems that cannot accept extended characters in external identifiers, an encoding of the universal-character-name may be used in forming such identifiers. For example, some otherwise unused character or sequence of characters may be used to encode the u in a universal character name.
// 78)This allows a reserved identifier that matches the spelling of a keyword to be used as a macro name by the program.
// If the program defines a reserved identifier or attribute token described in 6.7.12.1 as a macro name, or removes (with #undef) any macro definition of an identifier in the first group listed above or attribute token described in 6.7.12.1, the behavior is undefined.
// Some identifiers may be potentially reserved. A potentially reserved identifier is an identifier which is not reserved unless made so by an implementation providing the identifier (7.1.3) but is anticipated to become reserved by an implementation or a future version of this document.
// Recommended Practice
// Implementations are encouraged to issue a diagnostic message when a potentially reserved identifier is declared or defined for any use that is not implementation-compatible (see below) in a context where the potentially reserved identifier may be reserved under a conforming implementation. This brings attention to a potential conflict when porting a program to a future revision of this document.
// An implementation-compatible use of a potentially reserved identifier is a declaration of an external name where the name is provided by the implementation as an external name and where the declaration declares an object or function with a type that is compatible with the type of the object or function provided by the implementation under that name.
// Implementation limits
// As discussed in 5.2.4.1, an implementation may limit the number of significant initial characters in an identifier; the limit for an external name (an identifier that has external linkage) may be more restrictive than that for an internal name (a macro name or an identifier that does not have external linkage). The number of significant characters in an identifier is implementation-defined.
// Any identifiers that differ in a significant character are different identifiers. If two identifiers differ only in nonsignificant characters, the behavior is undefined.
// Forward references: universal character names (6.4.3), macro replacement (6.10.4), reserved library identifiers (7.1.3), use of library functions (7.1.4), attributes (6.7.12.1).
// 6.4.2.2 Predefined identifiers
// Semantics
// The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration
// static const char __func__[] = "function-name";
// error: p51.c:137:19: error: expected identifier or '(' before '__func__'
// 137 | static const char __func__[] = "function-name";
// | ^~~~~~~~
// appeared, where function-name is the name of the lexically-enclosing function.79)
// This name is encoded as if the implicit declaration had been written in the source character set and then translated into the execution character set as indicated in translation phase 5.
// EXAMPLE Consider the code fragment: Each time the function is called, it will print to the standard output stream: myfunc
// Forward references: function definitions (6.9.1).
// 79)Since the name __func__ is reserved for any use by the implementation (7.1.3), if any other identifier is explicitly declared using the name __func__, the behavior is undefined.
#include <stdio.h>
void myfunc(void) {
printf("%s\n", __func__);
/* ... */
}
// 6.4.3 Universal character names
// Syntax
// universal-character-name:
// \u hex-quad
// hex-quad:
// Constraints
// \U hex-quad hex-quad
// hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit
// A universal character name shall not designate a code point where the hexadecimal value is:
// — less than 00A0 other than 0024 ($), 0040 (@), or 0060 (` ); — in the range D800 through DFFF inclusive; or
// — greater than 10FFFF80).
// Description
// Universal character names may be used in identifiers, character constants, and string literals to designate characters that are not in the basic character set.
// Semantics
// The universal character name \Unnnnnnnn designates the character whose eight-digit short identifier (as specified by ISO/IEC 10646) is nnnnnnnn.81) Similarly, the universal character name \unnnn designates the character whose four-digit short identifier is nnnn (and whose eight-digit short identifier is 0000nnnn).
// 80)The disallowed characters are the characters in the basic character set and the code positions reserved by ISO/IEC 10646 for control characters, the character DELETE, the S-zone (reserved for use by UTF-16), and characters too large to be encoded by ISO/IEC 10646. Disallowed universal character escape sequences can still be specified with hexadecimal and octal escape sequences (6.4.4.4).
// 81)Short identifiers for characters were first specified in ISO/IEC 10646–1:1993/Amd 9:1997.
// constant:
// Constraints
// integer-constant floating-constant enumeration-constant character-constant predefined-constant
// 6.4.4 Constants Syntax
// Each constant shall have a type and the value of a constant shall be in the range of representable values for its type.
// Semantics
// Each constant has a type, determined by its form and value, as detailed later.
// 6.4.4.1 Integer constants Syntax
/* integer-constant:
decimal-constant:
octal-constant:
decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt binary-constant integer-suffixopt
nonzero-digit decimal-constant ’opt digit
octal-constant ’opt octal-digit
hexadecimal-constant:
hexadecimal-prefix hexadecimal-digit-sequence
binary-constant:
hexadecimal-prefix: one of 0x 0X
binary-prefix: one of
0b 0B
binary-prefix binary-digit binary-constant ’opt binary-digit
nonzero-digit: one of
octal-digit: one of
123456789
01234567
hexadecimal-digit-sequence: hexadecimal-digit
hexadecimal-digit-sequence ’opt hexadecimal-digit
hexadecimal-digit: one of 0123456789
abcdef ABCDEF
binary-digit: one of 01
integer-suffix:
unsigned-suffix long-suffixopt unsigned-suffix long-long-suffix unsigned-suffix bit-precise-int-suffix long-suffix unsigned-suffixopt long-long-suffix unsigned-suffixopt bit-precise-int-suffix unsigned-suffixopt
bit-precise-int-suffix: one of wb WB
unsigned-suffix: one of uU
long-suffix: one of
lL
long-long-suffix: one of ll LL
Description */
// An integer constant begins with a digit, but has no period or exponent part. It may have a prefix that specifies its base and a suffix that specifies its type. An optional separating single quote character (’) in an integer or floating constant is called a digit separator. Digit separators are ignored when determining the value of the constant.
// EXAMPLE The following integer constants use digit separators; the comment associated with each constant shows the equivalent constant without digit separators.
// A decimal constant begins with a nonzero digit and consists of a sequence of decimal digits. An octal constant consists of the prefix 0 optionally followed by a sequence of the digits 0 through 7 only. A hexadecimal constant consists of the prefix 0x or 0X followed by a sequence of the decimal digits and the letters a (or A) through f (or F) with values 10 through 15 respectively. A binary constant consists of the prefix 0b or 0B followed by a sequence of the digits 0 or 1.
// Semantics
// The value of a decimal constant is computed base 10; that of an octal constant, base 8; that of a hexadecimal constant, base 16; that of a binary constant, base 2. The lexically first digit is the most significant.
// The type of an integer constant is the first of the corresponding list in which its value can be represented.
// 0b11’10’11’01 /* 0b11101101 */
// ’1’2 /* character constant ’1’ followed by integer constant 2, not the integer constant 12 */
// 11’22 /* 1122 */
// 0x’FFFF’FFFF /* invalid hexadecimal constant (’ cannot appear after 0x) */ 0x1’2’3’4AB’C’D /* 0x1234ABCD */
/* Suffix none
uorU lorL
Both u or U and lor L
ll or LL Both u or U
and ll or LL wb or WB
Both u or U and wb or WB
Octal, Hexadecimal or Binary Constant
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
unsigned int
int unsigned
Decimal Constant
int
long int
long long int
unsigned
unsigned
unsigned
long int
long long int
unsigned long
unsigned long
long long int
unsigned long
int long long
long int
int
long int
long int
long int
long long int
unsigned
long int
unsigned
long long int
unsigned long long int
unsigned long int
unsigned long long int
long long int
unsigned long long int
unsigned long long int
long int
_BitInt(N) where the width N
is the smallest N greater than */
// which can accommodate the value and the sign bit. unsigned _BitInt(N)wherethe unsigned _BitInt(N)wherethe _BitInt(N) where the width N is the smallest N greater than
// which can accommodate
// the value and the sign bit.
// width N is the smallest N greater than 0 which can accommodate the value. width N is the smallest N greater than 0 which can accommodate the value.
// If an integer constant cannot be represented by any type in its list, it may have an extended integer type, if the extended integer type can represent its value. If all the types in the list for the constant are signed, the extended integer type shall be signed. If all the types in the list for the constant are unsigned, the extended integer type shall be unsigned. If the list contains both signed and unsigned types, the extended integer type may be signed or unsigned. If an integer constant cannot be represented by any type in its list and has no extended integer type, then the integer constant has no type.
// EXAMPLE 1 The wb suffix results in an _BitInt that includes space for the sign bit even if the value of the constant is positive or was specified in hexadecimal or octal notation.
// Forward references: preprocessing numbers (6.4.8), numeric conversion functions (7.24.1).
// 6.4.4.2 Floating constants Syntax
// floating-constant:
// decimal-floating-constant hexadecimal-floating-constant
// decimal-floating-constant:
// fractional-constant exponent-partopt floating-suffixopt
// digit-sequence exponent-part floating-suffixopt
// hexadecimal-floating-constant:
// hexadecimal-prefix hexadecimal-fractional-constant
// -3wb /* Yields an _BitInt(3) that is then negated; two value bits, one sign bit */
// -0x3wb /* Yields an _BitInt(3) that is then negated; two value bits, one sign bit */
// 3wb /* Yields an _BitInt(3); two value bits, one sign bit */ 3uwb /* Yields an unsigned _BitInt(2) */
// -3uwb /* Yields an unsigned _BitInt(2) that is then negated, resulting in wraparound */ 1
/* fractional-constant:
binary-exponent-part floating-suffixopt hexadecimal-prefix hexadecimal-digit-sequence
binary-exponent-part floating-suffixopt
digit-sequenceopt . digit-sequence digit-sequence .
e signopt digit-sequence E signopt digit-sequence
+-
exponent-part:
sign: one of
digit-sequence:
digit
digit-sequence ’opt digit
hexadecimal-fractional-constant:
hexadecimal-digit-sequenceopt . hexadecimal-digit-sequence
hexadecimal-digit-sequence .
binary-exponent-part:
p signopt digit-sequence
P signopt digit-sequence floating-suffix: one of
f l F L df dd dl DF DD DL */
// Constraints
// A floating suffix df, dd, dl, DF, DD, or DL shall not be used in a hexadecimal floating constant. Description
// A floating constant has a significand part that may be followed by an exponent part and a suffix that specifies its type. The components of the significand part may include a digit sequence representing the whole-number part, followed by a period ( .), followed by a digit sequence representing the fraction part. Digit separators (6.4.4.1) are ignored when determining the value of the constant. The components of the exponent part are an e, E, p, or P followed by an exponent consisting of an optionally signed digit sequence. Either the whole-number part or the fraction part has to be present; for decimal floating constants, either the period or the exponent part has to be present.
// Semantics
// The significand part is interpreted as a (decimal or hexadecimal) rational number; the digit sequence in the exponent part is interpreted as a decimal integer. For decimal floating constants, the exponent indicates the power of 10 by which the significand part is to be scaled. For hexadecimal floating constants, the exponent indicates the power of 2 by which the significand part is to be scaled. For decimal floating constants, and also for hexadecimal floating constants when FLT_RADIX is not a power of 2, the result is either the nearest representable value, or the larger or smaller representable value immediately adjacent to the nearest representable value, chosen in an implementation-defined manner. For hexadecimal floating constants when FLT_RADIX is a power of 2, the result is correctly rounded.
// An unsuffixed floating constant has type double. If suffixed by a floating suffix it has a type according to the following table: Suffixes for floating constants
// The values of floating constants may be represented in greater range and precision than that required by the type (determined by the suffix); the types are not changed thereby. See 5.2.4.2.2 regarding evaluation formats. 82)
// 82)Hexadecimal floating constants can be used to obtain exact values in the semantic type that are independent of the
/* Suffix
Type
f, F
float
l, L
long double
df, DF
_Decimal32
dd, DD
_Decimal64
dl, DL
_Decimal128 */
// Floating constants of decimal floating type that have the same numerical value but different quantum exponents have distinguishable internal representations. The value shall be correctly rounded as specified in IEC 60559. The coefficient c and the quantum exponent q of a finite converted decimal floating-point number (see 5.2.4.2.3) are determined as follows:
// — q is set to the value of signopt digit-sequence in the exponent part, if any, or to 0, otherwise.
// — If there is a fractional constant, q is decreased by the number of digits to the right of the period and the period is removed to form a digit sequence.
// — c is set to the value of the digit sequence (after any period has been removed).
// — Rounding required because of insufficient precision or range in the type of the result will round c to the full precision available in the type, and will adjust q accordingly within the limits of the type, provided the rounding does not yield an infinity (in which case the result is an appropriately signed internal representation of infinity). If the full precision of the type would require q to be smaller than the minimum for the type, then q is pinned at the minimum and c is adjusted through the subnormal range accordingly, perhaps to zero.
// Floating constants are converted to internal format as if at translation-time. The conversion of a floating constant shall not raise an exceptional condition or a floating-point exception at execution time. All floating constants of the same source form 83) shall convert to the same internal format with the same value.
// EXAMPLE Following are floating constants of type _Decimal64 and their values as triples (s, c, q). Note that for _Decimal64, the precision (maximum coefficient length) is 16 and the quantum exponent range is −398 ≤ q ≤ 369.
/* 0.dd
0.00dd
123.dd
1.23E3dd
1.23E+3dd
12.3E+7dd
12.0dd
12.3dd
0.00123dd
1.23E-12dd
1234.5E-4dd
0E+7dd
12345678901234567890.dd
1234E-400dd
1234E-402dd
1000.dd
.0001dd
1000.e0dd
.0001e0dd
1000.0dd
0.0001dd
1000.00dd
00.0001dd
(+1, 0, 0)
(+1, 0, −2) (+1, 123, 0) (+1, 123, 1) (+1, 123, 1) (+1, 123, 6) (+1, 120, −1) (+1, 123, −1) (+1, 123, −5) (+1, 123, −14) (+1, 12345, −5) (+1, 0, 7)
assuming
default
rounding and
(+1, 1234567890123457, 4)
DEC_EVAL_METHOD is 0 or 184)
(+1, 12, −398) assuming default rounding and DEC_EVAL_METHOD is 0 or 1
(+1, 0, −398) assuming default rounding and DEC_EVAL_METHOD is 0 or 1
(+1, 1000, 0)
(+1, 1, −4)
(+1, 1000, 0)
(+1, 1, −4)
(+1, 10000, −1)
(+1, 1, −4)
(+1, 100000, −2)
(+1, 1, −4) */
// evaluation format. Casts produce values in the semantic type, though depend on the rounding mode and may raise the inexact floating-point exception.
// 83)1.23, 1.230, 123e-2, 123e-02, and 1.23L are all different source forms and thus need not convert to the same internal format and value.
// The implementation should produce a diagnostic message if a hexadecimal constant cannot be represented exactly in its evaluation format; the implementation should then proceed with the translation of the program.
// The translation-time conversion of floating constants should match the execution-time conversion of character strings by library functions, such as strtod, given matching inputs suitable for both conversions, the same result format, and default execution-time rounding. 85)
// NOTE 1 Floating constants do not include a sign and are negated by the unary − operator (6.5.3.3) which negates the rounded value of the constant. In contrast, the numeric conversion functions in the strto family (7.24.1.5, 7.24.1.6) may include the sign as part of the input value and convert and round the negated input; Annex F requires this behavior. Negating before rounding and negating after rounding might yield different results, depending on the rounding direction and whether the results are correctly rounded. For example, the results are the same when both are correctly rounded using rounding to nearest or rounding toward zero, but the results are different when they are inexact and correctly rounded using rounding toward positive infinity or rounding toward negative infinity.
// Conversions yielding exact results require no rounding, so are not affected by the order of negating and rounding. For types with radix 10, decimal floating constants expressed within the precision and range of the evaluation format convert exactly. For types whose radix is a power of 2, hexadecimal floating constants expressed within the precision and range of the evaluation format convert exactly.
// Forward references: preprocessing numbers (6.4.8), numeric conversion functions (7.24.1), the strto function family (7.24.1.5, 7.24.1.6).
// 6.4.4.3 Enumeration constants Syntax
// enumeration-constant: identifier
// Semantics
// An identifier declared as an enumeration constant for an enumeration without a fixed underlying type has either type int or the enumerated type, as defined in 6.7.2.2. An identifier declared as an enumeration constant for an enumeration with a fixed underlying type has the associated enumeration type.
// An enumeration constant may be used in an expression (or constant expression) wherever a value of an integer type may be used.
// Forward references: enumeration specifiers (6.7.2.2).
// 6.4.4.4 Character constants Syntax
// character-constant: encoding-prefixopt ’ c-char-sequence ’
// 84)That is, assuming the default translation rounding-direction mode is not changed by an FENV_DEC_ROUND pragma (7.6.3).
// 85)The specification for the library functions recommends more accurate conversion than required for floating constants (see 7.24.1.5).
// 001000.dd 001000.0dd 001000.00dd 00.00dd 00.dd .00dd 00.00e-5dd 00.e-5dd .00e-5dd
// Recommended practice
// (+1, 1000, 0) (+1, 10000, −1) (+1, 100000, −2) (+1, 0, −2) (+1, 0, 0) (+1, 0, −2) (+1, 0, −7) (+1, 0, −5) (+1, 0, −7)
// encoding-prefix: one of u8
// uUL
// c-char-sequence:
// c-char
// c-char:
// escape-sequence:
// c-char-sequence c-char
// any member of the source character set except
// the single-quote ’, backslash \, or new-line character
// escape-sequence
// simple-escape-sequence octal-escape-sequence hexadecimal-escape-sequence // universal-character-name
// simple-escape-sequence: one of \’ \" \? \\ \a \b \f \n \r \t \v
// octal-escape-sequence:
// \ octal-digit
// \ octal-digit octal-digit
// \ octal-digit octal-digit octal-digit
// hexadecimal-escape-sequence:
// \x hexadecimal-digit
// hexadecimal-escape-sequence hexadecimal-digit
// Description
// An integer character constant is a sequence of one or more multibyte characters enclosed in single- quotes, as in ’x’. A UTF-8 character constant is the same, except prefixed by u8. A wchar_t character constant is prefixed by the letter L. A UTF-16 character constant is prefixed by the letter u. A UTF-32 character constant is prefixed by the letter U. Collectively, wchar_t, UTF-16, and UTF-32 character constants are called wide character constants. With a few exceptions detailed later, the elements of the sequence are any members of the source character set; they are mapped in an implementation- defined manner to members of the execution character set.
// The single-quote ’, the double-quote ", the question-mark ?, the backslash \, and arbitrary integer values are representable according to the following table of escape sequences:
// single quote’
// double quote " question mark ? backslash \
// octal character hexadecimal character
// \’
// \"
// \?
// \\
// \octal digits
// \x hexadecimal digits
// The double-quote " and question-mark ? are representable either by themselves or by the escape sequences \" and \?, respectively, but the single-quote ’ and the backslash \ shall be represented, respectively, by the escape sequences \’ and \\.
// The octal digits that follow the backslash in an octal escape sequence are taken to be part of the construction of a single character for an integer character constant or of a single wide character for a wide character constant. The numerical value of the octal integer so formed specifies the value of the desired character or wide character.
// The hexadecimal digits that follow the backslash and the letter x in a hexadecimal escape sequence are taken to be part of the construction of a single character for an integer character constant or of a single wide character for a wide character constant. The numerical value of the hexadecimal integer so formed specifies the value of the desired character or wide character.
// Each octal or hexadecimal escape sequence is the longest sequence of characters that can constitute the escape sequence.
// In addition, characters not in the basic character set are representable by universal character names and certain non-graphic characters are representable by escape sequences consisting of the back- slash \ followed by a lowercase letter: \a, \b, \f, \n, \r, \t, and \v.86)
// Constraints
// The value of an octal or hexadecimal escape sequence shall be in the range of representable values for the corresponding type: Prefix Corresponding Type none unsigned char u8 char8_t L the unsigned type corresponding to wchar_t u char16_t U char32_t
// A UTF-8, UTF-16, or UTF-32 character constant shall not contain more than one character.87) The value shall be representable with a single UTF-8, UTF-16, or UTF-32 code unit, respectively.
// Semantics
// An integer character constant has type int. The value of an integer character constant containing a single character that maps to a single value in the literal encoding (6.2.9) is the numerical value of the representation of the mapped character in the literal encoding interpreted as an integer. The value of an integer character constant containing more than one character (e.g., ’ab’), or containing a character or escape sequence that does not map to a single value in the literal encoding, is implementation-defined. If an integer character constant contains a single character or escape sequence, its value is the one that results when an object with type char whose value is that of the single character or escape sequence is converted to type int.
// A UTF-8 character constant has type char8_t. If the UTF-8 character constant is not produced through a hexadecimal or octal escape sequence, the value of a UTF-8 character constant is equal to its ISO/IEC 10646 code point value, provided that the code point value can be encoded as a single UTF-8 code unit. Otherwise, the value of the UTF-8 character constant is the numeric value specified in the hexadecimal or octal escape sequence.
// A UTF-16 character constant has type char16_t which is an unsigned integer types defined in the <uchar.h> header. If the UTF-16 character constant is not produced through a hexadecimal or octal escape sequence, the value of a UTF-16 character constant is equal to its ISO/IEC 10646 code point value, provided that the code point value can be encoded as a single UTF-16 code unit. Otherwise, the value of the UTF-16 character constant is the numeric value specified in the hexadecimal or octal escape sequence.
// A UTF-32 character constant has type char32_t which is an unsigned integer types defined in the <uchar.h> header. If the UTF-32 character constant is not produced through a hexadecimal or octal escape sequence, the value of a UTF-32 character constant is equal to its ISO/IEC 10646 code point value, provided that the code point value can be encoded as a single UTF-32 code unit. Otherwise, the value of the UTF-32 character constant is the numeric value specified in the hexadecimal or octal escape sequence.
// 86)The semantics of these characters were discussed in 5.2.2. If any other character follows a backslash, the result is not a token and a diagnostic is required. See "future language directions" (6.11.4).
// 87)For example u8’ab’ violates this constraint.
// A wchar_t character constant prefixed by the letter L has type wchar_t, an integer type defined in the <stddef.h> header. The value of a wchar_t character constant containing a single multibyte character that maps to a single member of the extended execution character set is the wide character corresponding to that multibyte character in the implementation-defined wide literal encoding (6.2.9). The value of a wchar_t character constant containing more than one multibyte character or a single multibyte character that maps to multiple members of the extended execution character set, or containing a multibyte character or escape sequence not represented in the extended execution character set, is implementation-defined.
// EXAMPLE 1 The construction ’\0’ is commonly used to represent the null character.
// EXAMPLE 2 Consider implementations that use eight bits for objects that have type char. In an implementation in which type char has the same range of values as signed char, the integer character constant ’\xFF’ has the value −1; if type char has the same range of values as unsigned char, the character constant ’\xFF’ has the value +255.
// EXAMPLE 3 Even if eight bits are used for objects that have type char, the construction ’\x123’ specifies an integer character constant containing only one character, since a hexadecimal escape sequence is terminated only by a non-hexadecimal character. To specify an integer character constant containing the two characters whose values are ’\x12’ and ’3’, the construction ’\0223’ can be used, since an octal escape sequence is terminated after three octal digits. (The value of this two- character integer character constant is implementation-defined.)
// EXAMPLE 4 Even if 12 or more bits are used for objects that have type wchar_t, the construction L’\1234’ specifies the implementation-defined value that results from the combination of the values 0123 and ’4’.
// Forward references: common definitions <stddef.h> (7.21), the mbtowc function (7.24.7.2), Uni- code utilities <uchar.h> (7.30).
// 6.4.4.5 Predefined constants
// Syntax
// predefined-constant: false
// true nullptr
// Description
// Some keywords represent constants of a specific value and type.
// The keywords false and true are constants of type bool with a value of 0 for false and 1 for true88) .
// The keyword nullptr represents a null pointer constant. Details of its type are described in 7.21.2.
// 6.4.5 String literals
// Syntax
// string-literal: encoding-prefixopt " s-char-sequenceopt "
// 88)The constants false and true promote to type int, see 6.3.1.1. When used for arithmetic, in translation phase 4, they are signed values and the result of such arithmetic is consistent with the results of later translation phases.
// s-char-sequence:
// s-char
// s-char:
// Constraints
// s-char-sequence s-char
// any member of the source character set except the double-quote ", backslash \, or new-line character escape-sequence
// If a sequence of adjacent string literal tokens includes prefixed string literal tokens, the prefixed tokens shall all have the same prefix.
// Description
// A character string literal is a sequence of zero or more multibyte characters enclosed in double-quotes, as in "xyz". A UTF-8 string literal is the same, except prefixed by u8. A wchar_t string literal is the same, except prefixed by L. A UTF-16 string literal is the same, except prefixed by u. A UTF-32 string literal is the same, except prefixed by U. Collectively, wchar_t, UTF-16, and UTF-32 string literals are called wide string literals.
// The same considerations apply to each element of the sequence in a string literal as if it were in an integer character constant (for a character or UTF-8 string literal) or a wide character constant (for a wide string literal), except that the single-quote ’ is representable either by itself or by the escape sequence \’, but the double-quote " shall be represented by the escape sequence \".
// Semantics
// In translation phase 6, the multibyte character sequences specified by any sequence of adjacent character and identically-prefixed string literal tokens are concatenated into a single multibyte character sequence. If any of the tokens has an encoding prefix, the resulting multibyte character sequence is treated as having the same prefix; otherwise, it is treated as a character string literal.
// In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. // 89) The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence corresponding to the literal encoding (6.2.9). For UTF-8 string literals, the array elements have type char8_t, and are initialized with the characters of the multibyte character sequence, as encoded in UTF-8. For wide string literals prefixed by the letter L, the array elements have type wchar_t and are initialized with the sequence of wide characters corresponding to the wide literal encoding. For wide string literals prefixed by the letter u or U, the array elements have type char16_t or char32_t, respectively, and are initialized sequence of wide characters corresponding to UTF-16 and UTF-32 encoded text, respectively. The value of a string literal containing a multibyte character or escape sequence not represented in the execution character set is implementation-defined. Any hexadecimal escape sequence or octal escape sequence specified in a u8, u, or U string specifies a single char8_t, char16_t, or char32_t value and may result in the full character sequence not being valid UTF-8, UTF-16, or UTF-32.
// It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.
// EXAMPLE
// This pair of adjacent character string literals "\x12" "3"
// 89)A string literal might not be a string (see 7.1.1), because a null character can be embedded in it by a \0 escape sequence.
// produces a single character string literal containing the two characters whose values are ’\x12’ and ’3’, because escape sequences are converted into single members of the execution character set just prior to adjacent string literal concatenation.
// EXAMPLE 2 Each of the sequences of adjacent string literal tokens is equivalent to the string literal L"abc" Likewise, each of the sequences is equivalent to u"abc"
// Forward references: common definitions <stddef.h> (7.21), the mbstowcs function (7.24.8.1), Unicode utilities <uchar.h> (7.30).
// 6.4.6 Punctuators
// Syntax
// punctuator: one of[ ] ( ) { } . -> ++ -- & * + - ~ ! / % << >> < > <= >= == != ^ | && || ? : :: ; ... = *= /= %= += -= <<= >>= &= ^= |= , # ## <: :> <% %> %: %:%:
// Semantics
// A punctuator is a symbol that has independent syntactic and semantic significance. Depending on context, it may specify an operation to be performed (which in turn may yield a value or a function designator, produce a side effect, or some combination thereof) in which case it is known as an operator (other forms of operator also exist in some contexts). An operand is an entity on which an operator acts.
// "a" "b" L"c" "a" L"b" "c" L"a" "b" L"c" L"a" L"b" L"c" "a" "b" u"c" "a" u"b" "c" u"a" "b" u"c" u"a" u"b" u"c"
// In all aspects of the language, the six tokens90) <: :> <% %> %: %:%: behave, respectively, the same as the six tokens [ ] { } # ##
// except for their spelling.91)
// 90)These tokens are sometimes called "digraphs".
// 91)Thus [ and <: behave differently when "stringized" (see 6.10.4.2), but can otherwise be freely interchanged. 68 Language
// references: expressions (6.5), declarations (6.7), preprocessing directives (6.10), statements
// 6.4.7 Header names
// Syntax
// header-name:
// h-char-sequence:
// h-char
// h-char:
// h-char-sequence h-char
// any member of the source character set except the new-line character and >
// q-char-sequence:
// q-char
// q-char:
// Semantics
// q-char-sequence q-char
// any member of the source character set except the new-line character and " < h-char-sequence > " q-char-sequence "
// The sequences in both forms of header names are mapped in an implementation-defined manner to headers or external source file names as specified in 6.10.2.
// If the characters ’, \, ", //, or /* occur in the sequence between the < and > delimiters, the behavior is undefined. Similarly, if the characters ’, \, //, or /* occur in the sequence between the " delimiters, the behavior is undefined.92) Header name preprocessing tokens are recognized only within #include preprocessing directives and in implementation-defined locations within #pragma directives.93)
// EXAMPLE The following sequence of characters: forms the following sequence of preprocessing tokens (with each individual preprocessing token delimited by a { on the left and a } on the right).
// 92)Thus, sequences of characters that resemble escape sequences cause undefined behavior. 93)For an example of a header name preprocessing token used in a #pragma directive, see 6.10.10.
// 0x3<1/a.h>1e2
// p51.c:497:10: error: expected identifier or '(' before numeric constant
// 497 | 0x3<1/a.h>1e2
// | ^~~
#include <1/a.h>
#define const.member@$
// p51.c:499:9: warning: ISO C99 requires whitespace after the macro name
// 499 | #define const.member@$
// | ^~~~~
// p51.c:499:21: error: stray '@' in program
// 499 | #define const.member@$
// | ^
// {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// errpr: p51.c:500:27: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:30: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:33: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:36: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:39: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:42: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:45: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:48: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:54: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:55: error: stray '#' in program
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:57: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// | ^
// p51.c:500:67: error: expected identifier or '(' before '{' token
// 500 | {0x3}{<}{1}{/}{a}{.}{h}{>}{1e2} {#}{include} {<1/a.h>}
// |
// {#}{define} {const}{.}{member}{@}{$}
// p51.c:501:1: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
// p51.c:501:2: error: stray '#' in program
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:4: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:13: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
// error:p51.c:501:14: note: in expansion of macro 'const'
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^~~~~
//p51.c:501:20: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:23: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:31: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:32: error: stray '@' in program
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
//p51.c:501:34: error: expected identifier or '(' before '{' token
// 501 | {#}{define} {const}{.}{member}{@}{$}
// | ^
// Forward references: source file inclusion (6.10.2).
// 6.4.8 Preprocessing numbers
// Syntax
// pp-number:
// Description
// digit
// . digit
// pp-number identifier-continue pp-number ’ digit pp-number ’ nondigit pp-number e sign pp-number E sign pp-number p sign pp-number P sign pp-number .
// A preprocessing number begins with a digit optionally preceded by a period (.) and may be followed by valid identifier characters and the character sequences e+, e-, E+, E-, p+, p-, P+, or P-.
// Preprocessing number tokens lexically include all floating and integer constant tokens.
// Semantics
// A preprocessing number does not have type or a value; it acquires both after a successful conversion (as part of translation phase 7) to a floating constant token or an integer constant token.
// 6.4.9 Comments
// Except within a character constant, a string literal, or a comment, the characters /* introduce a comment. The contents of such a comment are examined only to identify multibyte characters and to find the characters */ that terminate it.94)
// Except within a character constant, a string literal, or a comment, the characters // introduce a comment that includes all multibyte characters up to, but not including, the next new-line character. The contents of such a comment are examined only to identify multibyte characters and to find the terminating new-line character.
// EXAMPLE
// "a//b"
// error:p51.c:518:2: error: expected identifier or '(' before string constant
// 518 | "a//b"
// | ^~~~~~
// #include "//e"
// error: p51.c:518:10: fatal error: //e: No such file or directory
// 518 | #include "//e"
// | ^~~~~
// */
void f1(void) {
int f;
int g = 1;
int h = 2;
f = g/**//h;
}
//\
void i() {}
void j() {}
i();
/\
/ j();
#define glue(x,y) x##y glue(/,/) k();
void f2(void) {
/*//*/ l();
int m;
int n=3;
int p=4;
m = n//**/o
+ p;
}
// four-character string literal // undefined behavior
// comment, not syntax error
// equivalent to f = g / h;
// part of a two-line comment
// part of a two-line comment
// syntax error, not comment // equivalent to l();
// equivalent to m = n + p;
int main() {
// From here, the codes are added by Dr. Kiyosi Ogawa
#ifdef __has_include
PR("include", s);
#endif
int x = 1;
int y = 2;
// x = x+++++y;
x = x++ + ++y;
PR(x,d);
// To here, the codes are added by Dr. Kiyosi Ogawa
printf("%s\n", n3054);
return EXIT_SUCCESS;
}
途中警告等
$ clang p51e.c -std=11 -o p51el -I. -Wall
p51e.c:505:14: warning: ISO C99 requires whitespace after the macro name [-Wc99-extensions]
#define const.member@$
^
p51e.c:611:3: warning: multi-line // comment [-Wcomment]
//\
^
p51e.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
int f;
^
p51e.c:614:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
i();
^
p51e.c:619:8: warning: implicit declaration of function 'l' is invalid in C99 [-Wimplicit-function-declaration]
/*//*/ l();
^
p51e.c:620:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
int m;
^
p51e.c:641:10: warning: multiple unsequenced modifications to 'x' [-Wunsequenced]
x = x++ + ++y;
~ ^
7 warnings generated.
/usr/bin/ld: /tmp/p51e-a8d253.o: in function `f2':
p51e.c:(.text+0x5b): undefined reference to `l'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
$ clang p51e.c -std=17 -o p51el -I. -Wall
p51e.c:505:14: warning: ISO C99 requires whitespace after the macro name [-Wc99-extensions]
#define const.member@$
^
p51e.c:611:3: warning: multi-line // comment [-Wcomment]
//\
^
p51e.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
int f;
^
p51e.c:614:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
i();
^
p51e.c:619:8: warning: implicit declaration of function 'l' is invalid in C99 [-Wimplicit-function-declaration]
/*//*/ l();
^
p51e.c:620:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
int m;
^
p51e.c:641:10: warning: multiple unsequenced modifications to 'x' [-Wunsequenced]
x = x++ + ++y;
~ ^
7 warnings generated.
/usr/bin/ld: /tmp/p51e-27f14f.o: in function `f2':
p51e.c:(.text+0x5b): undefined reference to `l'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
$ clang p51e.c -std=2x -o p51el -I. -Wall
p51e.c:505:14: warning: ISO C99 requires whitespace after the macro name [-Wc99-extensions]
#define const.member@$
^
p51e.c:611:3: warning: multi-line // comment [-Wcomment]
//\
^
p51e.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
int f;
^
p51e.c:614:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
i();
^
p51e.c:619:8: warning: implicit declaration of function 'l' is invalid in C99 [-Wimplicit-function-declaration]
/*//*/ l();
^
p51e.c:620:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
int m;
^
p51e.c:641:10: warning: multiple unsequenced modifications to 'x' [-Wunsequenced]
x = x++ + ++y;
~ ^
7 warnings generated.
/usr/bin/ld: /tmp/p51e-aad34c.o: in function `f2':
p51e.c:(.text+0x5b): undefined reference to `l'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
$ gcc p51e.c -std=11 -o p51eg -I. -Wall
p51e.c:410:1: warning: multi-line comment [-Wcomment]
410 | // double quote " question mark ? backslash \
| ^
p51e.c:415:1: warning: multi-line comment [-Wcomment]
415 | // \\
| ^
p51e.c:505:9: warning: ISO C99 requires whitespace after the macro name
505 | #define const.member@$
| ^~~~~
p51e.c: In function 'f1':
p51e.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
606 | int f;
| ^
p51e.c: At top level:
p51e.c:611:1: warning: multi-line comment [-Wcomment]
611 | //\
| ^
p51e.c:614:1: warning: data definition has no type or storage class
614 | i();
| ^
p51e.c:614:1: warning: type defaults to 'int' in declaration of 'i' [-Wimplicit-int]
p51e.c:615:1: warning: multi-line comment [-Wcomment]
615 | /\
| ^
p51e.c: In function 'f2':
p51e.c:619:8: warning: implicit declaration of function 'l' [-Wimplicit-function-declaration]
619 | /*//*/ l();
| ^
p51e.c:620:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
620 | int m;
| ^
p51e.c: In function 'main':
p51e.c:641:7: warning: operation on 'x' may be undefined [-Wsequence-point]
641 | x = x++ + ++y;
| ~~^~~~~~~~~~~
/usr/bin/ld: /tmp/ccuzKKD2.o: in function `f2':
p51e.c:(.text+0x45): undefined reference to `l'
collect2: error: ld returned 1 exit status
$ gcc p51e.c -std=c17 -o p51eg -I. -Wall
p51e.c:410:1: warning: multi-line comment [-Wcomment]
410 | // double quote " question mark ? backslash \
| ^
p51e.c:415:1: warning: multi-line comment [-Wcomment]
415 | // \\
| ^
p51e.c:505:9: warning: ISO C99 requires whitespace after the macro name
505 | #define const.member@$
| ^~~~~
p51e.c: In function 'f1':
p51e.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
606 | int f;
| ^
p51e.c: At top level:
p51e.c:611:1: warning: multi-line comment [-Wcomment]
611 | //\
| ^
p51e.c:614:1: warning: data definition has no type or storage class
614 | i();
| ^
p51e.c:614:1: warning: type defaults to 'int' in declaration of 'i' [-Wimplicit-int]
p51e.c:615:1: warning: multi-line comment [-Wcomment]
615 | /\
| ^
p51e.c: In function 'f2':
p51e.c:619:8: warning: implicit declaration of function 'l' [-Wimplicit-function-declaration]
619 | /*//*/ l();
| ^
p51e.c:620:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
620 | int m;
| ^
p51e.c: In function 'main':
p51e.c:641:7: warning: operation on 'x' may be undefined [-Wsequence-point]
641 | x = x++ + ++y;
| ~~^~~~~~~~~~~
/usr/bin/ld: /tmp/ccCIs5Wq.o: in function `f2':
p51e.c:(.text+0x45): undefined reference to `l'
collect2: error: ld returned 1 exit status
$ gcc p51e.c -std=c2x -o p51eg -I. -Wall
p51e.c:410:1: warning: multi-line comment [-Wcomment]
410 | // double quote " question mark ? backslash \
| ^
p51e.c:415:1: warning: multi-line comment [-Wcomment]
415 | // \\
| ^
p51e.c:505:9: warning: ISO C99 requires whitespace after the macro name
505 | #define const.member@$
| ^~~~~
p51e.c: In function 'f1':
p51e.c:606:5: warning: variable 'f' set but not used [-Wunused-but-set-variable]
606 | int f;
| ^
p51e.c: At top level:
p51e.c:611:1: warning: multi-line comment [-Wcomment]
611 | //\
| ^
p51e.c:614:1: warning: data definition has no type or storage class
614 | i();
| ^
p51e.c:614:1: warning: type defaults to 'int' in declaration of 'i' [-Wimplicit-int]
p51e.c:615:1: warning: multi-line comment [-Wcomment]
615 | /\
| ^
p51e.c: In function 'f2':
p51e.c:619:8: warning: implicit declaration of function 'l' [-Wimplicit-function-declaration]
619 | /*//*/ l();
| ^
p51e.c:620:5: warning: variable 'm' set but not used [-Wunused-but-set-variable]
620 | int m;
| ^
p51e.c: In function 'main':
p51e.c:641:7: warning: operation on 'x' may be undefined [-Wsequence-point]
641 | x = x++ + ++y;
| ~~^~~~~~~~~~~
/usr/bin/ld: /tmp/ccCHMhiO.o: in function `f2':
p51e.c:(.text+0x45): undefined reference to `l'
collect2: error: ld returned 1 exit status
検討事項(agenda)
"#include"があると __has_includeが有効になり、#ifdef __has_include の条件を満たして "include" = includeを出力している。
x = x++ + ++y;の警告はClangとgccで違い、-Wで警告抑制の文字列も違うことが分かった。
応用例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リンク切れ 変更, C言語教育はCコンパイラの写経で URL追記 20221029
最後までおよみいただきありがとうございました。
いいね 💚、フォローをお願いします。
Thank you very much for reading to the last sentence.
Please press the like icon 💚 and follow me for your happy life.