LoginSignup
0
0

More than 1 year has passed since last update.

6.10 Preprocessing directives, CN3054:2022 (12) p163.c

Posted at

はじめに(Introduction)

N3054 Working Draft, Standard for Programming Language C

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

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

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

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

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

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

背景(back ground)

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

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

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

作業方針(sequence)

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

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

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

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

読書感想文

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

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

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

個人開発

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

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

編纂器(Compiler)

clang --version

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

gcc --version

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

6.10 Preprocessing directives, CN3054:2022 (12) p163.c

算譜(source code)

p163.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.10 Preprocessing directives, CN3054:2022 (12) p163.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.10 Preprocessing directives
Syntax
1 preprocessing-file:
groupopt
group: group-part:
if-section: if-group:
elif-groups: elif-group:
else-group: endif-line: control-line:
group-part
group group-part
if-section control-line text-line
# non-directive
if-group elif-groupsopt else-groupopt endif-line
# if constant-expression new-line groupopt # ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
elif-group
elif-groups elif-group
# elif constant-expression new-line groupopt # elifdef identifier new-line groupopt
# elifndef identifier new-line groupopt
# else new-line groupopt # endif new-line
# include pp-tokens new-line
# embed pp-tokens new-line
# define identifier replacement-list new-line
# define identifier lparen identifier-listopt ) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list , ... ) replacement-list new-line # undef identifier new-line
# line pp-tokens new-line
# error pp-tokensopt new-line
# warning pp-tokensopt new-line
# pragma pp-tokensopt new-line
# new-line
pp-tokensopt new-line
pp-tokens new-line
a ( character not immediately preceded by white space
pp-tokensopt
text-line:
non-directive:
lparen:
replacement-list:
pp-tokens:
new-line:
identifier-list:
pp-parameter:
preprocessing-token
pp-tokens preprocessing-token
the new-line character
identifier
identifier-list , identifier
pp-parameter-name pp-parameter-clauseopt
pp-parameter-name: pp-standard-parameter
pp-prefixed-parameter
pp-standard-parameter: identifier
pp-prefixed-parameter:
identifier :: identifier
pp-parameter-clause:
( pp-balanced-token-sequenceopt )
pp-balanced-token-sequence: pp-balanced-token
pp-balanced-token-sequence pp-balanced-token pp-balanced-token:
( pp-balanced-token-sequenceopt ) [ pp-balanced-token-sequenceopt ] { pp-balanced-token-sequenceopt }
any pp-token other than a parenthesis, a bracket, or a brace
embed-parameter-sequence: pp-parameter
embed-parameter-sequence pp-parameter
Description
2 A preprocessing directive consists of a sequence of preprocessing tokens that satisfies the following constraints: The first token in the sequence is a # preprocessing token that (at the start of translation phase 4) is either the first character in the source file (optionally after white space containing no new-line characters) or that follows white space containing at least one new-line character. The last token in the sequence is the first new-line character that follows the first token in the sequence. 207)
207)Thus, preprocessing directives are commonly called "lines". These "lines" have no other syntactic significance, as all white space is equivalent except in certain situations during preprocessing (see the # character string literal creation operator
A new-line character ends the preprocessing directive even if it occurs within what would otherwise
be an invocation of a function-like macro.
3 A text line shall not begin with a # preprocessing token. A non-directive shall not begin with any of the directive names appearing in the syntax.
4 Some preprocessing directives take additional information using preprocessor parameters. A preprocessing parameter (pp-parameter) shall be either a preprocessor prefixed parameter (identified by a pp-prefixed-parameter, for implementation-defined preprocessor parameters) or a preprocessor standard parameter (identified with a pp-standard-parameter, for pp-parameters specified by this document).
5 In all aspects, a preprocessor standard parameter specified by this document as an identifier pp_param and an identifier of the form __pp_param__ shall behave the same when used as a preprocessor parameter, except for the spelling.
6 EXAMPLE 1 Thus, the preprocessor parameters on the two binary resource inclusion directives (6.10.3.1):
behave the same, and can be freely interchanged. Implementations are encouraged to behave similarly for preprocessor parameters (including preprocessor prefixed parameters) they provide.
7 When in a group that is skipped (6.10.1), the directive syntax is relaxed to allow any sequence of preprocessing tokens to occur between the directive name and the following new-line character.
Constraints
8 The only white-space characters that shall appear between preprocessing tokens within a prepro- cessing directive (from just after the introducing # preprocessing token through just before the terminating new-line character) are space and horizontal-tab (including spaces that have replaced comments or possibly other white-space characters in translation phase 3).
9 A preprocessor parameter shall be either a preprocessor standard parameter, or an implementation- defined preprocessor prefixed parameter208).
Semantics
10 The implementation can process and skip sections of source files conditionally, include other source files, and replace macros. These capabilities are called preprocessing, because conceptually they occur before translation of the resulting translation unit.
11 The preprocessing tokens within a preprocessing directive are not subject to macro expansion unless otherwise stated.
12 EXAMPLE In:
                    13
1
the sequence of preprocessing tokens on the second line is not a preprocessing directive, because it does not begin with a # at the start of translation phase 4, even though it will do so after the macro EMPTY has been replaced.
The execution of a non-directive preprocessing directive results in undefined behavior.
6.10.1 Conditional inclusion Syntax
defined-macro-expression:
defined identifier
in 6.10.4.2, for example).
208)An unrecognized preprocessor prefixed parameter is a constraint violation, except within has_embed expressions (6.10.1).
#embed "boop.h" limit(5) #embed "boop.h" __limit__(5)
      #define EMPTY
EMPTY # include <file.h>
defined ( identifier ) h-preprocessing-token:
any preprocessing-token other than > h-preprocessing-token
h-pp-tokens h-preprocessing-token
string-literal
< h-pp-tokens > has-include-expression:
__has_include ( header-name )
__has_include ( header-name-tokens ) has-embed-expression:
__has_embed ( header-name embed-parameter-sequenceopt )
__has_embed ( header-name-tokens pp-balanced-token-sequenceopt ) has-c-attribute-express:
__has_c_attribute ( pp-tokens )
2 The #if and #elif directives are collectively known as the conditional expression inclusion prepro- cessing directives. The conditional expression inclusion preprocessing directives, #ifdef, #ifndef, #elifdef, and #elifndef directives are collectively known as the conditional inclusion preprocessing directives.
Constraints
3 The expression that controls conditional inclusion shall be an integer constant expression except that: identifiers (including those lexically identical to keywords) are interpreted as described below209) and it may contain zero or more defined macro expressions, has_include expressions, has_embed expressions, and/or has_c_attribute expressions as unary operator expressions.
4 A defined macro expression evaluates to 1 if the identifier is currently defined as a macro name (that is, if it is predefined or if it has been the subject of a #define preprocessing directive without an intervening #undef directive with the same subject identifier), 0 if it is not.
5 The second form of the has_include expression and has_embed expression is considered only if the first form does not match, in which case the preprocessing tokens are processed just as in normal text.
6 The header or source file identified by the parenthesized preprocessing token sequence in each contained has_include expression is searched for as if that preprocessing token were the pp-tokens in a #include directive, except that no further macro expansion is performed. Such a directive shall satisfy the syntactic requirements of a #include directive. The has_include expression evaluates to 1 if the search for the source file succeeds, and to 0 if the search fails.
7 The resource (6.10.3.1) identified by the header-name preprocessing token sequence in each contained has_embed expression is searched for as if those preprocessing token were the pp-tokens in a #embed directive, except that no further macro expansion is performed. Such a directive shall satisfy the syntactic requirements of a #embed directive. The has_embed expression evaluates to:
 0 if the search fails or if any of the embed parameters in the embed parameter sequence specified are not supported by the implementation for the #embed directive; or,
 1 if the search for the resource succeeds and all embed parameters in the embed parameter sequence specified are supported by the implementation for the #embed directive and the resource is not empty; or,
209)Because the controlling constant expression is evaluated during translation phase 4, all identifiers either are or are not macro names  there simply are no keywords, enumeration constants, etc.
h-pp-tokens: header-name-tokens:
 2 if the search for the resource succeeds and all embed parameters in the embed parameter sequence specified are supported by the implementation for the #embed directive and the resource is empty.
