はじめに(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)との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。
最新規格はCN4950
背景(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/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.
5. Environment CN3540:2022 (3) p10.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 = "5. Environment CN3054:2022 (3) p10.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"
// 5. Environment
// An implementation translates C source files and executes C programs in two data-processing-system environments, which will be called the translation environment and the execution environment in this document. Their characteristics define and constrain the results of executing conforming C programs constructed according to the syntactic and semantic rules for conforming implementations.
// Forward references: In this clause, only a few of many possible forward references have been noted.
// 5.1 Conceptual models
// 5.1.1 Translation environment 5.1.1.1 Program structure
// A C program need not all be translated at the same time. The text of the program is kept in units called source files, (or preprocessing files) in this document. A source file together with all the headers and source files included via the preprocessing directive #include is known as a preprocessing translation unit. After preprocessing, a preprocessing translation unit is called a translation unit. Previously translated translation units may be preserved individually or in libraries. The separate translation units of a program communicate by (for example) calls to functions whose identifiers have external linkage, manipulation of objects whose identifiers have external linkage, or manipulation of data files. Translation units may be separately translated and then later linked to produce an executable program.
// Forward references: linkages of identifiers (6.2.2), external definitions (6.9), preprocessing direc- tives (6.10).
// 5.1.1.2 Translation phases
// The precedence among the syntax rules of translation is specified by the following phases.6)
// 1. Physicalsourcefilemultibytecharactersaremapped,inanimplementation-definedmanner,to the source character set (introducing new-line characters for end-of-line indicators) if necessary.
// 2. Each instance of a backslash character (\) immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines. Only the last backslash on any physical source line shall be eligible for being part of such a splice. A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character before any such splicing takes place.
// 3. The source file is decomposed into preprocessing tokens7) and sequences of white-space characters (including comments). A source file shall not end in a partial preprocessing token or in a partial comment. Each comment is replaced by one space character. New-line characters are retained. Whether each nonempty sequence of white-space characters other than new-line is retained or replaced by one space character is implementation-defined.
// 4. Preprocessing directives are executed, macro invocations are expanded, and _Pragma unary operator expressions are executed. If a character sequence that matches the syntax of a univer- sal character name is produced by token concatenation (6.10.4.3), the behavior is undefined. A #include preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively. All preprocessing directives are then deleted.
// 6)This requires implementations to behave as if these separate phases occur, even though many are typically folded together in practice. Source files, translation units, and translated translation units need not necessarily be stored as files, nor need there be any one-to-one correspondence between these entities and any external representation. The description is conceptual only, and does not specify any particular implementation.
// 7)As described in 6.4, the process of dividing a source file’s characters into preprocessing tokens is context-dependent. For example, see the handling of < within a #include preprocessing directive.
// 5. Each source character set member and escape sequence in character constants and string literals is converted to the corresponding member of the execution character set. Each instance of a source character or escape sequence for which there is no corresponding member is converted in an implementation-defined manner to some member of the execution character set other than the null (wide) character.8)
// 6. Adjacent string literal tokens are concatenated.
// 7. White-space characters separating tokens are no longer significant. Each preprocessing token is converted into a token. The resulting tokens are syntactically and semantically analyzed and translated as a translation unit.
// 8. All external object and function references are resolved. Library components are linked to satisfy external references to functions and objects not defined in the current translation. All such translator output is collected into a program image which contains information needed for execution in its execution environment.
// Forward references: universal character names (6.4.3), lexical elements (6.4), preprocessing direc- tives (6.10), external definitions (6.9).
// 5.1.1.3 Diagnostics
// A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.9)
// EXAMPLE An implementation is required to issue a diagnostic for the translation unit:
// because in those cases where wording in this document describes the behavior for a construct as being both a constraint error and resulting in undefined behavior, the constraint error is still required to be diagnosed.
// 5.1.2 Execution environments
// Two execution environments are defined: freestanding and hosted. In both cases, program startup occurs when a designated C function is called by the execution environment. All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified. Program termination returns control to the execution environment.
// Forward references: storage durations of objects (6.2.4), initialization (6.7.10). 5.1.2.1 Freestanding environment
// In a freestanding environment (in which C program execution may take place without any ben- efit of an operating system), the name and type of the function called at program startup are implementation-defined. Any library facilities available to a freestanding program, other than the minimal set required by Clause 4, are implementation-defined.
// The effect of program termination in a freestanding environment is implementation-defined.
// 5.1.2.2 Hosted environment
// A hosted environment need not be provided, but shall conform to the following specifications if present.
// 8)An implementation may convert each instance of the same non-corresponding source character to a different member of the execution character set.
// 9)An implementation is encouraged to identify the nature of, and where possible localize, each violation. Of course, an implementation is free to produce any number of diagnostic messages, often referred to as warnings, as long as a valid program is still correctly translated. It can also successfully translate an invalid program. Annex I lists a few of the more // // common warnings.
char i;
int i;
// Program startup
// The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:
int main2(void) { /* ... */ }
// or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):
int main3(int argc, char *argv[]) { /* ... */ }
// or equivalent10); or in some other implementation-defined manner.
// If they are declared, the parameters to the main function shall obey the following constraints:
// — The value of argc shall be nonnegative.
// — argv[argc] shall be a null pointer.
// — If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.
// — If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters.
// - Theparametersargcandargvandthestringspointedtobytheargvarrayshallbemodifiable by the program, and retain their last-stored values between program startup and program termination.
// 5.1.2.2.2 Program execution
// In a hosted environment, a program may use all the functions, macros, type definitions, and objects described in the library clause (Clause 7).
// 5.1.2.2.3 Program termination
// If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument;11) reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.
// Forward references: definition of terms (7.1.1), the exit function (7.24.4.4). 5.1.2.3 Program execution
// The semantic descriptions in this document describe the behavior of an abstract machine in which issues of optimization are irrelevant.
// An access to an object through the use of an lvalue of volatile-qualified type is a volatile access. A volatile access to an object, modifying an object, modifying a file, or calling a function that does any
//10)Thus,intcanbereplacedbyatypedefnamedefinedasint,orthetypeofargvcanbewrittenaschar ** argv,andso on.
// 11)In accordance with 6.2.4, the lifetimes of objects with automatic storage duration declared in main will have ended in the former case, even where they would not have in the latter.
// of those operations are all side effects12), which are changes in the state of the execution environment.
// Evaluation of an expression in general includes both value computations and initiation of side effects. Value computation for an lvalue expression includes determining the identity of the designated object.
// Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread, which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. (Conversely, if A is sequenced before B, then B is sequenced after A.) If A is not sequenced before or after B, then A and B are unsequenced. Evaluations A and B are indeterminately sequenced when A is sequenced either before or after B, but it is unspecified which.13) The presence of a sequence point between the evaluation of expressions A and B implies that every value computation and side effect associated with A is sequenced before every value computation and side effect associated with B. (A summary of the sequence points is given in Annex C.)
// In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or through volatile access to an object).
// When the processing of the abstract machine is interrupted by receipt of a signal, the values of objects that are neither lock-free atomic objects nor of type volatile sig_atomic_t are unspecified, as is the state of the dynamic floating-point environment. The representation of any object modified by thehandlerthatisneitheralock-freeatomicobjectnoroftypevolatile sig_atomic_tbecomes indeterminate when the handler exits, as does the state of the dynamic floating-point environment if it is modified by the handler and not restored to its original state.
// The least requirements on a conforming implementation are:
// — Volatile accesses to objects are evaluated strictly according to the rules of the abstract machine.
// — At program termination, all data written into files shall be identical to the result that execution of the program according to the abstract semantics would have produced.
// — The input and output dynamics of interactive devices shall take place as specified in 7.23.3. The intent of these requirements is that unbuffered or line-buffered output appear as soon as possible, to ensure that prompting messages appear prior to a program waiting for input.
// This is the observable behavior of the program.
// What constitutes an interactive device is implementation-defined.
// More stringent correspondences between abstract and actual semantics may be defined by each implementation.
// EXAMPLE 1 An implementation might define a one-to-one correspondence between abstract and actual semantics: at every sequence point, the values of the actual objects would agree with those specified by the abstract semantics. The keyword volatile would then be redundant.
// Alternatively, an implementation might perform various optimizations within each translation unit, such that the actual semantics would agree with the abstract semantics only when making function calls across translation unit boundaries. In such an implementation, at the time of each function entry and function return where the calling function and the called function are in different translation units, the values of all externally linked objects and of all objects accessible via pointers therein would agree with the abstract semantics. Furthermore, at the time of each such function
// 12)The IEC 60559 standard for binary floating-point arithmetic requires certain user-accessible status flags and control modes. Floating-point operations implicitly set the status flags; modes affect result values of floating-point operations. Implementations that support such floating-point state are required to regard changes to it as side effects — see Annex F for details. The floating-point environment library <fenv.h> provides a programming facility for indicating when these side effects matter, freeing the implementations in other cases.
// 13)The executions of unsequenced evaluations can interleave. Indeterminately sequenced evaluations cannot interleave, but can be executed in any order.
// entry the values of the parameters of the called function and of all objects accessible via pointers therein would agree with the abstract semantics. In this type of implementation, objects referred to by interrupt service routines activated by the signal function would require explicit specification of volatile storage, as well as other implementation-defined restrictions.
// EXAMPLE 2 In executing the fragment
// the "integer promotions" require that the abstract machine promote the value of each variable to int size and then add the two ints and truncate the sum. Provided the addition of two chars can be done without integer overflow, or with integer overflow wrapping silently to produce the correct result, the actual execution need only produce the same result, possibly omitting the promotions.
// EXAMPLE 3 Similarly, in the fragment the multiplication can be executed using single-precision arithmetic if the implementation can ascertain that the result would be the same as if it were executed using double-precision arithmetic (for example, if d were replaced by the constant 2.0, which has type double).
// EXAMPLE 4 Implementations employing wide registers have to take care to honor appropriate semantics. Values are independent of whether they are represented in a register or in memory. For example, an implicit spilling of a register is not permitted to alter the value. Also, an explicit store and load is required to round to the precision of the storage type. In particular, casts and assignments are required to perform their specified conversion. For the fragment the values assigned to d1 and d2 are required to have been converted to float.
// EXAMPLE 5 Rearrangement for floating-point expressions is often restricted because of limitations in precision as well as range. The implementation cannot generally apply the mathematical associa- tive rules for addition or multiplication, nor the distributive rule, because of roundoff error, even in the absence of overflow and underflow. Likewise, implementations cannot generally replace decimal constants to rearrange expressions. In the following fragment, rearrangements suggested by mathematical rules for real numbers are often not valid (see F.9).
// EXAMPLE 6 To illustrate the grouping behavior of expressions, in the following fragment the expression statement behaves exactly the same as
// Environment § 5.1.2.3
char c1, c2; /* ... */
c1 = c1 + c2;
float f1, f2;
double d;
/* ... */
f1 = f2 * d;
double d1, d2;
float f;
d1 = f = expression;
d2 = (float) expression;
double x, y, z;
/* ... */
x=(x*y)*z; //notequivalentto
x*=y*z;
z=(x-y)+y; //notequivalentto
z=x;
z = x + x * y; // not equivalent to
z = x * (1.0 + y);
y = x / 5.0; // not equivalent to
y = x * 0.2;
int a, b;
/* ... */
a = a + 32760 + b + 5;
a = (((a + 32760) + b) + 5);
// duetotheassociativityandprecedenceoftheseoperators.Thus,theresultofthesum(a + 32760) is next added to b, and that result is then added to 5 which results in the value assigned to a. On a machine in which integer overflows produce an explicit trap and in which the range of values representable by an int is [−32768, +32767], the implementation cannot rewrite this expression as
a = ((a + b) + 32765);
// sinceifthevaluesforaandbwere,respectively,−32754and−15,thesuma + bwouldproducea trap while the original expression would not; nor can the expression be rewritten either as or
a = ((a + 32765) + b);
a = (a + (b + 32765));
// since the values for a and b might have been, respectively, 4 and −8 or −17 and 12. However, on a machine in which integer overflow silently generates some value and where positive and negative integer overflows cancel, the above expression statement can be rewritten by the implementation in any of the above ways because the same result will occur.
// EXAMPLE 7 The grouping of an expression does not completely determine its evaluation. In the following fragment the expression statement is grouped as if it were written as
sum = (((sum * 10) + ((*(p++)) = (getchar())));
// but the actual increment of p can occur at any time between the previous sequence point and the next sequence point (the ;), and the call to getchar can occur at any point prior to the need of its returned value.
// Forward references: expressions (6.5), type qualifiers (6.7.3), statements (6.8), floating-point envi- ronment <fenv.h> (7.6), the signal function (7.14), files (7.23.3).
// 5.1.2.4 Multi-threaded executions and data races
// Under a hosted implementation, a program can have more than one thread of execution (or thread) running concurrently. The execution of each thread proceeds as defined by the remainder of this document. The execution of the entire program consists of an execution of all its threads.14) Under a freestanding implementation, it is implementation-defined whether a program can have more than one thread of execution.
// The value of an object visible to a thread T at a particular point is the initial value of the object, a value stored in the object by T , or a value stored in the object by another thread, according to the rules below.
// NOTE 1 In some cases, there could instead be undefined behavior. Much of this section is motivated by the desire to support atomic operations with explicit and detailed visibility constraints. However, it also implicitly supports a simpler view for more restricted programs.
// 14)The execution can usually be viewed as an interleaving of all the threads. However, some kinds of atomic operations, for example, allow executions inconsistent with a simple interleaving as described below.
#include <stdio.h>
int sum;
char *p;
/* ... */
sum = sum * 10 + (*p++ = getchar());
// Two expression evaluations conflict if one of them modifies a memory location and the other one reads or modifies the same memory location.
// The library defines atomic operations (7.17) and operations on mutexes (7.28.4) that are specially identified as synchronization operations. These operations play a special role in making assignments in one thread visible to another. A synchronization operation on one or more memory locations is one of an acquire operation, a release operation, both an acquire and release operation, or a consume operation. A synchronization operation without an associated memory location is a fence and can be either an acquire fence, a release fence, or both an acquire and release fence. In addition, there are relaxed atomic operations, which are not synchronization operations, and atomic read-modify-write operations, which have special characteristics.
// NOTE 2 For example, a call that acquires a mutex will perform an acquire operation on the locations composing the mutex. Correspondingly, a call that releases the same mutex will perform a release operation on those same locations. Informally, performing a release operation on A forces prior side effects on other memory locations to become visible to other threads that later perform an acquire or consume operation on A. Relaxed atomic operations are not included as synchronization operations although, like synchronization operations, they cannot contribute to data races.
// All modifications to a particular atomic object M occur in some particular total order, called the modification order of M. If A and B are modifications of an atomic object M, and A happens before B, then A shall precede B in the modification order of M , which is defined below.
// NOTE 3 This states that the modification orders are expected to respect the "happens before" relation.
// NOTE 4 There is a separate order for each atomic object. There is no requirement that these can be combined into a single total order for all objects. In general this will be impossible since different threads can observe modifications to different variables in inconsistent orders.
// A release sequence headed by a release operation A on an atomic object M is a maximal contiguous sub-sequence of side effects in the modification order of M , where the first operation is A and every subsequent operation either is performed by the same thread that performed the release or is an atomic read-modify-write operation.
// Certain library calls synchronize with other library calls performed by another thread. In particular, an atomic operation A that performs a release operation on an object M synchronizes with an atomic operation B that performs an acquire operation on M and reads a value written by any side effect in the release sequence headed by A.
// NOTE 5 Except in the specified cases, reading a later value does not necessarily ensure visibility as described below. Such a requirement would sometimes interfere with efficient implementation.
// NOTE 6 The specifications of the synchronization operations define when one reads the value written by another. For atomic variables, the definition is clear. All operations on a given mutex occur in a single total order. Each mutex acquisition "reads the value written" by the last mutex release.
// An evaluation A carries a dependency15) to an evaluation B if: — the value of A is used as an operand of B, unless:
// • B is an invocation of the kill_dependency macro, • A is the left operand of a && or || operator,• A is the left operand of a ?: operator, or • A is the left operand of a , operator; or
// — A writes a scalar object or bit-field M, B reads from M the value written by A, and A is sequenced before B, or
// — for some evaluation X, A carries a dependency to X and X carries a dependency to B.
// An evaluation A is dependency-ordered before16) an evaluation B if:
// 15)The "carries a dependency" relation is a subset of the "sequenced before" relation, and is similarly strictly intra-thread.
// 16)The "dependency-ordered before" relation is analogous to the "synchronizes with" relation, but uses release/consume in place of release/acquire.
// — A performs a release operation on an atomic object M , and, in another thread, B performs a consume operation on M and reads a value written by any side effect in the release sequence headed by A, or
// — for some evaluation X, A is dependency-ordered before X and X carries a dependency to B.
// An evaluation A inter-thread happens before an evaluation B if A synchronizes with B, A is dependency-ordered before B, or, for some evaluation X:
// — A synchronizes with X and X is sequenced before B,
// — A is sequenced before X and X inter-thread happens before B, or
// — A inter-thread happens before X and X inter-thread happens before B.
// NOTE 7 The "inter-thread happens before" relation describes arbitrary concatenations of "sequenced before", "synchronizes with", and "dependency-ordered before" relationships, with two exceptions. The first exception is that a concatenation is not permitted to end with "dependency-ordered before" followed by "sequenced before". The reason for this limitation is that a consume operation participating in a "dependency-ordered before" relationship provides ordering only with respect to operations to which this consume operation carries a dependency. The reason that this limitation applies only to the end of such a concatenation is that any subsequent release operation will provide the required ordering for a prior consume operation. The second exception is that a concatenation is not permitted to consist entirely of "sequenced before". The reasons for this limitation are (1) to permit "inter-thread happens before" to be transitively closed and (2) the "happens before" relation, defined below, provides for relationships consisting entirely of "sequenced before".
// An evaluation A happens before an evaluation B if A is sequenced before B or A inter-thread happens before B. The implementation shall ensure that no program execution demonstrates a cycle in the "happens before" relation.
// NOTE 8 This cycle would otherwise be possible only through the use of consume operations.
// A visible side effect A on an object M with respect to a value computation B of M satisfies the conditions:
// — A happens before B, and
// — there is no other side effect X to M such that A happens before X and X happens before B.
// The value of a non-atomic scalar object M, as determined by evaluation B, shall be the value stored by the visible side effect A.
// NOTE 9 If there is ambiguity about which side effect to a non-atomic object is visible, then there is a data race and the behavior is undefined.
// NOTE 10 This states that operations on ordinary variables are not visibly reordered. This is not detectable without data races, but it is necessary to ensure that data races, as defined here, and with suitable restrictions on the use of atomics, correspond to data races in a simple interleaved (sequentially consistent) execution.
// The value of an atomic object M, as determined by evaluation B, shall be the value stored by some side effect A that modifies M , where B does not happen before A.
// NOTE 11 The set of side effects from which a given evaluation might take its value is also restricted by the rest of the rules described here, and in particular, by the coherence requirements below.
// If an operation A that modifies an atomic object M happens before an operation B that modifies M , then A shall be earlier than B in the modification order of M .
// NOTE 12 The requirement above is known as "write-write coherence".
// If a value computation A of an atomic object M happens before a value computation B of M , and A takes its value from a side effect X on M , then the value computed by B shall either be the value stored by X or the value stored by a side effect Y on M, where Y follows X in the modification order of M.
// NOTE 13 The requirement above is known as "read-read coherence".
// If a value computation A of an atomic object M happens before an operation B on M , then A shall take its value from a side effect X on M , where X precedes B in the modification order of M .
// NOTE 14 The requirement above is known as "read-write coherence".
// If a side effect X on an atomic object M happens before a value computation B of M, then the evaluation B shall take its value from X or from a side effect Y that follows X in the modification order of M.
// NOTE 15 The requirement above is known as "write-read coherence".
// NOTE 16 This effectively disallows compiler reordering of atomic operations to a single object, even if both operations are "relaxed" loads. By doing so, it effectively makes the "cache coherence" guarantee provided by most hardware available to C atomic operations.
// NOTE 17 The value observed by a load of an atomic object depends on the "happens before" relation, which in turn depends on the values observed by loads of atomic objects. The intended reading is that there exists an association of atomic loads with modifications they observe that, together with suitably chosen modification orders and the "happens before" relation derived as described above, satisfy the resulting constraints as imposed here.
// The execution of a program contains a data race if it contains two conflicting actions in different threads, at least one of which is not atomic, and neither happens before the other. Any such data race results in undefined behavior.
// NOTE 18 It can be shown that programs that correctly use simple mutexes and memory_order_seq_cst operations to prevent all data races, and use no other synchronization operations, behave as though the operations executed by their constituent threads were simply interleaved, with each value computation of an object being the last value stored in that interleaving. This is normally referred to as "sequential consistency". However, this applies only to data-race-free programs, and data-race-free programs cannot observe most program transformations that do not change single-threaded program semantics. In fact, most single-threaded program transformations continue to be allowed, since any program that behaves differently as a result necessarily has undefined behavior even before such a transformation is applied.
// NOTE 19 Compiler transformations that introduce assignments to a potentially shared memory location that would not be modified by the abstract machine are generally precluded by this document, since such an assignment might overwrite another assignment by a different thread in cases in which an abstract machine execution would not have encountered a data race. This includes implementations of data member assignment that overwrite adjacent members in separate memory locations. Reordering of atomic loads in cases in which the atomics in question might alias is also generally precluded, since this could violate the coherence requirements.
// NOTE 20 Transformations that introduce a speculative read of a potentially shared memory location might not preserve the semantics of the program as defined in this document, since they potentially introduce a data race. However, they are typically valid in the context of an optimizing compiler that targets a specific machine with well-defined semantics for data races. They would be invalid for a hypothetical machine that is not tolerant of races or provides hardware race detection.
// 5.2 Environmental considerations
// 5.2.1 Character sets
// Two sets of characters and their associated collating sequences shall be defined: the set in which source files are written (the source character set), and the set interpreted in the execution environment (the execution character set). Each set is further divided into a basic character set, whose contents are given by this subclause, and a set of zero or more locale-specific members (which are not members of the basic character set) called extended characters. The combined set is also called the extended character set. The values of the members of the execution character set are implementation-defined.
// In a character constant or string literal, members of the execution character set shall be represented by corresponding members of the source character set or by escape sequences consisting of the backslash \ followed by one or more characters. A byte with all bits set to 0, called the null character, shall exist in the basic execution character set; it is used to terminate a character string.
// Both the basic source and basic execution character sets shall have the following members: the 26 uppercase letters of the Latin alphabet the 26 lowercase letters of the Latin alphabet the 10 decimal digits 0123456789 18 Environment ABCDEFGHIJKLM NOPQRSTUVWXYZ abcdefghijklm nopqrstuvwxyz
// the following 29 graphic characters
// the space character, and control characters representing horizontal tab, vertical tab, and form feed. The representation of each member of the source and execution basic character sets shall fit in a byte. In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous. In source files, there shall be some way of indicating the end of each line of text; this document treats such an end-of-line indicator as if it were a single new-line character. In the basic execution character set, there shall be control characters representing alert, backspace, carriage return, and new line. If any other characters are encountered in a source file (except in an identifier, a character constant, a string literal, a header name, a comment, or a preprocessing token that is never converted to a token), the behavior is undefined.
// A letter is an uppercase letter or a lowercase letter as defined above; in this document the term does not include other characters that are letters in other alphabets.
// The universal character name construct provides a way to name other characters.
// Forward references: universal character names (6.4.3), character constants (6.4.4.4), preprocessing directives (6.10), string literals (6.4.5), comments (6.4.9), string (7.1.1).
// 5.2.1.1 Multibyte characters
// The source character set may contain multibyte characters, used to represent members of the extended character set. The execution character set may also contain multibyte characters, which need not have the same encoding as for the source character set. For both character sets, the following shall hold:
// — The basic character set, @, $, and ` shall be present and each character shall be encoded as a single byte.
// — The presence, meaning, and representation of any additional members is locale-specific.
// — A multibyte character set may have a state-dependent encoding, wherein each sequence of multibyte characters begins in an initial shift state and enters other locale-specific shift states when specific multibyte characters are encountered in the sequence. While in the initial shift state, all single-byte characters retain their usual interpretation and do not alter the shift state. The interpretation for subsequent bytes in the sequence is a function of the current shift state.
// — A byte with all bits zero shall be interpreted as a null character independent of shift state. Such a byte shall not occur as part of any other multibyte character.
// For source files, the following shall hold:
// — An identifier, comment, string literal, character constant, or header name shall begin and end in the initial shift state.
// — An identifier, comment, string literal, character constant, or header name shall consist of a sequence of valid multibyte characters.
// 5.2.2 Character display semantics
// The active position is that location on a display device where the next character output by the fputc function would appear. The intent of writing a printing character (as defined by the isprint function) to a display device is to display a graphic representation of that character at the active position and then advance the active position to the next position on the current line. The direction of writing is locale-specific. If the active position is at the final position of a line (if there is one), the behavior of the display device is unspecified.
// Alphabetic escape sequences representing non-graphic characters in the execution character set are intended to produce actions on display devices as follows:
// !"#%&’()*+,-./: ;<=>?[\]^_{|}~
// \a (alert)Producesanaudibleorvisiblealertwithoutchangingtheactiveposition.
// \b (backspace)Movestheactivepositiontothepreviouspositiononthecurrentline.Iftheactive position is at the initial position of a line, the behavior of the display device is unspecified.
// \f (formfeed)Movestheactivepositiontotheinitialpositionatthestartofthenextlogicalpage. \n (newline)Movestheactivepositiontotheinitialpositionofthenextline.
// \r (carriagereturn)Movestheactivepositiontotheinitialpositionofthecurrentline.
// \t (horizontaltab)Movestheactivepositiontothenexthorizontaltabulationpositiononthecurrent line. If the active position is at or past the last defined horizontal tabulation position, the behavior of the display device is unspecified.
// \v (vertical tab) Moves the active position to the initial position of the next vertical tabulation position. If the active position is at or past the last defined vertical tabulation position, the behavior of the display device is unspecified.
// Each of these escape sequences shall produce a unique implementation-defined value which can be stored in a single char object. The external representations in a text file need not be identical to the internal representations, and are outside the scope of this document.
// Forward references: the isprint function (7.4.1.8), the fputc function (7.23.7.3). 5.2.3 Signals and interrupts
// Functions shall be implemented such that they may be interrupted at any time by a signal, or may be called by a signal handler, or both, with no alteration to earlier, but still active, invocations’ control flow (after the interruption), function return values, or objects with automatic storage duration. All such objects shall be maintained outside the function image (the instructions that compose the executable representation of a function) on a per-invocation basis.
// 5.2.4 Environmental limits
// Both the translation and execution environments constrain the implementation of language trans- lators and libraries. The following summarizes the language-related environmental limits on a conforming implementation; the library-related limits are discussed in Clause 7.
// 5.2.4.1 Translation limits
// The implementation shall be able to translate and execute a program that uses but does not exceed the following limitations for these constructs and entities17):
// — 127 nesting levels of blocks
// — 63 nesting levels of conditional inclusion
// — 12 pointer, array, and function declarators (in any combinations) modifying an arithmetic, structure, union, or void type in a declaration
// — 63 nesting levels of parenthesized declarators within a full declarator
// — 63 nesting levels of parenthesized expressions within a full expression
// — 63 significant initial characters in an internal identifier or a macro name(each universal charac- ter name or extended source character is considered a single character)
// — 31 significant initial characters in an external identifier (each universal character name specify- ing a short identifier of 0000FFFF or less is considered 6 characters, each universal character name specifying a short identifier of 00010000 or more is considered 10 characters, and each extended source character is considered the same number of characters as the corresponding universal character name, if any)18)
// 17)Implementations are encouraged to avoid imposing fixed translation limits whenever possible. 18)See "future language directions" (6.11.3).
// — 4095 external identifiers in one translation unit
// — 511 identifiers with block scope declared in one block
// — 4095 macro identifiers simultaneously defined in one preprocessing translation unit
// — 127 parameters in one function definition
// — 127 arguments in one function call
// — 127 parameters in one macro definition
// — 127 arguments in one macro invocation
// — 4095 characters in a logical source line
// — 4095 characters in a string literal (after concatenation)
// — 32767 bytes in an object (in a hosted environment only)
// — 15 nesting levels for #included files
// — 1023 case labels for a switch statement (excluding those for any nested switch statements) — 1023 members in a single structure or union
// — 1023 enumeration constants in a single enumeration
// — 63 levels of nested structure or union definitions in a single member declaration list
// 5.2.4.2 Numerical limits
// An implementation is required to document all the limits specified in this subclause, which are specified in the headers <limits.h> and <float.h>. Additional limits are specified in <stdint.h>.
// Forward references: integer types <stdint.h> (7.22). 5.2.4.2.1 Characteristics of integer types <limits.h>
// The values given below shall be replaced by constant expressions suitable for use in conditional expression inclusion preprocessing directives. Their implementation-defined values shall be equal or greater to those shown.
// — width for an object of type bool19) BOOL_WIDTH 1
// — number of bits for smallest object that is not a bit-field (byte) CHAR_BIT 8
// The macros CHAR_WIDTH, SCHAR_WIDTH, and UCHAR_WIDTH that represent the width of the typeschar,signed charandunsigned charshallexpandtothesamevalueasCHAR_BIT.
// — width for an object of type unsigned short int USHRT_WIDTH 16
// ThemacroSHRT_WIDTHrepresentsthewidthofthetypeshort intandshallexpandtothe same value as USHRT_WIDTH.
// — width for an object of type unsigned int 19)This value is exact.
// UINT_WIDTH 16
// The macro INT_WIDTH represents the width of the type int and shall expand to the same value as UINT_WIDTH.
// — width for an object of type unsigned long int ULONG_WIDTH 32
// The macro LONG_WIDTH represents the width of the type long int and shall expand to the same value as ULONG_WIDTH.
// — width for an object of type unsigned long long int ULLONG_WIDTH 64
// ThemacroLLONG_WIDTHrepresentsthewidthofthetypelong long intandshallexpandto the same value as ULLONG_WIDTH.
// — maximum width for an object of type _BitInt or unsigned _BitInt BITINT_MAXWIDTH /* see below */
// The macro BITINT_MAXWIDTH represents the maximum width N supported by the declaration of a bit-precise integer (6.2.5) in the type specifier _BitInt(N). The value BITINT_MAXWIDTH shall expand to a value that is greater than or equal to the value of ULLONG_WIDTH.
// — maximum number of bytes in a multibyte character, for any supported locale MB_LEN_MAX 1
// For all unsigned integer types for which <limits.h> or <stdint.h> define a macro with suffix _WIDTH holding its width N , there is a macro with suffix _MAX holding the maximal value 2N − 1 that is representable by the type and that has the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. If the value is in the range of the type uintmax_t (7.22.1.5) the macro is suitable for use in conditional expression inclusion preprocessing directives.
// For all signed integer types for which <limits.h> or <stdint.h> define a macro with suffix _WIDTH holding its width N , there are macros with suffix _MIN and _MAX holding the minimal and maximal values −2N−1 and 2N−1 − 1 that are representable by the type and that have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions. If the values are in the range of the type intmax_t (7.22.1.5) the macros are suitable for use in conditional expression inclusion preprocessing directives.
// If an object of type char can hold negative values, the value of CHAR_MIN shall be the same as that of SCHAR_MIN and the value of CHAR_MAX shall be the same as that of SCHAR_MAX. Otherwise, the value of CHAR_MIN shall be 0 and the value of CHAR_MAX shall be the same as that of UCHAR_MAX.20)
// Forward references: representations of types (6.2.6), conditional inclusion (6.10.1), integer types <stdint.h> (7.22).
// 5.2.4.2.2 Characteristics of floating types <float.h>
// The characteristics of floating types are defined in terms of a model that describes a repre- sentation of floating-point numbers and allows other values. The characteristics provide in- formation about an implementation’s floating-point arithmetic.21) An implementation that de-
// 20)See 6.2.5.
// 21)The floating-point model is intended to clarify the description of each floating-point characteristic and does not require the floating-point arithmetic of the implementation to be identical.
// Environment fines __STDC_IEC_60559_BFP__ or __STDC_IEC_559__ shall implement floating types and arith- metic conforming to IEC 60559 as specified in Annex F. An implementation that defines __STDC_IEC_60559_COMPLEX__ or __STDC_IEC_559_COMPLEX__ shall implement complex types and arithmetic conforming to IEC 60559 as specified in Annex G.
// The following parameters are used to define the model for each floating type:
// s sign (±1)
// b base or radix of exponent representation (an integer > 1)
// e exponent (an integer between a minimum emin and a maximum emax) p precision (the number of base-b digits in the significand)
// fk nonnegative integers less than b (the significand digits)
// For each floating type, the parameters b, p, emin, and emax are fixed constants.
// For each floating type, a floating-point number (x) is defined by the following model: p x=sbefkb−k, emin≤e≤emax k=1
// Model floating-point numbers x with f1 > 0 are called normalized floating-point numbers.
// Model floating-point numbers x ̸= 0 with f1 = 0 and e = emin are called subnormal floating-point numbers.
// Model floating-point numbers x ̸= 0 with f1 = 0 and e > emin are called unnormalized floating-point numbers.
// Model floating-point numbers x with all fk = 0 are zeros.
// Floating types shall be able to represent signed zeros or an unsigned zero and all normalized floating- point numbers. In addition, floating types may be able to contain other kinds of floating-point numbers22), such as subnormal floating-point numbers and unnormalized floating-point numbers, and values that are not floating-point numbers, such as NaNs and (signed and unsigned) infinities. A NaN is a value signifying Not-a-Number. A quiet NaN propagates through almost every arithmetic operation without raising a floating-point exception; a signaling NaN generally raises a floating-point exception when occurring as an arithmetic operand23).
// Wherever values are unsigned, any requirement in this document to get the sign shall produce an unspecified sign, and any requirement to set the sign shall be ignored, unless otherwise specified.24)
// Whether and in what cases subnormal numbers are treated as zeros is implementation-defined. Subnormal numbers that in some cases are treated by arithmetic operations as zeros are properly classified as subnormal. However, object representations that could represent subnormal numbers but that are always treated by arithmetic operations as zeros are non-canonical zeros, and the values are properly classified as zero, not subnormal. IEC 60559 arithmetic (with default exception handling) always treats subnormal numbers as nonzero.
// A value is negative if and only if it compares less than 0. Thus, negative zeros and NaNs are not negative values.
// An implementation may prefer particular representations of values that have multiple representa- tions in a floating type, 6.2.6.1 not withstanding.25) The preferred representations of a floating type, including unique representations of values in the type, are called canonical. A floating type may also contain non-canonical representations, for example, redundant representations of some or all its values, or representations that are extraneous to the floating-point model.26) Typically, floating-point
// 22)Some implementations have types that include finite numbers with range and/or precision that are not covered by the model.
// 23)IEC 60559 specifies quiet and signaling NaNs. For implementations that do not support IEC 60559, the terms quiet NaN and signaling NaN are intended to apply to values with similar behavior.
// 24)Bit representations of floating-point values might include a sign bit, even if the values can be regarded as unsigned. IEC 60559 NaNs are such values.
// 25)The library operations iscanonical and canonicalize distinguish canonical (preferred) representations, but this distinction alone does not imply that canonical and non-canonical representations are of different values.
// 26)Some of the values in the IEC 60559 decimal formats have non-canonical representations (as well as a canonical representation).
// operations deliver results with canonical representations. IEC 60559 operations deliver results with canonical representations, unless specified otherwise.
// The minimum range of representable values for a floating type is the most negative finite floating- point number representable in that type through the most positive finite floating-point number representable in that type. In addition, if negative infinity is representable in a type, the range of that type is extended to all negative real numbers; likewise, if positive infinity is representable in a type, the range of that type is extended to all positive real numbers.
// The accuracy of the floating-point operations (+, −, *, /) and of most of the library functions in <math.h> and <complex.h> that return floating-point results is implementation-defined, as is the accuracy of the conversion between floating-point internal representations and string representations
// performed by the library functions in <stdio.h>, <stdlib.h>, and <wchar.h>. The implemen- tation may state that the accuracy is unknown. Decimal floating-point operations have stricter requirements.
// All integer values in the <float.h> header, except FLT_ROUNDS, shall be constant expressions suitable for use in conditional expression inclusion preprocessing directives; all floating values shall be constant expressions. All except CR_DECIMAL_DIG (F.5), DECIMAL_DIG, DEC_EVAL_METHOD , FLT_EVAL_METHOD, FLT_RADIX, and FLT_ROUNDS have separate names for all floating types. The floating-point model representation is provided for all values except DEC_EVAL_METHOD, FLT_EVAL_METHOD and FLT_ROUNDS.
// The remainder of this subclause specifies characteristics of standard floating types.
// The rounding mode for floating-point addition for standard floating types is characterized by the implementation-defined value of FLT_ROUNDS. Evaluation of FLT_ROUNDS correctly reflects any execution-time change of rounding mode through the function fesetround in <fenv.h>.
// −1 indeterminable
// 0 toward zero
// 1 to nearest, ties to even
// 2 toward positive infinity
// 3 toward negative infinity
// 4 to nearest, ties away from zero
// All other values for FLT_ROUNDS characterize implementation-defined rounding behavior.
// Whether a type matches an IEC 60559 format (and perhaps, operations) is characterized by the implementation-defined values of FLT_IS_IEC_60559, DBL_IS_IEC_60559, and LDBL_IS_IEC_60559 (this does not imply conformance to Annex F):
// 0 type does not match an IEC 60559 format
// 1 type matches an IEC 60559 format
// 2 type matches an IEC 60559 format and operations
// The values of floating type yielded by operators subject to the usual arithmetic conversions, including the values yielded by the implicit conversion of operands, and the values of floating constants are evaluated to a format whose range and precision may be greater than required by the type. Such a format is called an evaluation format. In all cases, assignment and cast operators yield values in the format of the type. The extent to which evaluation formats are used is characterized by the value of FLT_EVAL_METHOD:27)
// 27)The evaluation method determines evaluation formats of expressions involving all floating types, not just real types. For example, if FLT_EVAL_METHOD is 1, then the product of two float _Complex operands is represented in the double _Complex format, and its parts are evaluated to double.
// −1 indeterminable;
// 0 evaluate all operations and constants just to the range and precision of the type;
// evaluate operations and constants of type float and double to the range and precision of thedoubletype,evaluatelong doubleoperationsandconstantstotherangeandprecision ofthelong doubletype;
// evaluate all operations and constants to the range and precision of the long double type.
// All other negative values for FLT_EVAL_METHOD characterize implementation-defined behavior. The value of FLT_EVAL_METHOD does not characterize values returned by function calls (see 6.8.6.4, F.6). 20 The presence or absence of subnormal numbers is characterized by the implementation-defined values of FLT_HAS_SUBNORM, DBL_HAS_SUBNORM, and LDBL_HAS_SUBNORM:
// −1 indeterminable
// 0 absent (type does not support subnormal numbers)
// 1 present (type does support subnormal numbers)
// The use of FLT_HAS_SUBNORM, DBL_HAS_SUBNORM, and LDBL_HAS_SUBNORM macros is an obsolescent feature.
// Each of the signaling NaN macros is defined if and only if the respective type contains signaling NaNs. They expand to a constant expression of the respective type representing a signaling NaN. If an optional unary + or − operator followed by a signaling NaN macro is used as the initializer for initializing an object of the same type that has static or thread storage duration, the object is initialized with a signaling NaN value.
// The macro INFINITY is defined if and only if the implementation supports an infinity for the type float. It expands to a constant expression of type float representing positive or unsigned infinity.
// The macro NAN is defined if and only if the implementation supports quiet NaNs for the float type. It expands to a constant expression of type float representing a quiet NaN.
// The values given in the following list shall be replaced by constant expressions with implementation- defined values that are greater or equal in magnitude (absolute value) to those shown, with the same sign:
// — radix of exponent representation, b FLT_RADIX 2
// — number of base-FLT_RADIX digits in the floating-point significand, p
// FLT_SNAN
// DBL_SNAN
// LDBL_SNAN
// FLT_MANT_DIG
// DBL_MANT_DIG
// LDBL_MANT_DIG
// — number of decimal digits, n, such that any floating-point number with p radix b digits can be rounded to a floating-point number with n decimal digits and back again without change to the value, plog10 b ifbisapowerof10 ⌈1 + p log10 b⌉ otherwise
// — numberofdecimaldigits,n,suchthatanyfloating-pointnumberinthewidestofthesupported floating types and the supported IEC 60559 encodings with pmax radix b digits can be rounded to a floating-point number with n decimal digits and back again without change to the value,
// FLT_DECIMAL_DIG 6 DBL_DECIMAL_DIG 10 LDBL_DECIMAL_DIG 10
// pmax log10 b
// ⌈1 + pmax log10 b⌉
// DECIMAL_DIG
// ifbisapowerof10 otherwise
// This is an obsolescent feature, see 7.33.8.
// — number of decimal digits, q, such that any floating-point number with q decimal digits can be rounded into a floating-point number with p radix b digits and back again without change to the q decimal digits, plog10 b ifbisapowerof10 ⌊(p − 1) log10 b⌋ otherwise
// — minimum negative integer such that FLT_RADIX raised to one less than that power is a normal- ized floating-point number, emin
// — minimum negative integer such that 10 raised to that power is in the range of normalized floating-point numbers, log10bemin−1
// — maximum integer such that FLT_RADIX raised to one less than that power is a representable finite floating-point number; if that representable finite floating-point number is normalized, the value of the macro is emax
// FLT_DIG 6 DBL_DIG 10 LDBL_DIG 10
// FLT_MIN_EXP
// DBL_MIN_EXP
// LDBL_MIN_EXP
// FLT_MIN_10_EXP -37 DBL_MIN_10_EXP -37 LDBL_MIN_10_EXP -37
// FLT_MAX_EXP
// DBL_MAX_EXP
// LDBL_MAX_EXP — maximum integer such that 10 raised to that power is in the range of representable finite floating-point numbers, ⌊log10((1 − b−p)bemax )⌋
// The values given in the following list shall be replaced by constant expressions with implementation- defined values that are greater than or equal to those shown:
// — maximum representable finite floating-point number; if that number is normalized, its value is (1 − b−p)bemax — maximum normalized floating-point number, (1 − b−p)bemax
// The values given in the following list shall be replaced by constant expressions with implementation- defined (positive) values that are less than or equal to those shown:
// — the difference between 1 and the least normalized value greater than 1 that is representable in the given floating type, b1−p
// — minimum normalized positive floating-point number, bemin−1
// — minimum positive floating-point number28)
// 28)If the presence or absence of subnormal numbers is indeterminable, then the value is intended to be a positive number no greater than the minimum normalized positive number for the type.
// FLT_MAX_10_EXP +37 DBL_MAX_10_EXP +37 LDBL_MAX_10_EXP +37
// FLT_MAX
// DBL_MAX
// LDBL_MAX
// 1E+37
// 1E+37
// 1E+37
// FLT_NORM_MAX
// DBL_NORM_MAX
// LDBL_NORM_MAX
// 1E+37
// 1E+37
// 1E+37
// FLT_EPSILON 1E-5 DBL_EPSILON 1E-9 LDBL_EPSILON 1E-9
// FLT_MIN
// DBL_MIN
// LDBL_MIN
// 1E-37
// 1E-37
// 1E-37
// FLT_TRUE_MIN
// DBL_TRUE_MIN
// LDBL_TRUE_MIN
// 1E-37
// 1E-37
// 1E-37
// Conversion between real floating type and decimal character sequence with at most T_DECIMAL_DIG digits should be correctly rounded, where T is the macro prefix for the type. This assures conversion from real floating type to decimal character sequence with T_DECIMAL_DIG digits and back, using to-nearest rounding, is the identity function.
// EXAMPLE 1 The following describes an artificial floating-point representation that meets the minimum requirements of this document, and the appropriate values in a <float.h> header for type float: x=s16e fk16−k, −31≤e≤+32 k=1
// FLT_RADIX 16 FLT_MANT_DIG 6 FLT_EPSILON 9.53674316E-07F FLT_DECIMAL_DIG 9 FLT_DIG 6 FLT_MIN_EXP -31 FLT_MIN 2.93873588E-39F FLT_MIN_10_EXP -38 FLT_MAX_EXP +32 FLT_MAX 3.40282347E+38F FLT_MAX_10_EXP +38
// EXAMPLE 2 The following describes floating-point representations that also meet the requirements for single-precision and double-precision numbers in IEC 60559,29) and the appropriate values in a <float.h> header for types float and double:
// xf =s2e fk2−k, k=1
// xd =s2e fk2−k, k=1
// FLT_IS_IEC_60559
// FLT_RADIX
// FLT_MANT_DIG
// FLT_EPSILON
// FLT_EPSILON
// FLT_DECIMAL_DIG
// FLT_DIG
// FLT_MIN_EXP
// FLT_MIN
// FLT_MIN
// FLT_TRUE_MIN
// FLT_TRUE_MIN
// FLT_HAS_SUBNORM
// FLT_MIN_10_EXP
// FLT_MAX_EXP
// FLT_MAX
// FLT_MAX
// FLT_MAX_10_EXP
// DBL_MANT_DIG
// DBL_IS_IEC_60559
// DBL_EPSILON 2.2204460492503131E-16 // decimal constant DBL_EPSILON 0X1P-52 // hex constant
// 29)The floating-point model in that standard sums powers of b from zero, so the values of the exponent limits are one less than shown here. −125≤e≤+128 −1021≤e≤+1024 2
// 1.19209290E-07F // decimal constant 0X1P-23F // hex constant
// 6 -125
// 1.17549435E-38F // decimal constant 0X1P-126F // hex constant
// 1.40129846E-45F // decimal constant 0X1P-149F // hex constant 1 -37 +128
// 3.40282347E+38F // decimal constant 0X1.fffffeP127F // hex constant +38 53 2
// DBL_DECIMAL_DIG 17
// DBL_DIG
// DBL_MIN_EXP
// DBL_MIN
// DBL_MIN
// DBL_TRUE_MIN 4.9406564584124654E-324 // decimal constant
// 15 -1021
// 2.2250738585072014E-308 // decimal constant 0X1P-1022 // hex constant
// DBL_TRUE_MIN
// DBL_HAS_SUBNORM
// DBL_MIN_10_EXP
// DBL_MAX_EXP
// DBL_MAX
// 0X1P-1074 // hex constant 1
// -307 +1024
// 1.7976931348623157E+308 // decimal constant 0X1.fffffffffffffP1023 // hex constant
// DBL_MAX
// DBL_MAX_10_EXP +308
// Forward references: conditional inclusion (6.10.1), predefined macro names (6.10.9), complex arith- metic <complex.h> (7.3), extended multibyte and wide character utilities <wchar.h> (7.31), floating- point environment <fenv.h> (7.6), general utilities <stdlib.h> (7.24), input/output <stdio.h> (7.23), mathematics <math.h> (7.12), IEC 60559 floating-point arithmetic (Annex F), IEC 60559- compatible complex arithmetic (Annex G).
// 5.2.4.2.3 Characteristics of decimal floating types in <float.h>
// This subclause specifies macros in <float.h> that provide characteristics of decimal floating types (an optional feature) in terms of the model presented in 5.2.4.2.2. An implementation shall provide these macros if and only if defines __STDC_IEC_60559_DFP__. The prefixes DEC32_, DEC64_, and DEC128_ denote the types _Decimal32, _Decimal64, and _Decimal128 respectively.
// DEC_EVAL_METHOD is the decimal floating-point analog of FLT_EVAL_METHOD (5.2.4.2.2). Its implementation-defined value characterizes the use of evaluation formats for decimal floating types: −1 indeterminable;
// evaluate all operations and constants just to the range and precision of the type;
// evaluate operations and constants of type _Decimal32 and _Decimal64 to the range and precision of the _Decimal64 type, evaluate _Decimal128 operations and constants to the range and precision of the _Decimal128 type;
// evaluate all operations and constants to the range and precision of the _Decimal128 type.
// Each of the decimal signaling NaN macros
// expands to a constant expression of the respective decimal floating type representing a signaling NaN. If an optional unary + or − operator followed by a signaling NaN macro is used for initializing an object of the same type that has static or thread storage duration, the object is initialized with a signaling NaN value.
// The macro DEC_INFINITY
// expands to a constant expression of type _Decimal32 representing positive infinity.
// The macro
// DEC_NAN
// DEC32_SNAN
// DEC64_SNAN
// DEC128_SNAN
// expands to a constant expression of type _Decimal32 representing a quiet NaN.
// The integer values given in the following lists shall be replaced by constant expressions suitable for use in conditional expression inclusion preprocessing directives:
// — radix of exponent representation, b(=10)
// For the standard floating types, this value is implementation-defined and is specified by the macro FLT_RADIX. For the decimal floating types there is no corresponding macro, since the value 10 is an inherent property of the types. Wherever FLT_RADIX appears in a description of a function that has versions that operate on decimal floating types, it is noted that for the decimal floating-point versions the value used is implicitly 10, rather than // FLT_RADIX.
// — number of digits in the coefficient
// — minimum exponent
// — maximum exponent
// — maximum representable finite decimal floating-point number (there are 6, 15 and 33 9’s after the decimal points respectively)
// — the difference between 1 and the least value greater than 1 that is representable in the given floating type
// — minimum normalized positive decimal floating-point number
// — minimum positive subnormal decimal floating-point number
// DEC32_MANT_DIG 7 DEC64_MANT_DIG 16 DEC128_MANT_DIG 34
// DEC32_MIN_EXP -94 DEC64_MIN_EXP -382 DEC128_MIN_EXP -6142
// DEC32_MAX_EXP 97 DEC64_MAX_EXP 385 DEC128_MAX_EXP 6145
// DEC32_MAX
// DEC64_MAX
// DEC128_MAX
// 9.999999E96DF
// 9.999999999999999E384DD 9.999999999999999999999999999999999E6144DL
// DEC32_EPSILON
// DEC64_EPSILON
// DEC128_EPSILON
// 1E-6DF
// 1E-15DD
// 1E-33DL
// DEC32_MIN
// DEC64_MIN
// DEC128_MIN
// 1E-95DF
// 1E-383DD
// 1E-6143DL
// DEC32_TRUE_MIN
// DEC64_TRUE_MIN
// DEC128_TRUE_MIN
// 0.000001E-95DF
// 0.000000000000001E-383DD 0.000000000000000000000000000000001E-6143DL
// For decimal floating-point arithmetic, it is often convenient to consider an alternate equivalent model where the significand is represented with integer rather than fraction digits. With s, b, e, p, and fk as defined in 5.2.4.2.2, a floating-point number x is defined by the model:
// p x=s·b(e−p)fk ·b(p−k)
// k=1
// With b fixed to 10, a decimal floating-point number x is thus:
// p x=s·10(e−p)fk ·10(p−k)
// k=1
// The quantum exponent is q = e − p and the coefficient is c = f1f2 · · · fp, which is an integer between 0 and 10(p−1), inclusive. Thus, x = s · c · 10q is represented by the triple of integers (s, c, q). The quantum of x is 10q , which is the value of a unit in the last place of the coefficient. Quantum exponent ranges
// For binary floating-point arithmetic following IEC 60559, representations in the model described in 5.2.4.2.2 that have the same numerical value are indistinguishable in the arithmetic. However, for decimal floating-point arithmetic, representations that have the same numerical value but different quantum exponents, e.g., (+1,10,−1) representing 1.0 and (+1,100,−2) representing 1.00, are distinguishable. To facilitate exact fixed-point calculation, operation results that are of decimal floating type have a preferred quantum exponent, as specified in IEC 60559, which is determined by the quantum exponents of the operands if they have decimal floating types (or by specific rules for conversions from other types). The table below gives rules for determining preferred quantum exponents for results of IEC 60559 operations, and for other operations specified in this document. When exact, these operations produce a result with their preferred quantum exponent, or as close to it as possible within the limitations of the type. When inexact, these operations produce a result with the least possible quantum exponent. For example, the preferred quantum exponent for addition is the minimum of the quantum exponents of the operands. Hence (+1, 123, −2) + (+1, 4000, −3) = (+1, 5230, −3) or 1.23 + 4.000 = 5.230.
// The following table shows, for each operation delivering a result in decimal floating-point format, how the preferred quantum exponents of the operands, Q(x), Q(y), etc., determine the preferred quantum exponent of the operation result, provided the table formula is defined for the arguments. For the cases where the formula is undefined and the function result is ±∞, the preferred quantum exponent is immaterial because the quantum exponent of ±∞ is defined to be infinity. For the other cases where the formula is undefined and the function result is finite, the preferred quantum exponent is unspecified.30)
// Preferred quantum exponents
// 30)Although unspecified in IEC 60559, a preferred quantum exponent of 0 for these cases would be a reasonable implemen- tation choice.
// Type
// _Decimal32
// _Decimal64
// _Decimal128
// Maximum Quantum Exponent (qmax)
// 90
// 369
// 6111
// Minimum Quantum Exponent (qmin)
// −101
// −398
// −6176
// Operation
// Preferred quantum exponent of result
// roundeven, round, trunc, ceil, floor, rint, nearbyint
// max(Q(x), 0)
// nextup, nextdown, nextafter, nexttoward
// least possible
// remainder
// min(Q(x), Q(y))
// fmin, fmax, fminimum, fmaximum, fminimum_mag, fmaximum_mag, fminimum_num, fmaximum_num, fminimum_mag_num, fmaximum_mag_num
// Q(x) if x gives the result, Q(y) if y gives the result
// scalbn, scalbln
// Q(x)+n
// ldexp
// Q(x)+p
// logb
// 0
// postfix ++ operator, postfix -- operator, prefix ++ operator, prefix -- operator
// min(Q(x), 0)
// +, d32add, d64add
// min(Q(x), Q(y))
// −, d32sub, d64sub
// min(Q(x), Q(y))
// *, d32mul, d64mul
// Q(x) + Q(y)
// /, d32div, d64div
// Q(x) − Q(y)
// sqrt, d32sqrt, d64sqrt
// ⌊Q(x)/2⌋
// fma, d32fma, d64fma
// min(Q(x) + Q(y), Q(z))
// conversion from integer type
// 0
// exact conversion from non-decimal floating type
// 0
// inexact conversion from non-decimal floating type
// least possible
// conversion between decimal floating types
// Q(x)
// *cx returned by canonicalize
// Q(*x)
// strto, wcsto, scanf, floating constants of decimal floating type see 7.24.1.6
// -(x), +(x)
// Q(x)
// fabs
// Q(x)
// copysign
// Q(x)
// quantize
// Q(y)
// quantum
// Q(x)
// *encptr returned by encodedec, encodebin
// Q(*xptr)
// *xptr returned by decodedec, decodebin
// Q(*encptr)
// fmod
// min(Q(x), Q(y))
// fdim
// min((Q(x), Q(y)) if x > y, 0 if x ≤ y
// cbrt
// ⌊Q(x)/3⌋
// hypot
// min(Q(x), Q(y))
// pow
// ⌊y × Q(x)⌋
// modf
// Q(value)
// *iptr returned by modf
// max(Q(value), 0)
// frexp
// Q(value) if value = 0, –(length of coefficient of value) otherwise
// *res returned by setpayload, setpayloadsig
// 0 if pl does not represent a valid payload, not applicable otherwise (NaN returned)
// getpayload
// 0 if *x is a NaN, unspecified otherwise
// compoundn
// ⌊n × min(0, Q(x))⌋
// pown
// ⌊n × Q(x)⌋
// powr
// ⌊y × Q(x)⌋
// rootn
// ⌊Q(x)/n⌋
// rsqrt
// −⌊Q(x)/2⌋
// transcendental functions
// 0
// A function family listed in the table above indicates the functions for all decimal floating types, where the function family is represented by the name of the functions without a suffix. For example, ceil indicates the functions ceild32, ceild64, and ceild128.
// Forward references: extended multibyte and wide character utilities <wchar.h> (7.31), floating- point environment <fenv.h> (7.6), general utilities <stdlib.h> (7.24), input/output <stdio.h> (7.23), mathematics <math.h> (7.12), type-generic mathematics <tgmath.h> (7.27), IEC 60559 floating-point arithmetic (Annex F).
int main() {
main2();
main3();
printf("%s\n", n3540);
return EXIT_SUCCESS;
}
編纂・実行結果(compile and go)
$ clang p10.c -std=11 -o p10l -I. -Wall
p10.c:44:22: error: redefinition of 'i' with a different type: 'int' vs 'char'
char i; int i;
^
p10.c:44:15: note: previous definition is here
char i; int i;
^
p10.c:91:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
c1 = c1 + c2;
^
p10.c:91:1: error: redefinition of 'c1' with a different type: 'int' vs 'char'
p10.c:90:14: note: previous definition is here
char c1, c2; /* ... */
^
p10.c:94:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
f1 = f2 * d;
^
p10.c:94:1: error: redefinition of 'f1' with a different type: 'int' vs 'float'
p10.c:92:25: note: previous definition is here
float f1, f2; double d;
^
p10.c:97:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
d1 = f = expression;
^
p10.c:97:1: error: redefinition of 'd1' with a different type: 'int' vs 'double'
p10.c:95:29: note: previous definition is here
double d1, d2;
^
p10.c:97:10: error: use of undeclared identifier 'expression'
d1 = f = expression;
^
p10.c:98:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
d2 = (float) expression;
^
p10.c:98:1: error: redefinition of 'd2' with a different type: 'int' vs 'double'
p10.c:95:33: note: previous definition is here
double d1, d2;
^
p10.c:98:14: error: use of undeclared identifier 'expression'
d2 = (float) expression;
^
p10.c:101:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
x=(x*y)*z; //notequivalentto
^
p10.c:101:1: error: redefinition of 'x' with a different type: 'int' vs 'double'
p10.c:99:29: note: previous definition is here
double x, y, z;
^
p10.c:102:1: error: unknown type name 'x'
x*=y*z; z=(x-y)+y; //notequivalentto
^
p10.c:102:2: error: expected identifier or '('
x*=y*z; z=(x-y)+y; //notequivalentto
^
p10.c:102:9: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
x*=y*z; z=(x-y)+y; //notequivalentto
^
p10.c:102:9: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:103:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z=x;
^
p10.c:103:1: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:104:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z = x + x * y; // not equivalent to
^
p10.c:104:1: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:105:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z = x * (1.0 + y); y = x / 5.0; // not equivalent to
^
p10.c:105:1: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:105:20: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z = x * (1.0 + y); y = x / 5.0; // not equivalent to
^
p10.c:105:20: error: redefinition of 'y' with a different type: 'int' vs 'double'
p10.c:99:32: note: previous definition is here
double x, y, z;
^
p10.c:106:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
y = x * 0.2;
^
p10.c:106:1: error: redefinition of 'y' with a different type: 'int' vs 'double'
p10.c:99:32: note: previous definition is here
double x, y, z;
^
p10.c:109:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = a + 32760 + b + 5;
^
p10.c:109:19: error: initializer element is not a compile-time constant
a = a + 32760 + b + 5;
~~~~~~~~~~~~~~^~~
p10.c:110:17: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = (((a + 32760) + b) + 5);
^
p10.c:110:17: error: redefinition of 'a'
p10.c:109:1: note: previous definition is here
a = a + 32760 + b + 5;
^
p10.c:112:8: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = ((a + b) + 32765);
^
p10.c:112:8: error: redefinition of 'a'
p10.c:109:1: note: previous definition is here
a = a + 32760 + b + 5;
^
p10.c:114:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = ((a + 32765) + b);
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
15 warnings and 20 errors generated.
$ clang p10.c -std=17 -o p10l -I. -Wall
p10.c:44:22: error: redefinition of 'i' with a different type: 'int' vs 'char'
char i; int i;
^
p10.c:44:15: note: previous definition is here
char i; int i;
^
p10.c:91:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
c1 = c1 + c2;
^
p10.c:91:1: error: redefinition of 'c1' with a different type: 'int' vs 'char'
p10.c:90:14: note: previous definition is here
char c1, c2; /* ... */
^
p10.c:94:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
f1 = f2 * d;
^
p10.c:94:1: error: redefinition of 'f1' with a different type: 'int' vs 'float'
p10.c:92:25: note: previous definition is here
float f1, f2; double d;
^
p10.c:97:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
d1 = f = expression;
^
p10.c:97:1: error: redefinition of 'd1' with a different type: 'int' vs 'double'
p10.c:95:29: note: previous definition is here
double d1, d2;
^
p10.c:97:10: error: use of undeclared identifier 'expression'
d1 = f = expression;
^
p10.c:98:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
d2 = (float) expression;
^
p10.c:98:1: error: redefinition of 'd2' with a different type: 'int' vs 'double'
p10.c:95:33: note: previous definition is here
double d1, d2;
^
p10.c:98:14: error: use of undeclared identifier 'expression'
d2 = (float) expression;
^
p10.c:101:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
x=(x*y)*z; //notequivalentto
^
p10.c:101:1: error: redefinition of 'x' with a different type: 'int' vs 'double'
p10.c:99:29: note: previous definition is here
double x, y, z;
^
p10.c:102:1: error: unknown type name 'x'
x*=y*z; z=(x-y)+y; //notequivalentto
^
p10.c:102:2: error: expected identifier or '('
x*=y*z; z=(x-y)+y; //notequivalentto
^
p10.c:102:9: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
x*=y*z; z=(x-y)+y; //notequivalentto
^
p10.c:102:9: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:103:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z=x;
^
p10.c:103:1: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:104:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z = x + x * y; // not equivalent to
^
p10.c:104:1: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:105:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z = x * (1.0 + y); y = x / 5.0; // not equivalent to
^
p10.c:105:1: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:105:20: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z = x * (1.0 + y); y = x / 5.0; // not equivalent to
^
p10.c:105:20: error: redefinition of 'y' with a different type: 'int' vs 'double'
p10.c:99:32: note: previous definition is here
double x, y, z;
^
p10.c:106:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
y = x * 0.2;
^
p10.c:106:1: error: redefinition of 'y' with a different type: 'int' vs 'double'
p10.c:99:32: note: previous definition is here
double x, y, z;
^
p10.c:109:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = a + 32760 + b + 5;
^
p10.c:109:19: error: initializer element is not a compile-time constant
a = a + 32760 + b + 5;
~~~~~~~~~~~~~~^~~
p10.c:110:17: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = (((a + 32760) + b) + 5);
^
p10.c:110:17: error: redefinition of 'a'
p10.c:109:1: note: previous definition is here
a = a + 32760 + b + 5;
^
p10.c:112:8: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = ((a + b) + 32765);
^
p10.c:112:8: error: redefinition of 'a'
p10.c:109:1: note: previous definition is here
a = a + 32760 + b + 5;
^
p10.c:114:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = ((a + 32765) + b);
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
15 warnings and 20 errors generated.
$ clang p10.c -std=2x -o p10l -I. -Wall
p10.c:44:22: error: redefinition of 'i' with a different type: 'int' vs 'char'
char i; int i;
^
p10.c:44:15: note: previous definition is here
char i; int i;
^
p10.c:91:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
c1 = c1 + c2;
^
p10.c:91:1: error: redefinition of 'c1' with a different type: 'int' vs 'char'
p10.c:90:14: note: previous definition is here
char c1, c2; /* ... */
^
p10.c:94:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
f1 = f2 * d;
^
p10.c:94:1: error: redefinition of 'f1' with a different type: 'int' vs 'float'
p10.c:92:25: note: previous definition is here
float f1, f2; double d;
^
p10.c:97:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
d1 = f = expression;
^
p10.c:97:1: error: redefinition of 'd1' with a different type: 'int' vs 'double'
p10.c:95:29: note: previous definition is here
double d1, d2;
^
p10.c:97:10: error: use of undeclared identifier 'expression'
d1 = f = expression;
^
p10.c:98:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
d2 = (float) expression;
^
p10.c:98:1: error: redefinition of 'd2' with a different type: 'int' vs 'double'
p10.c:95:33: note: previous definition is here
double d1, d2;
^
p10.c:98:14: error: use of undeclared identifier 'expression'
d2 = (float) expression;
^
p10.c:101:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
x=(x*y)*z; //notequivalentto
^
p10.c:101:1: error: redefinition of 'x' with a different type: 'int' vs 'double'
p10.c:99:29: note: previous definition is here
double x, y, z;
^
p10.c:102:1: error: unknown type name 'x'
x*=y*z; z=(x-y)+y; //notequivalentto
^
p10.c:102:2: error: expected identifier or '('
x*=y*z; z=(x-y)+y; //notequivalentto
^
p10.c:102:9: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
x*=y*z; z=(x-y)+y; //notequivalentto
^
p10.c:102:9: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:103:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z=x;
^
p10.c:103:1: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:104:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z = x + x * y; // not equivalent to
^
p10.c:104:1: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:105:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z = x * (1.0 + y); y = x / 5.0; // not equivalent to
^
p10.c:105:1: error: redefinition of 'z' with a different type: 'int' vs 'double'
p10.c:99:35: note: previous definition is here
double x, y, z;
^
p10.c:105:20: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
z = x * (1.0 + y); y = x / 5.0; // not equivalent to
^
p10.c:105:20: error: redefinition of 'y' with a different type: 'int' vs 'double'
p10.c:99:32: note: previous definition is here
double x, y, z;
^
p10.c:106:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
y = x * 0.2;
^
p10.c:106:1: error: redefinition of 'y' with a different type: 'int' vs 'double'
p10.c:99:32: note: previous definition is here
double x, y, z;
^
p10.c:109:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = a + 32760 + b + 5;
^
p10.c:109:19: error: initializer element is not a compile-time constant
a = a + 32760 + b + 5;
~~~~~~~~~~~~~~^~~
p10.c:110:17: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = (((a + 32760) + b) + 5);
^
p10.c:110:17: error: redefinition of 'a'
p10.c:109:1: note: previous definition is here
a = a + 32760 + b + 5;
^
p10.c:112:8: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = ((a + b) + 32765);
^
p10.c:112:8: error: redefinition of 'a'
p10.c:109:1: note: previous definition is here
a = a + 32760 + b + 5;
^
p10.c:114:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = ((a + 32765) + b);
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
15 warnings and 20 errors generated.
$ gcc p10.c -std=11 -o p10g -I. -Wall
p10.c:44:22: error: conflicting types for 'i'; have 'int'
44 | char i; int i;
| ^
p10.c:44:15: note: previous declaration of 'i' with type 'char'
44 | char i; int i;
| ^
p10.c:91:1: warning: data definition has no type or storage class
91 | c1 = c1 + c2;
| ^~
p10.c:91:1: warning: type defaults to 'int' in declaration of 'c1' [-Wimplicit-int]
p10.c:91:1: error: conflicting types for 'c1'; have 'int'
p10.c:90:14: note: previous declaration of 'c1' with type 'char'
90 | char c1, c2; /* ... */
| ^~
p10.c:91:6: error: initializer element is not constant
91 | c1 = c1 + c2;
| ^~
p10.c:94:1: warning: data definition has no type or storage class
94 | f1 = f2 * d;
| ^~
p10.c:94:1: warning: type defaults to 'int' in declaration of 'f1' [-Wimplicit-int]
p10.c:94:1: error: conflicting types for 'f1'; have 'int'
p10.c:92:25: note: previous declaration of 'f1' with type 'float'
92 | float f1, f2; double d;
| ^~
p10.c:97:1: warning: data definition has no type or storage class
97 | d1 = f = expression;
| ^~
p10.c:97:1: warning: type defaults to 'int' in declaration of 'd1' [-Wimplicit-int]
p10.c:97:1: error: conflicting types for 'd1'; have 'int'
p10.c:95:29: note: previous declaration of 'd1' with type 'double'
95 | double d1, d2;
| ^~
p10.c:97:10: error: 'expression' undeclared here (not in a function)
97 | d1 = f = expression;
| ^~~~~~~~~~
p10.c:98:1: warning: data definition has no type or storage class
98 | d2 = (float) expression;
| ^~
p10.c:98:1: warning: type defaults to 'int' in declaration of 'd2' [-Wimplicit-int]
p10.c:98:1: error: conflicting types for 'd2'; have 'int'
p10.c:95:33: note: previous declaration of 'd2' with type 'double'
95 | double d1, d2;
| ^~
p10.c:101:1: warning: data definition has no type or storage class
101 | x=(x*y)*z; //notequivalentto
| ^
p10.c:101:1: warning: type defaults to 'int' in declaration of 'x' [-Wimplicit-int]
p10.c:101:1: error: conflicting types for 'x'; have 'int'
p10.c:99:29: note: previous declaration of 'x' with type 'double'
99 | double x, y, z;
| ^
p10.c:102:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*=' token
102 | x*=y*z; z=(x-y)+y; //notequivalentto
| ^~
p10.c:102:9: warning: data definition has no type or storage class
102 | x*=y*z; z=(x-y)+y; //notequivalentto
| ^
p10.c:102:9: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:102:9: error: conflicting types for 'z'; have 'int'
p10.c:99:35: note: previous declaration of 'z' with type 'double'
99 | double x, y, z;
| ^
p10.c:103:1: warning: data definition has no type or storage class
103 | z=x;
| ^
p10.c:103:1: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:104:1: warning: data definition has no type or storage class
104 | z = x + x * y; // not equivalent to
| ^
p10.c:104:1: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:105:1: warning: data definition has no type or storage class
105 | z = x * (1.0 + y); y = x / 5.0; // not equivalent to
| ^
p10.c:105:1: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:105:20: warning: data definition has no type or storage class
105 | z = x * (1.0 + y); y = x / 5.0; // not equivalent to
| ^
p10.c:105:20: warning: type defaults to 'int' in declaration of 'y' [-Wimplicit-int]
p10.c:105:20: error: conflicting types for 'y'; have 'int'
p10.c:99:32: note: previous declaration of 'y' with type 'double'
99 | double x, y, z;
| ^
p10.c:106:1: warning: data definition has no type or storage class
106 | y = x * 0.2;
| ^
p10.c:106:1: warning: type defaults to 'int' in declaration of 'y' [-Wimplicit-int]
p10.c:109:1: warning: data definition has no type or storage class
109 | a = a + 32760 + b + 5;
| ^
p10.c:109:1: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:109:5: error: initializer element is not constant
109 | a = a + 32760 + b + 5;
| ^
p10.c:110:17: warning: data definition has no type or storage class
110 | a = (((a + 32760) + b) + 5);
| ^
p10.c:110:17: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:110:17: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:110:21: error: initializer element is not constant
110 | a = (((a + 32760) + b) + 5);
| ^
p10.c:112:8: warning: data definition has no type or storage class
112 | a = ((a + b) + 32765);
| ^
p10.c:112:8: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:112:8: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:112:12: error: initializer element is not constant
112 | a = ((a + b) + 32765);
| ^
p10.c:114:1: warning: data definition has no type or storage class
114 | a = ((a + 32765) + b);
| ^
p10.c:114:1: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:114:1: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:114:5: error: initializer element is not constant
114 | a = ((a + 32765) + b);
| ^
p10.c:115:1: warning: data definition has no type or storage class
115 | a = (a + (b + 32765));
| ^
p10.c:115:1: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:115:1: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:115:5: error: initializer element is not constant
115 | a = (a + (b + 32765));
| ^
p10.c:118:1: warning: data definition has no type or storage class
118 | sum = (((sum * 10) + ((*(p++)) = (getchar())));
| ^~~
p10.c:118:1: warning: type defaults to 'int' in declaration of 'sum' [-Wimplicit-int]
p10.c:118:27: error: 'p' undeclared here (not in a function)
118 | sum = (((sum * 10) + ((*(p++)) = (getchar())));
| ^
p10.c:118:48: error: expected ')' before ';' token
118 | sum = (((sum * 10) + ((*(p++)) = (getchar())));
| ~ ^
| )
p10.c: In function 'main2':
p10.c:47:29: warning: control reaches end of non-void function [-Wreturn-type]
47 | int main2(void) { /* ... */ }
| ^
p10.c: In function 'main3':
p10.c:49:47: warning: control reaches end of non-void function [-Wreturn-type]
49 | int main3(int argc, char *argv[]) { /* ... */ }
| ^
$ gcc p10.c -std=c17 -o p10g -I. -Wall
p10.c:44:22: error: conflicting types for 'i'; have 'int'
44 | char i; int i;
| ^
p10.c:44:15: note: previous declaration of 'i' with type 'char'
44 | char i; int i;
| ^
p10.c:91:1: warning: data definition has no type or storage class
91 | c1 = c1 + c2;
| ^~
p10.c:91:1: warning: type defaults to 'int' in declaration of 'c1' [-Wimplicit-int]
p10.c:91:1: error: conflicting types for 'c1'; have 'int'
p10.c:90:14: note: previous declaration of 'c1' with type 'char'
90 | char c1, c2; /* ... */
| ^~
p10.c:91:6: error: initializer element is not constant
91 | c1 = c1 + c2;
| ^~
p10.c:94:1: warning: data definition has no type or storage class
94 | f1 = f2 * d;
| ^~
p10.c:94:1: warning: type defaults to 'int' in declaration of 'f1' [-Wimplicit-int]
p10.c:94:1: error: conflicting types for 'f1'; have 'int'
p10.c:92:25: note: previous declaration of 'f1' with type 'float'
92 | float f1, f2; double d;
| ^~
p10.c:97:1: warning: data definition has no type or storage class
97 | d1 = f = expression;
| ^~
p10.c:97:1: warning: type defaults to 'int' in declaration of 'd1' [-Wimplicit-int]
p10.c:97:1: error: conflicting types for 'd1'; have 'int'
p10.c:95:29: note: previous declaration of 'd1' with type 'double'
95 | double d1, d2;
| ^~
p10.c:97:10: error: 'expression' undeclared here (not in a function)
97 | d1 = f = expression;
| ^~~~~~~~~~
p10.c:98:1: warning: data definition has no type or storage class
98 | d2 = (float) expression;
| ^~
p10.c:98:1: warning: type defaults to 'int' in declaration of 'd2' [-Wimplicit-int]
p10.c:98:1: error: conflicting types for 'd2'; have 'int'
p10.c:95:33: note: previous declaration of 'd2' with type 'double'
95 | double d1, d2;
| ^~
p10.c:101:1: warning: data definition has no type or storage class
101 | x=(x*y)*z; //notequivalentto
| ^
p10.c:101:1: warning: type defaults to 'int' in declaration of 'x' [-Wimplicit-int]
p10.c:101:1: error: conflicting types for 'x'; have 'int'
p10.c:99:29: note: previous declaration of 'x' with type 'double'
99 | double x, y, z;
| ^
p10.c:102:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*=' token
102 | x*=y*z; z=(x-y)+y; //notequivalentto
| ^~
p10.c:102:9: warning: data definition has no type or storage class
102 | x*=y*z; z=(x-y)+y; //notequivalentto
| ^
p10.c:102:9: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:102:9: error: conflicting types for 'z'; have 'int'
p10.c:99:35: note: previous declaration of 'z' with type 'double'
99 | double x, y, z;
| ^
p10.c:103:1: warning: data definition has no type or storage class
103 | z=x;
| ^
p10.c:103:1: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:104:1: warning: data definition has no type or storage class
104 | z = x + x * y; // not equivalent to
| ^
p10.c:104:1: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:105:1: warning: data definition has no type or storage class
105 | z = x * (1.0 + y); y = x / 5.0; // not equivalent to
| ^
p10.c:105:1: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:105:20: warning: data definition has no type or storage class
105 | z = x * (1.0 + y); y = x / 5.0; // not equivalent to
| ^
p10.c:105:20: warning: type defaults to 'int' in declaration of 'y' [-Wimplicit-int]
p10.c:105:20: error: conflicting types for 'y'; have 'int'
p10.c:99:32: note: previous declaration of 'y' with type 'double'
99 | double x, y, z;
| ^
p10.c:106:1: warning: data definition has no type or storage class
106 | y = x * 0.2;
| ^
p10.c:106:1: warning: type defaults to 'int' in declaration of 'y' [-Wimplicit-int]
p10.c:109:1: warning: data definition has no type or storage class
109 | a = a + 32760 + b + 5;
| ^
p10.c:109:1: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:109:5: error: initializer element is not constant
109 | a = a + 32760 + b + 5;
| ^
p10.c:110:17: warning: data definition has no type or storage class
110 | a = (((a + 32760) + b) + 5);
| ^
p10.c:110:17: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:110:17: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:110:21: error: initializer element is not constant
110 | a = (((a + 32760) + b) + 5);
| ^
p10.c:112:8: warning: data definition has no type or storage class
112 | a = ((a + b) + 32765);
| ^
p10.c:112:8: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:112:8: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:112:12: error: initializer element is not constant
112 | a = ((a + b) + 32765);
| ^
p10.c:114:1: warning: data definition has no type or storage class
114 | a = ((a + 32765) + b);
| ^
p10.c:114:1: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:114:1: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:114:5: error: initializer element is not constant
114 | a = ((a + 32765) + b);
| ^
p10.c:115:1: warning: data definition has no type or storage class
115 | a = (a + (b + 32765));
| ^
p10.c:115:1: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:115:1: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:115:5: error: initializer element is not constant
115 | a = (a + (b + 32765));
| ^
p10.c:118:1: warning: data definition has no type or storage class
118 | sum = (((sum * 10) + ((*(p++)) = (getchar())));
| ^~~
p10.c:118:1: warning: type defaults to 'int' in declaration of 'sum' [-Wimplicit-int]
p10.c:118:27: error: 'p' undeclared here (not in a function)
118 | sum = (((sum * 10) + ((*(p++)) = (getchar())));
| ^
p10.c:118:48: error: expected ')' before ';' token
118 | sum = (((sum * 10) + ((*(p++)) = (getchar())));
| ~ ^
| )
p10.c: In function 'main2':
p10.c:47:29: warning: control reaches end of non-void function [-Wreturn-type]
47 | int main2(void) { /* ... */ }
| ^
p10.c: In function 'main3':
p10.c:49:47: warning: control reaches end of non-void function [-Wreturn-type]
49 | int main3(int argc, char *argv[]) { /* ... */ }
| ^
$ gcc p10.c -std=c2x -o p10g -I. -Wall
p10.c:44:22: error: conflicting types for 'i'; have 'int'
44 | char i; int i;
| ^
p10.c:44:15: note: previous declaration of 'i' with type 'char'
44 | char i; int i;
| ^
p10.c:91:1: warning: data definition has no type or storage class
91 | c1 = c1 + c2;
| ^~
p10.c:91:1: warning: type defaults to 'int' in declaration of 'c1' [-Wimplicit-int]
p10.c:91:1: error: conflicting types for 'c1'; have 'int'
p10.c:90:14: note: previous declaration of 'c1' with type 'char'
90 | char c1, c2; /* ... */
| ^~
p10.c:91:6: error: initializer element is not constant
91 | c1 = c1 + c2;
| ^~
p10.c:94:1: warning: data definition has no type or storage class
94 | f1 = f2 * d;
| ^~
p10.c:94:1: warning: type defaults to 'int' in declaration of 'f1' [-Wimplicit-int]
p10.c:94:1: error: conflicting types for 'f1'; have 'int'
p10.c:92:25: note: previous declaration of 'f1' with type 'float'
92 | float f1, f2; double d;
| ^~
p10.c:97:1: warning: data definition has no type or storage class
97 | d1 = f = expression;
| ^~
p10.c:97:1: warning: type defaults to 'int' in declaration of 'd1' [-Wimplicit-int]
p10.c:97:1: error: conflicting types for 'd1'; have 'int'
p10.c:95:29: note: previous declaration of 'd1' with type 'double'
95 | double d1, d2;
| ^~
p10.c:97:10: error: 'expression' undeclared here (not in a function)
97 | d1 = f = expression;
| ^~~~~~~~~~
p10.c:98:1: warning: data definition has no type or storage class
98 | d2 = (float) expression;
| ^~
p10.c:98:1: warning: type defaults to 'int' in declaration of 'd2' [-Wimplicit-int]
p10.c:98:1: error: conflicting types for 'd2'; have 'int'
p10.c:95:33: note: previous declaration of 'd2' with type 'double'
95 | double d1, d2;
| ^~
p10.c:101:1: warning: data definition has no type or storage class
101 | x=(x*y)*z; //notequivalentto
| ^
p10.c:101:1: warning: type defaults to 'int' in declaration of 'x' [-Wimplicit-int]
p10.c:101:1: error: conflicting types for 'x'; have 'int'
p10.c:99:29: note: previous declaration of 'x' with type 'double'
99 | double x, y, z;
| ^
p10.c:102:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*=' token
102 | x*=y*z; z=(x-y)+y; //notequivalentto
| ^~
p10.c:102:9: warning: data definition has no type or storage class
102 | x*=y*z; z=(x-y)+y; //notequivalentto
| ^
p10.c:102:9: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:102:9: error: conflicting types for 'z'; have 'int'
p10.c:99:35: note: previous declaration of 'z' with type 'double'
99 | double x, y, z;
| ^
p10.c:103:1: warning: data definition has no type or storage class
103 | z=x;
| ^
p10.c:103:1: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:104:1: warning: data definition has no type or storage class
104 | z = x + x * y; // not equivalent to
| ^
p10.c:104:1: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:105:1: warning: data definition has no type or storage class
105 | z = x * (1.0 + y); y = x / 5.0; // not equivalent to
| ^
p10.c:105:1: warning: type defaults to 'int' in declaration of 'z' [-Wimplicit-int]
p10.c:105:20: warning: data definition has no type or storage class
105 | z = x * (1.0 + y); y = x / 5.0; // not equivalent to
| ^
p10.c:105:20: warning: type defaults to 'int' in declaration of 'y' [-Wimplicit-int]
p10.c:105:20: error: conflicting types for 'y'; have 'int'
p10.c:99:32: note: previous declaration of 'y' with type 'double'
99 | double x, y, z;
| ^
p10.c:106:1: warning: data definition has no type or storage class
106 | y = x * 0.2;
| ^
p10.c:106:1: warning: type defaults to 'int' in declaration of 'y' [-Wimplicit-int]
p10.c:109:1: warning: data definition has no type or storage class
109 | a = a + 32760 + b + 5;
| ^
p10.c:109:1: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:109:5: error: initializer element is not constant
109 | a = a + 32760 + b + 5;
| ^
p10.c:110:17: warning: data definition has no type or storage class
110 | a = (((a + 32760) + b) + 5);
| ^
p10.c:110:17: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:110:17: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:110:21: error: initializer element is not constant
110 | a = (((a + 32760) + b) + 5);
| ^
p10.c:112:8: warning: data definition has no type or storage class
112 | a = ((a + b) + 32765);
| ^
p10.c:112:8: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:112:8: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:112:12: error: initializer element is not constant
112 | a = ((a + b) + 32765);
| ^
p10.c:114:1: warning: data definition has no type or storage class
114 | a = ((a + 32765) + b);
| ^
p10.c:114:1: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:114:1: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:114:5: error: initializer element is not constant
114 | a = ((a + 32765) + b);
| ^
p10.c:115:1: warning: data definition has no type or storage class
115 | a = (a + (b + 32765));
| ^
p10.c:115:1: warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]
p10.c:115:1: error: redefinition of 'a'
p10.c:109:1: note: previous definition of 'a' with type 'int'
109 | a = a + 32760 + b + 5;
| ^
p10.c:115:5: error: initializer element is not constant
115 | a = (a + (b + 32765));
| ^
p10.c:118:1: warning: data definition has no type or storage class
118 | sum = (((sum * 10) + ((*(p++)) = (getchar())));
| ^~~
p10.c:118:1: warning: type defaults to 'int' in declaration of 'sum' [-Wimplicit-int]
p10.c:118:27: error: 'p' undeclared here (not in a function)
118 | sum = (((sum * 10) + ((*(p++)) = (getchar())));
| ^
p10.c:118:48: error: expected ')' before ';' token
118 | sum = (((sum * 10) + ((*(p++)) = (getchar())));
| ~ ^
| )
p10.c: In function 'main2':
p10.c:47:29: warning: control reaches end of non-void function [-Wreturn-type]
47 | int main2(void) { /* ... */ }
| ^
p10.c: In function 'main3':
p10.c:49:47: warning: control reaches end of non-void function [-Wreturn-type]
49 | int main3(int argc, char *argv[]) { /* ... */ }
| ^
検討事項(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 初稿 20221010
ver. 0.02 ありがとう追記 20230622
最後までおよみいただきありがとうございました。
いいね 💚、フォローをお願いします。
Thank you very much for reading to the last sentence.
Please press the like icon 💚 and follow me for your happy life.