8 NOTE 1 Unrecognized preprocessor prefixed parameters in has_embed expressions is not a constraint violation and instead causes the expression to be evaluate to 0, as specified above.
9 Each has_c_attribute expression is replaced by a nonzero pp-number matching the form of an integer constant if the implementation supports an attribute with the name specified by interpreting the pp-tokens as an attribute token, and by 0 otherwise. The pp-tokens shall match the form of an attribute token.
10 Each preprocessing token that remains (in the list of preprocessing tokens that will become the controlling expression) after all macro replacements have occurred shall be in the lexical form of a token (6.4).
Semantics
11 The #ifdef, #ifndef, #elifdef, and #elifndef directives, and the defined conditional inclusion operator, shall treat __has_include, __has_embed and __has_c_attribute as if they were the name of defined macros. The identifiers __has_include, __has_embed, and __has_c_attribute shall not appear in any context not mentioned in this subclause.
12 Preprocessing directives of the forms
# if constant-expression new-line groupopt
# elif constant-expression new-line groupopt
check whether the controlling constant expression evaluates to nonzero.
13 Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the control- ling constant expression are replaced (except for those macro names modified by the defined unary operator), just as in normal text. If the token defined is generated as a result of this replacement process or use of the defined unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined. After all replacements due to macro expansion and evaluations of defined macro expressions, has_include expressions, has_embed expressions, and has_c_attribute expressions have been performed, all remaining identifiers other than true (including those lexically identical to keywords such as false) are replaced with the pp-number 0, true is replaced with pp-number 1, and then each preprocessing token is converted into a token. The resulting tokens compose the controlling constant expression which is evaluated according to the rules of 6.6. For the purposes of this token conversion and evaluation, all signed integer types and all unsigned integer types act as if they have the same representation as, respectively, the types intmax_t and uintmax_t defined in the header <stdint.h>. 210) This includes interpreting character constants, which may involve converting escape sequences into execution character set members. Whether the numeric value for these character constants matches the value obtained when an identical character constant occurs in an expression (other than within a #if or #elif directive) is implementation-defined211).
Also, whether a single-character character constant may have a negative value is implementation- defined.
14 Preprocessing directives of the forms
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
210)Thus, on an implementation where INT_MAX is 0x7FFF and UINT_MAX is 0xFFFF, the constant 0x8000 is signed and positive within a #if expression even though it would be unsigned in translation phase 7.
211)Thus, the constant expression in the following #if directive and if statement is not guaranteed to evaluate to the same value in these two contexts.
          #if ’z’ - ’a’ == 25 if (’z’ - ’a’ == 25)
# elifdef identifier new-line groupopt
# elifndef identifier new-line groupopt
check whether the identifier is or is not currently defined as a macro name. Their conditions are equivalent to #if defined identifier, #if !defined identifier, #elif defined identifier, and #elif !definedidentifierrespectively.
15 Each directives condition is checked in order. If it evaluates to false (zero), the group that it controls is skipped: directives are processed only through the name that determines the directive to keep track of the level of nested conditionals; the rest of the directives preprocessing tokens are ignored, as are the other preprocessing tokens in the group. Only the first group whose control condition evaluates to true (nonzero) is processed; any following groups are skipped and their controlling directives are processed as if they were in a group that is skipped. If none of the conditions evaluates to true, and there is a #else directive, the group controlled by the #else is processed; lacking a #else directive, all the groups until the #endif are skipped. 212)
16 EXAMPLE This demonstrates a way to include a header file only if it is available.
    #if __has_include(<optional.h>)
# include <optional.h>
# define have_optional 1
#elif __has_include(<experimental/optional.h>)
# include <experimental/optional.h>
# define have_optional 1
# define have_experimental_optional 1 #endif
#ifndef have_optional
# define have_optional 0 #endif
                                      17 EXAMPLE
        /* Fallback for compilers not yet implementing this feature. */
#ifndef __has_c_attribute #define __has_c_attribute(x) 0 #endif /* __has_c_attribute */
#if __has_c_attribute(fallthrough)
/* Standard attribute is available, use it. */ #define FALLTHROUGH [[fallthrough]]
#elif __has_c_attribute(vendor::fallthrough) /* Vendor attribute is available, use it. */ #define FALLTHROUGH [[vendor::fallthrough]] #else
/* Fallback implementation. */
#define FALLTHROUGH
#endif
                                              18 EXAMPLE
212)As indicated by the syntax, no preprocessing tokens are allowed to follow a #else or #endif directive before the terminating new-line character. However, comments can appear anywhere in a source file, including within a preprocessing directive.
    #ifdef __STDC__
#define TITLE "ISO C Compilation" #elifndef __cplusplus
#define TITLE "Non-ISO C Compilation" #else
/* C++ */
#define TITLE "C++ Compilation" #endif
EXAMPLE 1 A combination of __FILE__ (6.10.9.1) and __has_embed could be used to check for
support of specific implementation extensions for the #embed (6.10.3.1) directives parameters.
20 EXAMPLE 2 The snippet below uses __has_embed to check for support of a specific implementation-defined embed parameter, and otherwise uses standard behavior to produce the same effect.
void parse_into_s(short* ptr, unsigned char* ptr_bytes, unsigned long long size);
int main () {
#if __has_embed ("bits.bin" ds9000::element_type(short))
/* Implementation extension: create short integers from the */ /* translation environment resource into */
/* a sequence of integer constants */
short meow[] = {
#embed "bits.bin" ds9000::element_type(short) };
#elif __has_embed ("bits.bin")
/* no support for implementation-specific */ /* ds9000::element_type(short) parameter */ const unsigned char meow_bytes[] = {
#embed "bits.bin" };
short meow[sizeof(meow_bytes) / sizeof(short)] = {}; /* parse meow_bytes into short values by-hand! */ parse_into_s(meow, meow_bytes, sizeof(meow_bytes));
#else
#error "cannot find bits.bin resource" #endif
return (int)(meow[0] + meow[(sizeof(meow) / sizeof(*meow)) - 1]);
}
21 EXAMPLE 3 If the search for the resource is successful, this resource is always considered empty due to the limit(0) embed parameter, including in __has_embed expressions.
    #if __has_embed(__FILE__ ext::token(0xB055))
#define DESCRIPTION "Supports extended token embed"
#else
#define DESCRIPTION "Does not support extended token embed" #endif
                                           int main () {
#if __has_embed(<infinite-resource> limit(0)) == 2
// if <infinite-resource> exists, this // token sequence is always taken. return 0;
#else
// the ’infinite-resource’ resource does not exist #error "The resource does not exist"
#endif }
                                        Forward references: macro replacement (6.10.4), source file inclusion (6.10.2), mandatory macros (6.10.9.1), largest integer types (7.22.1.5).
6.10.2 Source file inclusion
Constraints
1 A #include directive shall identify a header or source file that can be processed by the implementa- tion.
Semantics
2 A preprocessing directive of the form
# include < h-char-sequence > new-line
searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.
3 A preprocessing directive of the form
# include " q-char-sequence " new-line
causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read
# include < h-char-sequence > new-line
with the identical contained sequence (including > characters, if any) from the original directive.
4 A preprocessing directive of the form
# include pp-tokens new-line
(that does not match one of the two previous forms) is permitted. The preprocessing tokens after include in the directive are processed just as in normal text. (Each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens.) The directive resulting after all replacements shall match one of the two previous forms.213) The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single header name preprocessing token is implementation-defined.
5 The implementation shall provide unique mappings for sequences consisting of one or more nondig- its or digits (6.4.2.1) followed by a period (.) and a single nondigit. The first character shall not be a digit. The implementation may ignore distinctions of alphabetical case and restrict the mapping to eight significant characters before the period.
6 A #include preprocessing directive may appear in a source file that has been read because of a #include directive in another file, up to an implementation-defined nesting limit (see 5.2.4.1).
7 EXAMPLE 1 The most common uses of #include preprocessing directives are as in the following:
8 EXAMPLE 2 This illustrates macro-replaced #include directives:
Forward references: macro replacement (6.10.4).
213)Note that adjacent string literals are not concatenated into a single string literal (see the translation phases in 5.1.1.2);
thus, an expansion that results in two string literals is an invalid directive.
        #include <stdio.h> #include "myprog.h"
               #if VERSION == 1
#define INCFILE "vers1.h"
#elif VERSION == 2
#define INCFILE "vers2.h"
#else
#define INCFILE "versN.h"
#endif
#include INCFILE
// and so on
6.10.3 6.10.3.1 Description
Binary resource inclusion #embed preprocessing directive
1 A resource is a source of data accessible from the translation environment. An embed parameter is a single preprocessor parameter in the embed parameter sequence. It has an implementation resource width, which is the implementation-defined size in bits of the located resource. It also has a resource width, which is either:
 the number of bits as computed from the optionally-provided limit embed parameter (6.10.3.2), if present; or,
 the implementation resource width.
2 An embed parameter sequence is a whitespace-delimited list of preprocessor parameters which may
modify the result of the replacement for the #embed preprocessing directive. Constraints
3 An #embed directive shall identify a resource that can be processed by the implementation as a binary data sequence given the provided embed parameters.
4 Embed parameters not specified in this document shall be implementation-defined. Implementation- defined embed parameters may change the below-defined semantics of the directive; otherwise, #embed directives which do not contain implementation-defined embed parameters shall behave as described in this document.
5 A resource is considered empty when its resource width is zero.
6 Let embed element width be either:
 an integer constant expression greater than zero determined by an implementation-defined embed parameter; or,
 CHAR_BIT (5.2.4.2.1).
The result of (resource width) % (embed element width) shall be zero214).
Semantics
7 The expansion of a #embed directive is a token sequence formed from the list of integer constant expressions described below. The group of tokens for each integer constant expression in the list is separated in the token sequence from the group of tokens for the previous integer constant expression in the list by a comma. The sequence neither begins nor ends in a comma. If the list of integer constant expressions is empty, the token sequence is empty. The directive is replaced by its expansion and, with the presence of certain embed parameters, additional or replacement token sequences.
8 A preprocessing directive of the form
# embed < h-char-sequence > embed-parameter-sequenceopt new-line
searches a sequence of implementation-defined places for a resource identified uniquely by the spec- ified sequence between the < and >. The search for the named resource is done in an implementation- defined manner.
9 A preprocessing directive of the form
# embed " q-char-sequence " embed-parameter-sequenceopt new-line
searches a sequence of implementation-defined places for a resource identified uniquely by the specified sequence between the " delimiters. The search for the named resource is done in an
214)This constraint helps ensure data is neither filled with padding values nor truncated in a given environment, and helps ensure the data is portable with respect to usages of memcpy (7.26.2.1) with character type arrays initialized from the data.
implementation-defined manner. If this search is not supported, or if the search fails, the directive is
reprocessed as if it read
# embed < h-char-sequence > embed-parameter-sequenceopt new-line
with the identical contained q-char-sequence (including > characters, if any) from the original directive.
10 Either form of the #embed directive specified previously behave as specified below. The values of the integer constant expressions in the expanded sequence are determined by an implementation- defined mapping of the resource’s data. Each integer constant expression’s value is in the range from 0 to (2embed element width) − 1, inclusive.215) If:
— the list of integer constant expressions is used to initialize an array of a type compatible with unsigned char,orcompatiblewithcharifcharcannotholdnegativevalues;and,
— the embed element width is equal to CHAR_BIT (5.2.4.2.1),
then the contents of the initialized elements of the array are as-if the resource’s binary data is fread
(7.23.8.1) into the array at translation time.
11 A preprocessing directive of the form
# embed pp-tokens new-line
(that does not match one of the two previous forms) is permitted. The preprocessing tokens after embed in the directive are processed just as in normal text. (Each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens.) The directive resulting after all replacements shall match one of the two previous forms216). The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single resource name preprocessing token is implementation-defined.
12 An embed parameter with a preprocessor parameter token that is one of the following is a standard embed parameter:
limit prefix suffix if_empty
The significance of these standard embed parameters is specified below.
Recommended practice
13 The #embed directive is meant to translate binary data in a resource to a sequence of integer constant expressions in a way that preserves the value of the resources bit stream where possible.
14 A mechanism similar to, but distinct from, the implementation-defined search paths used for source file inclusion (6.10.2) is encouraged.
15 Implementations should take into account translation-time bit and byte orders as well as execution time bit and byte orders to more appropriately represent the resources binary data from the directive. This maximizes the chance that, if the resource referenced at translation time through the #embed directive is the same one accessed through execution-time means, the data that is e.g. fread or similar into contiguous storage will compare bit-for-bit equal to an array of character type initialized from an #embed directives expanded contents.
16 EXAMPLE 1 Placing a small image resource.
215)For example, an embed element width of 8 will yield a range of values from 0 to 255, inclusive.
216)Note that adjacent string literals are not concatenated into a single string literal (see the translation phases in 5.1.1.2); thus, an expansion that results in two string literals is an invalid directive.
        #include <stddef.h>
void have_you_any_wool(const unsigned char*, size_t);
     int main (int, char*[]) {
static const unsigned char baa_baa[] = {
#embed "black_sheep.ico" };
                have_you_any_wool(baa_baa, sizeof(baa_baa)); return 0;
                }
    17 EXAMPLE 2 This snippet:
may violate the constraint that (resource width) % (embed element width) must be 0. The 8 bits might not be evenly divisible by the embed element width (e.g., on a system where CHAR_BIT is 16). Issuing a diagnostic in this case may aid in portability by calling attention to potentially incompatible expectations between implementations and their resources.
18 EXAMPLE 3 Initialization of non-arrays.
int main () {
/* Braces may be kept or elided as per normal initialization rules */ int i = {
#embed "i.dat"
}; /* i value is [0, 2^(embed element width)) first entry */ int i2 =
#embed "i.dat"
; /* valid if i.dat produces 1 value,
                        i2 value is [0, 2^(embed element width)) */
struct s {
double a, b, c;
struct { double e, f, g; }; double h, i, j;
};
struct s x = {
/* initializes each element in order according to initialization rules with comma-separated list of integer constant expressions inside of braces */
#embed "s.dat" };
return 0;
}
Non-array types can still be initialized since the directive produces a comma-delimited list of integer constant expressions, a single integer constant expression, or nothing.
19 EXAMPLE 4 Equivalency of bit sequence and bit order between a translation-time read and an execution-time read of the same resource/file.
         int main (int, char*[]) {
static const unsigned char coefficients[] = {
#embed "only_8_bits.bin" // potential constraint violation };
                    }
return 0;
                          #include <string.h> #include <stddef.h> #include <stdio.h>
int main(void) {
static const unsigned char embed_data[] = { #embed <data.dat>
};
const size_t f_size = sizeof(embed_data); unsigned char f_data[f_size];
FILE* f_source = fopen("data.dat", "rb"); if (f_source == NULL);
return 1;
char* f_ptr = (char*)&f_data[0];
if (fread(f_ptr, 1, f_size, f_source) != f_size) {
fclose(f_source); return 1;
} fclose(f_source);
int is_same = memcmp(&embed_data[0], f_ptr, f_size);
// if both operations refers to the same resource/file at
// execution time and translation time, "is_same" should be 0 return is_same == 0 ? 0 : 1;
   }
  limit parameter Constraints
1 The limit standard embed parameter may appear zero times or one time in the embed parameter sequence. Its preprocessor argument clause shall be present and have the form:
( constant-expression )
and shall be an integer constant expression. The integer constant expression shall not evaluate to a
value less than 0.
2 The token defined shall not appear within the constant expression.
Semantics
3 The embed parameter with a preprocessor parameter token limit denotes a balanced preprocessing token sequence that will be used to compute the resource width. Independently of any macro replacement done previously (e.g. when matching the form of #embed), the constant expression is evaluated after the balanced preprocessing token sequence is processed as in normal text, using the rules specified for conditional inclusion (6.10.1), with the exception that any defined macro expressions are not permitted.
4 The resource width is:
 0, if the integer constant expression evaluates to 0; or,
 the implementation resource width if it is less than the embed element width multiplied by the integer constant expression; or,
 the embed element width multiplied by the integer constant expression, if it is less than or equal to the implementation resource width.
5 EXAMPLE 1 Checking the first 4 elements of a sound resource.
6.10.3.2
        #include <assert.h>
int main (int, char*[]) {
static const char sound_signature[] = {
#embed <sdk/jump.wav> limit(2+2) };
static_assert((sizeof(sound_signature) / sizeof(*sound_signature)) == 4,
           "There should only be 4 elements in this array.");
// verify PCM WAV resource
assert(sound_signature[0] == R); assert(sound_signature[1] == I); assert(sound_signature[2] == F); assert(sound_signature[3] == F); assert(sizeof(sound_signature) == 4);
return 0;
                                        }
    6 EXAMPLE 2 Similar to a previous example, except it illustrates macro expansion specifically done for the limit(...) parameter.
#include <assert.h>
#define TWO_PLUS_TWO 2+2
int main (int, char*[]) {
const char sound_signature[] = {
/* the token sequence within the parentheses for the "limit" parameter undergoes macro expansion, at least once, resulting in
            #embed <sdk/jump.wav> limit(2+2)
                  */
#embed <sdk/jump.wav> limit(TWO_PLUS_TWO) };
       }
static_assert((sizeof(sound_signature) / sizeof(*sound_signature)) == 4, "There should only be 4 elements in this array.");
// verify PCM WAV resource
assert(sound_signature[0] == R); assert(sound_signature[1] == I); assert(sound_signature[2] == F); assert(sound_signature[3] == F); assert(sizeof(sound_signature) == 4);
return 0;
  7 EXAMPLE3 Apotentialconstraintviolationfromaresourcethatmaynothaveenoughinformation in an environment that has a CHAR_BIT greater than 24.
8 EXAMPLE4 Apotentialconstraintviolationfromaresourcethatmaynothaveenoughinformation in an environment that has a CHAR_BIT greater than 24.
         int main (int, char*[]) {
const unsigned char arr[] = {
#embed "24_bits.bin" limit(1) // may be a constraint violation };
                    }
return 0;
                 int main (int, char*[]) {
const unsigned char arr[] = {
#embed "24_bits.bin" limit(1) // may be a constraint violation };
return 0;
 }
9 EXAMPLE 5 Resources interfacing with certain implementations may have an infinite stream of data, such as the </owo/uwurandom> resource used in the snippet below:
The limit parameter may help process only a portion of that information and prevent exhaustion of an implementations internal resources when processing such data.
6.10.3.3 suffix parameter
Constraints
The suffix standard embed parameter may appear zero times or one time in the embed parameter sequence. Its preprocessor argument clause shall be present and have the form:
( pp-balanced-token-sequenceopt )
Semantics
1 The embed parameter with a preprocessing parameter token suffix denotes a balanced preprocess- ing token sequence within its preprocessor argument clause that will be placed immediately after the result of the associated #embed directives expansion.
2 If the resource is empty, then suffix has no effect and is ignored.
3 EXAMPLE 1 Extra elements added to array initializer.
#include <string.h>
#ifndef SHADER_TARGET
#define SHADER_TARGET "edith-impl.glsl" #endif
extern char* null_term_shader_data;
void fill_in_data () {
const char internal_data[] = {
#embed SHADER_TARGET \ suffix(,)
0 };
strcpy(null_term_shader_data, internal_data);
                int main (int, char*[]) {
const unsigned char arr[] = {
#embed </owo/uwurandom> limit(513) };
               }
return 0;
              }
  prefix parameter Constraints
1 The prefix standard embed parameter may appear zero times or one time in the embed parameter sequence. Its preprocessor parameter clause shall be present and have the form:
6.10.3.4
( pp-balanced-token-sequenceopt )
2 The embed parameter with a preprocessor parameter token prefix denotes a balanced preprocessing
token sequence within its preprocessor argument clause that will be placed immediately before the 176 Language § 6.10.3.4
Semantics
result of the associated #embed directives expansion, if any.
3 If the resource is empty, then prefix has no effect and is ignored.
4 EXAMPLE 1 A null-terminated character array with prefixed and suffixed additional tokens when the resource is not empty, providing null termination and a byte order mark.
#include <string.h> #include <assert.h>
#ifndef SHADER_TARGET
#define SHADER_TARGET "ches.glsl" #endif
extern char* merp;
void init_data () {
const char whl[] = {
#embed SHADER_TARGET \ prefix(0xEF, 0xBB, 0xBF, ) /* UTF-8 BOM */ \
suffix(,)
0 };
// always null terminated,
// contains BOM if not-empty
int is_good = (sizeof(whl) == 1 && whl[0] == ’\0)
|| (whl[0] == ’\xEF && whl[1] == ’\xBB
&& whl[2] == ’\xBF && whl[sizeof(whl) - 1] == ’\0); assert(is_good);
strcpy(merp, whl);
if_empty parameter
The if_empty standard embed parameter may appear zero times or one time in the embed parameter
sequence. Its preprocessor argument clause shall be present and have the form: ( pp-balanced-token-sequenceopt )
Semantics
1 The embed parameter with a preprocessing parameter token if_empty denotes a balanced pre- processing token sequence within its preprocessor argument clause that will replace the #embed directive entirely.
If the resource is not empty, then if_empty has no effect and is ignored.
2 EXAMPLE 1 If the search for the resource is successful, this resource is always considered empty due to the limit(0) embed parameter. This program always returns 0, even if the resource is searched for and found successfully by the implementation and has an implementation resource width greater than 0.
3 EXAMPLE 2 An example similar to using the suffix embed parameter, but changed slightly.
#include <string.h>
       }
  6.10.3.5 Constraints
         int main () { return
#embed <some_resource> limit(0) prefix(1) if_empty(0) ;
                // becomes:
// return 0;
        }
    #ifndef SHADER_TARGET
#define SHADER_TARGET "edith-impl.glsl" #endif
extern char* null_term_shader_data;
void fill_in_data () {
const char internal_data[] = {
#embed SHADER_TARGET \ suffix(, 0) \
                              if_empty(0) };
strcpy(null_term_shader_data, internal_data);
               }
    4 EXAMPLE 3 This resource is considered empty due to the limit(0) embed parameter, meaning an if_empty expression replaces the directive as specified above. A constraint is still violated if the search for the resource is unsuccessful.
becomes:
6.10.4 Macro replacement
Constraints
1 Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, ordering, spelling, and white-space separation, where all white-space separations are considered identical.
2 An identifier currently defined as an object-like macro shall not be redefined by another #define preprocessing directive unless the second definition is an object-like macro definition and the two replacement lists are identical. Likewise, an identifier currently defined as a function-like macro shall not be redefined by another #define preprocessing directive unless the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical.
3 There shall be white space between the identifier and the replacement list in the definition of an object-like macro.
4 If the identifier-list in the macro definition does not end with an ellipsis, the number of arguments (including those arguments consisting of no preprocessing tokens) in an invocation of a function-like macro shall equal the number of parameters in the macro definition. Otherwise, there shall be at least as many arguments in the invocation as there are parameters in the macro definition (excluding the ...). There shall exist a ) preprocessing token that terminates the invocation.
5 The identifiers __VA_ARGS__ and __VA_OPT__ shall occur only in the replacement-list of a function- like macro that uses the ellipsis notation in the parameters.
6 A parameter identifier in a function-like macro shall be uniquely declared within its scope.
        int main () { return
   #embed <infinite-resource> limit(0) if_empty(45540)
      ; }
               int main () { return 45540;
}
Semantics
7 The identifier immediately following the define is called the macro name. There is one name space for macro names. Any white-space characters preceding or following the replacement list of preprocessing tokens are not considered part of the replacement list for either form of macro.
8 If a # preprocessing token, followed by an identifier, occurs lexically at the point at which a prepro- cessing directive could begin, the identifier is not subject to macro replacement.
9 A preprocessing directive of the form
# define identifier replacement-list new-line
defines an object-like macro that causes each subsequent instance of the macro name217) to be replaced by the replacement list of preprocessing tokens that constitute the remainder of the directive. The replacement list is then rescanned for more macro names as specified below.
10 A preprocessing directive of the form
# define identifier lparen identifier-listopt ) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list , ... ) replacement-list new-line
defines a function-like macro with parameters, whose use is similar syntactically to a function call. The parameters are specified by the optional list of identifiers, whose scope extends from their declaration in the identifier list until the new-line character that terminates the #define preprocessing directive. Each subsequent instance of the function-like macro name followed by a ( as the next preprocessing token introduces the sequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation of the macro). The replaced sequence of preprocessing tokens is terminated by the matching ) preprocessing token, skipping intervening matched pairs of left and right parenthesis preprocessing tokens. Within the sequence of preprocessing tokens making up an invocation of a function-like macro, new-line is considered a normal white-space character.
11 The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments. If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives,218) the behavior is undefined.
12 If there is a ... in the identifier-list in the macro definition, then the trailing arguments (if any), including any separating comma preprocessing tokens, are merged to form a single item: the variable arguments. The number of arguments so combined is such that, following merger, the number of arguments is one more than the number of parameters in the macro definition (excluding the ...), except that if there are as many arguments as named parameters, the macro invocation behaves as if a comma token has been appended to the argument list such that variable arguments are formed that contain no pp-tokens.
6.10.4.1 Argument substitution
Syntax
1 va-opt-replacement:
__VA_OPT__ ( pp-tokensopt )
Description
2 Argument substitution is a process during macro expansion in which identifiers corresponding to the parameters of the macro definition and the special constructs __VA_ARGS__ and __VA_OPT__ are replaced with token sequences from the arguments of the macro invocation and possibly of the
217)Since, by macro-replacement time, all character constants and string literals are preprocessing tokens, not sequences possibly containing identifier-like subsequences (see 5.1.1.2, translation phases), they are never scanned for macro names or parameters.
218)Despite the name, a non-directive is a preprocessing directive.
argument of the feature __VA_OPT__. The latter process allows to control a substitute token sequence that is only expanded if the argument list that corresponds to a trailing ... of the parameter list is present and has a non-empty substitution.
Constraints
3 The identifier __VA_OPT__ shall always occur as part of the preprocessing token sequence va-opt- replacement; its closing ) is determined by skipping intervening pairs of matching left and right parentheses in its pp-tokens. The pp-tokens of a va-opt-replacement shall not contain __VA_OPT__. The pp-tokens shall form a valid replacement list for the current function-like macro.
Semantics
4 After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A va-opt-replacement is treated as if it were a parameter. For each parameter in the replacement list that is neither preceded by a # or ## preprocessing token nor followed by a ## preprocessing token, the preprocessing tokens naming the parameter are replaced by a token sequence determined as follows:
 If the parameter is of the form va-opt-replacement, the replacement preprocessing tokens are the preprocessing token sequence for the corresponding argument, as specified below.
 Otherwise, the replacement preprocessing tokens are the preprocessing tokens of the corre- sponding argument after all macros contained therein have been expanded. The arguments preprocessing tokens are completely macro replaced before being substituted as if they formed the rest of the preprocessing file with no other preprocessing tokens being available.
5 EXAMPLE 1
6 An identifier __VA_ARGS__ that occurs in the replacement list is treated as if it were a parameter, and the variable arguments form the preprocessing tokens used to replace it.
7 The preprocessing token sequence for the corresponding argument of a va-opt-replacement is defined as follows. If a (hypothetical) substitution of __VA_ARGS__ as neither an operand of # nor ## consists of no preprocessing tokens, the argument consists of a single placemarker preprocessing token (6.10.4.3, 6.10.4.4). Otherwise, the argument consists of the results of the expansion of the contained pp-tokens as the replacement list of the current function-like macro before removal of placemarker tokens, rescanning, and further replacement.
8 NOTE 1 The placemarker tokens are removed before stringization (6.10.4.2), and can be removed by rescanning and further replacement (6.10.4.4).
9 EXAMPLE 2
        #define LPAREN() (
#define G(Q) 42
#define F(R, X, ...) __VA_OPT__(G R X) )
int x = F(LPAREN(), 0, <:-); // replaced by int x = 42;
                 #define F(...) f(0 __VA_OPT__(,) __VA_ARGS__) #define G(X, ...) f(0, X __VA_OPT__(,) __VA_ARGS__) #define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ }) #define EMP
                   F(a, b, c)
F()
F(EMP)
G(a, b, c)
G(a, )
G(a)
SDEF(foo);
// replaced by f(0, a, b, c)
// replaced by f(0)
// replaced by f(0)
// replaced by f(0, a, b, c)
// replaced by f(0, a)
// replaced by f(0, a)
// replaced by S foo;
SDEF(bar, 1, 2); // replaced by S bar = { 1, 2 };
#define H1(X, ...) X __VA_OPT__(##) __VA_ARGS__ // error: ## on line above
                  // may not appear at the beginning of a replacement
                  // list (6.10.4.3)
#define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__ H2(a, b, c, d) // replaced by ab, c, d
#define H3(X, ...) #__VA_OPT__(X##X X##X) H3(, 0) // replaced by ""
#define H4(X, ...) __VA_OPT__(a X ## X) ## b
   H4(, 1)
#define H5A(...) #define H5B(X) #define H5C(X) H5C(H5A())
The # operator Constraints
// replaced by a b
__VA_OPT__()/**/__VA_OPT__() a ## X ## b
H5B(X)
// replaced by ab
  6.10.4.2
1 Each # preprocessing token in the replacement list for a function-like macro shall be followed by a parameter as the next preprocessing token in the replacement list.
Semantics
2 If, in the replacement list, a parameter is immediately preceded by a # preprocessing token, both are replaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding argument (excluding placemarker tokens). Let the stringizing argument be the preprocessing token sequence for the corresponding argument with placemarker tokens removed. Each occurrence of white space between the stringizing arguments preprocessing tokens becomes a single space character in the character string literal. White space before the first preprocessing token and after the last preprocessing token composing the stringizing argument is deleted. Otherwise, the original spelling of each preprocessing token in the stringizing argument is retained in the character string literal, except for special handling for producing the spelling of string literals and character constants: a \ character is inserted before each " and \ character of a character constant or string literal (including the delimiting " characters), except that it is implementation-defined whether a \ character is inserted before the \ character beginning a universal character name. If the replacement that results is not a valid character string literal, the behavior is undefined. The character string literal corresponding to an empty stringizing argument is "". The order of evaluation of # and ## operators is unspecified.
6.10.4.3 The ## operator
Constraints
1 A ## preprocessing token shall not occur at the beginning or at the end of a replacement list for either form of macro definition.
Semantics
2 If, in the replacement list of a function-like macro, a parameter is immediately preceded or followed by a ## preprocessing token, the parameter is replaced by the corresponding arguments preprocess- ing token sequence; however, if an argument consists of no preprocessing tokens, the parameter is replaced by a placemarker preprocessing token instead.219)
3 For both object-like and function-like macro invocations, before the replacement list is reexamined
219)Placemarker preprocessing tokens do not appear in the syntax because they are temporary entities that exist only within translation phase 4.
for more macro names to replace, each instance of a ## preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token. Placemarker preprocessing tokens are handled specially: concatena- tion of two placemarkers results in a single placemarker preprocessing token, and concatenation of a placemarker with a non-placemarker preprocessing token results in the non-placemarker pre- processing token. If the result is not a valid preprocessing token, the behavior is undefined. The resulting token is available for further macro replacement. The order of evaluation of ## operators is unspecified.
4 EXAMPLE In the following fragment:
The expansion produces, at various stages:
In other words, expanding hash_hash produces a new token, consisting of two adjacent sharp signs, but this new token is not the ## operator.
6.10.4.4 Rescanning and further replacement
1 After all parameters in the replacement list have been substituted and # and ## processing has taken place, all placemarker preprocessing tokens are removed. The resulting preprocessing token sequence is then rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace.
2 If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source files preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced. These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.
3 The resulting completely macro-replaced preprocessing token sequence is not processed as a prepro- cessing directive even if it resembles one, but all pragma unary operator expressions within it are then processed as specified in 6.10.10 below.
4 EXAMPLE There are cases where it is not clear whether a replacement is nested or not. For example, given the following macro definitions:
the invocation
f(2)(9)
    #define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)
char p[] = join(x, y); // equivalent to
// char p[] = "x ## y";
                                  join(x, y)
in_between(x hash_hash y) in_between(x ## y) mkstr(x ## y)
"x ## y"
#define f(a) a*g #define g(a) f(a)
could expand to either
2*f(9) or
2*9*g
Strictly conforming programs are not permitted to depend on such unspecified behavior.
6.10.4.5 Scope of macro definitions
1 A macro definition lasts (independent of block structure) until a corresponding #undef directive is encountered or (if none is encountered) until the end of the preprocessing translation unit. Macro definitions have no significance after translation phase 4.
2 A preprocessing directive of the form
# undef identifier new-line
causes the specified identifier no longer to be defined as a macro name. It is ignored if the specified
identifier is not currently defined as a macro name.
3 EXAMPLE 1 The simplest use of this facility is to define a "manifest constant", as in
4 EXAMPLE 2 The following defines a function-like macro whose value is the maximum of its arguments. It has the advantages of working for any compatible types of the arguments and of generating in-line code without the overhead of function calling. It has the disadvantages of evaluating one or the other of its arguments a second time (including side effects) and generating more code than a function if invoked several times. It also cannot have its address taken, as it has none.
#define max(a, b) ((a) > (b) ? (a): (b))
The parentheses ensure that the arguments and the resulting expression are bound properly.
5 EXAMPLE 3 To illustrate the rules for redefinition and reexamination, the sequence
                                   #define TABSIZE 100 int table[TABSIZE];
                                #define x
#define f(a)
#undef x
#define x
#define g
#define z
#define h
#define m(a)
#define w
#define t(a)
#define p()
#define q(x)
#define r(x,y) x ## y #define str(x) # x
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h 5) & m
(f)^m(m);
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; char c[2][6] = { str(hello), str() };
3
f(x * (a))
2
f
z[0] g(\~{ } a(w) 0,1
a
int
x
  § 6.10.4.5 Language 183

ISO/IEC 9899:2023 (E) working draft  September 3, 2022 N3054 results in
6 EXAMPLE 4 To illustrate the rules for creating character string literals and concatenating tokens, the sequence
        f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * (\~{ } 5)) & f(2 * (0,1))^m(0,1); inti[]={1,23,4,5, };
char c[2][6] = { "hello", "" };
                    #define str(s) # s
#define xstr(s) str(s)
#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \
x ## s, x ## t) #define INCFILE(n) vers ## n
#define glue(a, b) a ## b #define xglue(a, b) glue(a, b) #define HIGHLOW "hello" #define LOW LOW ", world"
debug(1, 2);
fputs(str(strncmp("abc\0d", "abc", ’\4) // this goes away
== 0) str(: @\n), s); #include xstr(INCFILE(2).h) glue(HIGH, LOW); xglue(HIGH, LOW)
results in
or, after concatenation of the character string literals,
Space around the # and ## tokens in the macro definition is optional.
7 EXAMPLE 5 To illustrate the rules for placemarker preprocessing tokens, the sequence
results in
8 EXAMPLE 6 To demonstrate the redefinition rules, the following sequence is valid.
          printf("x" "1" "= %d, x" "2" "= %s", x1, x2); fputs(
"strncmp(\"abc\\0d\", \"abc\", ’\\4’) == 0" ": @\n",
s);
#include "vers2.h" (after macro replacement, before file access) "hello";
"hello" ", world"
                              printf("x1= %d, x2= %s", x1, x2); fputs(
  "strncmp(\"abc\\0d\", \"abc\", ’\\4’) == 0: @\n",
s);
#include "vers2.h" (after macro replacement, before file access) "hello";
"hello, world"
                              #define t(x,y,z) x ## y ## z
int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
           t(10,,), t(,11,), t(,,12), t(,,) };
                  int j[] = { 123, 45, 67, 89, 10, 11, 12, };
       
N3054 working draft  September 3, 2022
ISO/IEC 9899:2023 (E)
    #define OBJ_LIKE #define OBJ_LIKE #define FUNC_LIKE(a) #define FUNC_LIKE(a)(
(1-1)
/* white space */ (1-1) /* other */
(a)
/* note the white space */ \ a /* other stuff on this line
*/)
                             But the following redefinitions are invalid:
9 EXAMPLE 7 Finally, to show the variable argument list macro facilities:
results in
6.10.5 Line control
Constraints
1 The string literal of a #line directive, if present, shall be a character string literal. Semantics
2 The line number of the current source line is one greater than the number of new-line characters read or introduced in translation phase 1 (5.1.1.2) while processing the source file to the current token.
3 If a preprocessing token (in particular __LINE__) spans two or more physical lines, it is unspecified which of those line numbers is associated with that token. If a preprocessing directive spans two or more physical lines, it is unspecified which of those line numbers is associated with the preprocessing directive. If a macro invocation spans multiple physical or logical lines, it is unspecified which of those line numbers is associated with that invocation. The line number of a preprocessing token is independent of the context (in particular, as a macro argument or in a preprocessing directive). The line number of a __LINE__ in a macro body is the line number of the macro invocation.
4 A preprocessing directive of the form
# line digit-sequence new-line
causes the implementation to behave as if the following sequence of source lines begins with a source line that has a line number as specified by the digit sequence (interpreted as a decimal integer, ignoring any optional digit separators (6.4.4.1) in the digit sequence). The digit sequence shall not specify zero, nor a number greater than 2147483647.
5 A preprocessing directive of the form
    #define OBJ_LIKE (0) // different token sequence #define OBJ_LIKE (1 - 1) // different white space #define FUNC_LIKE(b) (a) // different parameter usage #define FUNC_LIKE(b) (b) // different parameter spelling
                         #define debug(...) fprintf(stderr, __VA_ARGS__) #define showlist(...) puts(#__VA_ARGS__)
#define report(test, ...) ((test)?puts(#test):\
printf(__VA_ARGS__)) debug("Flag");
debug("X = %d\n", x);
showlist(The first, second, and third items.); report(x>y, "x is %d but y is %d", x, y);
                                              fprintf(stderr, "Flag");
fprintf(stderr, "X = %d\n", x);
puts("The first, second, and third items."); ((x>y)?puts("x>y"):
printf("x is %d but y is %d", x, y));
 # line digit-sequence " s-char-sequenceopt " new-line
sets the presumed line number similarly and changes the presumed name of the source file to be the contents of the character string literal.
6 A preprocessing directive of the form
# line pp-tokens new-line
(that does not match one of the two previous forms) is permitted. The preprocessing tokens after line on the directive are processed just as in normal text (each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens). The directive resulting after all replacements shall match one of the two previous forms and is then processed as appropriate.220)
Recommended practice
7 The line number associated with a pp-token should be the line number of the first character of the pp-token. The line number associated with a preprocessing directive should be the line number of the line with the first # token. The line number associated with a macro invocation should be the line number of the first character of the macro name in the invocation.
6.10.6 Diagnostic directives
Semantics
1 A preprocessing directive of either form
# error pp-tokensopt new-line
# warning pp-tokensopt new-line
causes the implementation to produce a diagnostic message that includes the specified sequence of
preprocessing tokens.
6.10.7 Pragma directive
Semantics
1 A preprocessing directive of the form
# pragma pp-tokensopt new-line
where the preprocessing token STDC does not immediately follow pragma in the directive (prior to any macro replacement)221) causes the implementation to behave in an implementation-defined man- ner. The behavior might cause translation to fail or cause the translator or the resulting program to behave in a non-conforming manner. Any such pragma that is not recognized by the implementation is ignored.
2 If the preprocessing token STDC does immediately follow pragma in the directive (prior to any macro replacement), then no macro replacement is performed on the directive, and the directive shall have one of the following forms222) whose meanings are described elsewhere:
standard-pragma:
# pragma STDC FP_CONTRACT on-off-switch
# pragma STDC FENV_ACCESS on-off-switch
# pragma STDC FENV_DEC_ROUND dec-direction
# pragma STDC FENV_ROUND direction
# pragma STDC CX_LIMITED_RANGE on-off-switch
220)Because a new-line is explicitly included as part of the #line directive, the number of new-line characters read while processing to the first pp-token can be different depending on whether the implementation uses a one-pass preprocessor. Therefore,therearetwopossiblevaluesforthelinenumberfollowingadirectiveoftheform#line __LINE__new-line.
221)An implementation is not required to perform macro replacement in pragmas, but it is permitted except for in standard pragmas (where STDC immediately follows pragma). If the result of macro replacement in a non-standard pragma has the same form as a standard pragma, the behavior is still implementation-defined; an implementation is permitted to behave as if it were the standard pragma, but is not required to.
222)See "future language directions" (6.11.6).
 on-off-switch: one of
direction: one of
ON OFF DEFAULT
FE_DOWNWARD FE_TONEAREST FE_TOWARDZERO FE_UPWARD
dec-direction: one of
FE_DEC_DOWNWARD FE_DEC_TONEAREST FE_DEC_TONEARESTFROMZERO FE_DEC_TOWARDZERO FE_DEC_UPWARD FE_DEC_DYNAMIC
Forward references: the FP_CONTRACT pragma (7.12.2), the FENV_ACCESS pragma (7.6.1), the FENV_DEC_ROUND pragma (7.6.3), the FENV_ROUND pragma (7.6.2), the CX_LIMITED_RANGE pragma (7.3.4).
6.10.8 Null directive
Semantics
1 A preprocessing directive of the form
# new-line
has no effect.
6.10.9 Predefined macro names
1 The values of the predefined macros listed in the following subclauses223) (except for __FILE__ and __LINE__) remain constant throughout the translation unit.
2 None of these macro names, nor the identifiers defined, __has_c_attribute, __has_include , or __has_embed shall be the subject of a #define or a #undef preprocessing directive. Any other predefined macro names: shall begin with a leading underscore followed by an uppercase letter; or, a second underscore; or, shall be any of the identifiers alignas, alignof, bool, false, static_assert, thread_local, or true.
3 The implementation shall not predefine the macro __cplusplus, nor shall it define it in any standard header.
Forward references: standard headers (7.1.2). 6.10.9.1 Mandatory macros
1 The following macro names shall be defined by the implementation:
__DATE__
__FILE__
__LINE__
Thedateoftranslationofthepreprocessingtranslationunit:acharacterstringliteralof theform"Mmm dd yyyy",wherethenamesofthemonthsarethesameasthosegenerated by the asctime function, and the first character of dd is a space character if the value is less than 10. If the date of translation is not available, an implementation-defined valid date shall be supplied.
Thepresumednameofthecurrentsourcefile(acharacterstringliteral).224)
Thepresumedlinenumber(withinthecurrentsourcefile)ofthecurrentsourceline(an integer constant).224)
__STDC__
__STDC_HOSTED__ Theintegerconstant1iftheimplementationisahostedimplementationorthe
Theintegerconstant1,intendedtoindicateaconformingimplementation. integer constant 0 if it is not.
 FE_TONEARESTFROMZERO
FE_DYNAMIC
 223)See "future language directions" (6.11.7).
224)The presumed source file name and line number can be changed by the #line directive.
__STDC_UTF_16__ The integer constant 1, intended to indicate that values of type char16_t are
UTF16 encoded.
__STDC_UTF_32__ The integer constant 1, intended to indicate that values of type char32_t are UTF32 encoded.
__STDC_VERSION__ Theintegerconstant202311L.225)
__TIME__ Thetimeoftranslationofthepreprocessingtranslationunit:acharacterstringliteralof the form "hh:mm:ss" as in the time generated by the asctime functions. If the time of translation is not available, an implementation-defined valid time shall be supplied.
Forward references: the asctime functions (7.29.3.1). 6.10.9.2 Environment macros
1 The following macro names are conditionally defined by the implementation:
__STDC_ISO_10646__ An integer constant of the form yyyymmL (for example, 199712L). If this symbol is defined, then every character in the Unicode required set, when stored in an object of type wchar_t, has the same value as the short identifier of that character. The Unicode required set consists of all the characters that are defined by ISO/IEC 10646, along with all amendments and technical corrigenda, as of the specified year and month. If some other encoding is used, the macro shall not be defined and the actual encoding used is implementation-defined.
__STDC_MB_MIGHT_NEQ_WC__ Theintegerconstant1,intendedtoindicatethat,intheencodingfor wchar_t, a member of the basic character set need not have a code value equal to its value when used as the lone character in an integer character constant.
Forward references: common definitions (7.21), Unicode utilities (7.30). 6.10.9.3 Conditional feature macros
1 The following macro names are conditionally defined by the implementation:
__STDC_ANALYZABLE__ Theintegerconstant1,intendedtoindicateconformancetothespecifica- tions in Annex L (Analyzability).
__STDC_IEC_60559_BFP__ The integer constant 202311L, intended to indicate conformance to Annex F (IEC 60559 floating-point arithmetic) for binary floating-point arithmetic.
__STDC_IEC_559__ Theintegerconstant1,intendedtoindicateconformancetothespecifications in Annex F (IEC 60559 floating-point arithmetic) for binary floating-point arithmetic. Use of this macro is an obsolescent feature.
__STDC_IEC_60559_DFP__ Theintegerconstant202311L,intendedtoindicatesupportofdecimal floating types and conformance to Annex F (IEC 60559 floating-point arithmetic) for decimal floating-point arithmetic.
__STDC_IEC_60559_COMPLEX__ Theintegerconstant202311L,intendedtoindicateconformance to the specifications in Annex G (IEC 60559 compatible complex arithmetic).
__STDC_IEC_60559_TYPES__ Theintegerconstant202311L,intendedtoindicateconformanceto the specification in Annex H (IEC 60559 interchange and extended types).
__STDC_IEC_559_COMPLEX__ Theintegerconstant1,intendedtoindicateadherencetothespecifi- cations in Annex G (IEC 60559 compatible complex arithmetic). Use of this macro is an obsolescent feature.
225)See Annex M for the values in previous revisions. The intention is that this will remain an integer constant of type long intthatisincreasedwitheachrevisionofthisdocument.
__STDC_LIB_EXT1__ Theintegerconstant202311L,intendedtoindicatesupportfortheextensions
defined in Annex K (Bounds-checking interfaces)226).
__STDC_NO_ATOMICS__ Theintegerconstant1,intendedtoindicatethattheimplementationdoes not support atomic types (including the _Atomic type qualifier) and the <stdatomic.h> header.
__STDC_NO_COMPLEX__ Theintegerconstant1,intendedtoindicatethattheimplementationdoes not support complex types or the <complex.h> header.
__STDC_NO_THREADS__ Theintegerconstant1,intendedtoindicatethattheimplementationdoes not support the <threads.h> header.
__STDC_NO_VLA__ Theintegerconstant1,intendedtoindicatethattheimplementationdoesnot support variable length arrays with automatic storage duration. Parameters declared with variable length array types are adjusted and then define objects of automatic storage duration with pointer types. Thus, support for such declarations is mandatory.
2 An implementation that defines __STDC_NO_COMPLEX__ shall not define __STDC_IEC_60559_COMPLEX__ or __STDC_IEC_559_COMPLEX__.
6.10.10 Pragma operator
Semantics
1 A unary operator expression of the form:
_Pragma ( string-literal )
is processed as follows: The string literal is destringized by deleting any encoding prefix, deleting the leading and trailing double-quotes, replacing each escape sequence \" by a double-quote, and replacing each escape sequence \\ by a single backslash. The resulting sequence of characters is processed through translation phase 3 to produce preprocessing tokens that are executed as if they were the pp-tokens in a pragma directive. The original four preprocessing tokens in the unary operator expression are removed.
2 EXAMPLE A directive of the form:
#pragma listing on "..\listing.dir"
can also be expressed as:
_Pragma ("listing on \"..\\listing.dir\"")
The latter form is processed in the same way whether it appears literally as shown, or results from macro replacement, as in:
                                   #define LISTING(x) PRAGMA(listing on #x) #define PRAGMA(x) _Pragma(#x)
LISTING (..\listing.dir)          226)Theintentionisthatthiswillremainanintegerconstantoftypelong intthatisincreasedwitheachrevisionofthis document.
6.11 Future language directions
6.11.1 Floating types
1 Future standardization may include additional floating types, including those with greater range, precision,orboththanlong double.
6.11.2 Linkages of identifiers
1 Declaring an identifier with internal linkage at file scope without the static storage-class specifier is an obsolescent feature.
6.11.3 External names
1 Restriction of the significance of an external name to fewer than 255 characters (considering each universal character name or extended source character as a single character) is an obsolescent feature that is a concession to existing implementations.
6.11.4 Character escape sequences
1 Lowercase letters as escape sequences are reserved for future standardization. Other characters may be used in extensions.
6.11.5 Storage-class specifiers
1 The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.
6.11.6 Pragma directives
1 Pragmas whose first preprocessing token is STDC are reserved for future standardization. 6.11.7 Predefined macro names
1 Macro names beginning with __STDC_ are reserved for future standardization.
2 Uses of the __STDC_IEC_559__ and __STDC_IEC_559_COMPLEX__ macros are obsolescent features.

int main() {
//    PR3(st.a,st.b,st.c,d);
    printf("%s\n", n3054);
    return EXIT_SUCCESS;
}

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

bash

検討事項(agenda)

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

応用例1 MISRA C/C++

MISRA C まとめ #include

MISRA C++ 5-0-16

応用例2 CERT C/C++

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

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

自己参考資料(self reference)

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

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

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 初稿  20221120

0
0
0

Register as a new user and use Qiita more conveniently

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