C
C++
coding
ISO
名古屋のIoTは名古屋のOSで

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

初めに

この資料はver. 0.19 です(文末に文書履歴があります)。ver 1.00になったら教材として利用予定です。

当初、C言語(C++)言語の誤解、曲解、無理解の記事の多さにぐったりして、C言語、C++で参考になる記事を集めることからはじめました。

記事を書いた2018年3月25日に、C89(ISO/IEC/ANSI C 9899:1990)とそのRationaleが手元にありませんでした。細かい確認までできませんでした。

今、C1989(1990),C1999, C2011を横並べしながら、4つ(場合によっては5つ)のコンパイラでコンパイルし、実行結果を見ながら内容を確認し、順次追記中です。

20180516追記
C++も比較をはじめました。C++のfreestandingについて無視して書かれている文章が多すぎかも(自分も含めて)。

未定義の場合「コンパイルエラーになる」という表現をしている方が時々見えます。「コンパイルエラーにする」という表現にした方が、良いかも。一字変えれば、誤解、曲解、無理解を防げるかも。

規格で未定義、未規定の内容は、処理系が合理的な理由を立てて、処理をしても良い。コンパイルエラーも一つの選択肢。利用者が、合理的な理由を考えていけない訳でなく、次の版の規格で未定義、未規定を止める提案をしても良い。

目的(purpose)

 この資料の目的は、国際規格・日本工業規格の内容の理解ではなく、処理系の振る舞いを理解し、結果としてプログラマの意図通りに、作ったプログラムが動作するかどうかの確からしさを向上させることにある。

成果(outcome)

 複数のプログラムを複数の処理系で処理することにより、
プログラマの意図が、特定の処理系の範囲内での実現を目指しているか、
複数の処理系で動作する可搬性を目指しているかの区分を明確にできること。

 特定の処理系の範囲内での実現を目指したプログラムを、
誤って別の処理系で翻訳して、プログラマの意図しない動作をさせないこと。

任意のデータ(意図しないデータを含む)に対する処理が、プログラマの意図した範囲に収めることができるかどうかを確かめること。

本文(main text)

C言語は、新しいCPUを設計した場合に、機械語以外の言語としてCPUに同梱するとよい言語としての位置付けを暗黙のうちに意識していた。

C言語でCコンパイラ始め各種言語コンパイラを記述していた。
C言語でOSを記述していた。

C言語を書く必要のあるプログラマでも、使うCPUの違いによってC言語のあるべき姿も違うかもしれない。

CコンパイラをC++で記述したり、OSをC++で記述し始めると、C言語に求める機能、性能も変わるかもしれない。

下の方で紹介するCの精神に「 Trust the programmer.」という記述がある。
想定するプログラマによって立場の違いがあるかもしれない。

1 特定のCPUのCコンパイラをCで書く必要のあるプログラマ
2 特定のCPUのOSをCで書く必要のあるプログラマ
3 特定のCPUの特定の装置(device)のデバイスドライバ(通信規約を含む)をCで書く必要のあるプログラマ
4 複数の構造の異なるCPUのコンパイラをCで書こうとしているプログラマ
5 複数の構造の異なるCPUのOSをCで書こうとしているプログラマ
6 複数の構造の異なるCPUの特定の装置(device)のデバイスドライバ(通信規約を含む)をCで書こうとしているプログラマ
7 特定のCPUのコンパイラをC++で書こうとしているプログラマ
8 特定のCPUのOSをC++で書こうとしているプログラマ
9 特定のCPUの特定の装置(device)のデバイスドライバ(通信規約を含む)をC++で書こうとしているプログラマ
10 複数の構造の異なるCPUのコンパイラをC++で書こうとしているプログラマ
11 複数の構造の異なるCPUのOSをC++で書こうとしているプログラマ
12 複数の構造の異なるCPUの特定の装置(device)のデバイスドライバ(通信規約を含む)をC++で書こうとしているプログラマ
13 特定のCPUをVerilog HDL, VHDL またはSystem Cで書こうとしているプログラマ
14 複数の構造の異なるCPUをVerilog HDL, VHDL またはSystem Cで書こうとしているプログラマ

どのプログラマを一番信頼するかがあると意見の調整がしやすい。
コンパイラを書くプログラマか、コンパイラでコンパイルするプログラマか。
CPUを記述すればC/C++のコンパイラが自動生成されるのであれば、コンパイラを書くプログラマはいなくなるので信頼する必要はないのかもしれない。

14の立場の違いは、CPUの設計の違い(arm, intel86系、その他)、ビット幅(16bit, 32bit, 64bit)の違いと関係しているかもしれない。

36bitCPUとか、16,32ではない幅のCPUのCコンパイラを書かれた方のご苦労は、測り知れないものがあるかもしれない。

C言語で書く必要がないプログラムを書かれている方のC言語(C++)に対する誤解、曲解、無理解と、C言語またはC++で書く必要のある方を含むプログラマの爽快を分類してみる。

順次具体例を探して記述する予定です。

文字の打ち間違えの誤植とかがありましたら、編集リクエスト、コメントの何でも結構ですのでお願いします。

背景(back ground)

C言語規格単独で意味がある規格とは限らない。CPUとC言語とOSとが揃って、一つの実行環境を提供する。
そしてインタネットの普及により、CPU, C言語, OS, 通信規約(network protocol)が一体となって実行環境を提供している。

C言語の歴史

C言語の歴史を標準との関係で記述してみる。

国際規格との関係

1.0 K&R初版

プログラミング言語Cの本が出て、その本をみて、手頃なCコンパイラをぽちぽち打ってるいた。
16bitCPUから、32bit, 36bit等各種CPUに対応した実装が始まった。

2.0 ANSI C 1989/ISO/IEC 9899:1990

K&R初版で書いたプログラムをANSI C適合に書き換えてみた。

2.1 ISO/IEC 9899 AMD1:1995

国際化対応。

3.0 ISO/IEC 9899:1999

//等C++拡張との整合性。

4.0 ISO/IEC 9899:2011

Cの精神からの離陸。

4.1 ISO/IEC TS 17961:2013

Information Technology — Programming languages, their environments and system software interfaces — C Secure Coding Rules
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1624.pdf

コーディング標準の国際仕様(technical specification)化。

下記でコンパイル、実行試験実施中。
ISO/IEC TS 17961:2013 C Secure Coding Rules(1) All list(to be confirmed)
https://qiita.com/kaizen_nagoya/items/54e056195c4f11b850a1

コーディング標準との関係(追記予定)

MISRA C

MISRA C:1999

MISRA C:2004

MISRA C:2012

CERT C

OSとの関係(追記予定)

UNIXの普及

Linuxの台頭

Linuxの国際規格化

ISO/IEC 23360-1:2006 Linux Standard Base (LSB) core specification 3.1 -- Part 1: Generic specification
http://refspecs.linuxfoundation.org/lsb.shtml

C言語標準等を審議しているISO/IEC JTC1 SC22で投票。
http://www.open-std.org/JTC1/SC22/
"ISO/IEC 23360 Linux Standard Base (PAS submission)"

通信規約との関係(追記予定)

TCP/IPの普及。

TCP/IPの国際規格での引用

ISO/IEC 14766:1997
Information technology - Telecommunications and information exchange between systems - Use of OSI applications over the Internet Transmission Control Protocol (TCP)

CPU(central processing unit)

CPUには国際規格がない。
CPUの発展を阻止しないためにCPUには国際規格がないとすれば、C言語はそのCPUとOSの間を取り持たないといけない。C++がCの代替となるためには、言語、OSの記述がうまくC++でできれば。

別の視点では、Verilog HDL、VHDLまたはSystem CによるオープンソースのCPUが普及してくれば、CPUの国際規格を決めることになるかもしれない。

OS(operating system)

OSにはPOSIXが著名だった。その後、Linuxが国際規格になっている。POSIX, LinuxではないOSは、OSの仕様書に実行環境の定義があるとよい。

UNIX(mac osを含む), Linux系ではないOSを書かれているプログラマの方の苦労も測り知れないかもしれない。

また、hosted環境とせず、freestanding環境を提供しているリアルタイムカーネルなどを描かれているプログラマの方の苦労も計り知れないかもしれない。

通信規約(network protocol)

通信規約はISOのOSIが著名だった。その後、TCP/IPが国際規格になっている。

OSは、通信規約と対になって普及している。現在の代表的なOSであるMS Windows, macOS, Linuxの半分から9割以上がUNIX由来。

Cはアメリカの規格(Is C an American Standard?)

1989年、ANSIで決めた規格。
ANSIで承認したX3 委員会に、日立アメリカ、Sonyアメリカという日本の企業も参加している。
https://researchmap.jp/jo927rbbb-1797580/#_1797580

ISO/IEC JTC1で1990年に承認。

ISO/IEC/ANSI C:1990にも多言語処理の規定はあった。
5.2.1.2 Multibyte characters
7.10.7 Multibyte character functions
7.10.8 Multibyte string functions

ISO/IEC 9899:1995 Amd1で国際化の対応を整備している。
この時点で、国際的な国際規格になったと考える人もいる。

道具類(tools)

主に4つのコンパイラを比較してきました。加えて、TOPPERS/SSP等で名古屋市工業研究所等で提供しているM16C/M32C用のコンパイラも同等の作業をしてきました。

GCC,G++

https://gcc.gnu.org

Update c99status.html
https://gcc.gnu.org/ml/gcc-patches/2007-11/msg01188.html

Clang, Clang++

https://clang.llvm.org

Language Compatibility
https://clang.llvm.org/compatibility.html

Visual C++

https://www.microsoft.com/ja-jp/dev/default.aspx

open watcom

16bit CPU用のコンパイラ。10種類のコンパイラを比較してC90の適合性が一番高かった(小職調べ).
C90の適合試験の参照に利用。
https://sourceforge.net/projects/openwatcom/files/

ルネサス(旧三菱)の CPUであるM16C/M32C用のコンパイラ

https://www.renesas.com/ja-jp/products/software-tools/tools/compiler-assembler/compiler-package-for-r8c-and-m16c-families.html
M16Cコンパイラで、未公開だった未定義、未規定、処理系定義を提示していただき、リアルタイムカーネルの提供を行ってきました。
https://www.toppers.jp/ssp-kernel.html#e-download

誤解(mis understanding)

誤解1 Cの独立(free standing)環境とOS(hosted)環境

誤解の原因に、freestandingとhostedの一方しか見ていない場合がある。

:ANSI C 1989/ISO/IEC C 1990 5.1.2
Two execution environments are defined freestanding and hosted.

freestanding

英単語に着目すると良い。freestandingは現在進行形。
C言語で何もかも書いてやるという意思が伝わってくる(?)

  1. Compliancd ISO/IEC 9899:1990 "A conforming freestanding implementation shall accept any strictly conforming program in which the use of the features specified in the library clause(clause 7) is confined to the contents of the standard headers 。

5.1.2.1 Freestanding environment ISO/IEC 9899:1990
"In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined. "
main関数を使わなくてもよく、処理系で定義すれば良い。

"There are otherwise no reserved external identifiers."

"Any library facilities available to a freestanding program are implementation-defined."

Freestandingに3つの概念

Freestanding Environment:Cを動かす環境でhosted以外のもの。
Freestanding implementation: Freestanding 環境用処理系。
Freestanding program: Freestanding 環境で書いたCのプログラム。

「フリースタンディング(freestanding)実行環境及びホスト(hosted)実行環境の 2 種類の実行環境を定義する。」

「フリースタンディング環境では,オペレーティングシステムのいかなる支援もなしに C プログラムの実行を行う」5.1.2.1 JIS X 3010:2003 (ISO/IEC 9899:1999)

C言語で、どちらについて言及しているかを明示していない言明は誤解の可能性がある。
C言語単独での記述のほとんどが、C言語単独では規定できないhosted環境を前提として描かれていることがある。

hosted

hostedは、誰か主役がいる。その主役はOS(operating system)。
C言語規格単独で存在する訳ではない。
どのOSのC言語について言及するか。そのOSではC言語のどの未規定項目について規定しているかを示すと良い。

hosted環境ではない例として、TOPPERSリアルタイムカーネルがある。
TOPPERSリアルタイムカーネルは、果たしてオペレーティングシステムかは議論があるかもしれない。
少なくともホスト環境を用意していないことは確か。

名古屋のIoTは名古屋のOSで(TOPPERS まとめ)
https://qiita.com/kaizen_nagoya/items/9026c049cb0309b9d451

誤解2 Cのmain関数, printf関数と可変数引数関数

hello.c
#include <stdio.h>
void main(){
  printf("Hello World");
}

というプログラムを見たことがあるかもしれない。
C言語でも、関数は、引数をとり、戻り値を返すのが主作用。

ISO/IEC/ANSI 9899:1990にも可変引数のマクロ等はある。

7.8 Variable arguments<stdarg.h>

引数の数の違う関数の例としてmain関数の記述がある。

5.1.2.2 Hosted environment(ISO/IEC ANSI 9899:1990)
5.1.2.2.1 Program startup

int main(void);
int main(int arg, char * argv[]); 

の2つの紹介がある。

Freestanding環境ではstartup関数はmain関数である必要はない。

C89(ISO/IEC 9899:1990)では、ライブラリ関数の引数はmain以外に下記。

int fprintf(FILE * stream const char * format, ...); // 7.9.1
int fscanf(FILE * stream, const char * format, ...); // 7.9.2
int printf(const char *format, ...); // 7.9.3
int scanf(const char *format, ...); // 7.9.4
int sprintf(char *s, const char *format, ...); //7.9.5
int sscanf(const char *s, const char* format...); //7.9.6.6 
int vfprintf(FILE * stream, const char *format, va_list arg); // 7.9.6.7
// = fprintf
int vprintf(const char *format, va_list arg); // 7.9.6.8
// = printf
int vsprintf(char *s, const char * format, va_list arg);//7.0.6.9
//= sprintf

vfscanf, vscanf, vsscanfがない理由は未調査。
上記3関数(vfscanf, vscanf, vsscanf)を含むC99,C2011の表は下記。
https://researchmap.jp/jojxcutwf-1797580/#_1797580

上記以外のライブラリ関数は固定引数。
mainとprintf系は、C言語の例外的な関数。

hello.cは、可変引数かどうかは知らんよという関数の利用の仕方なのだろうか。

hello.cプログラムで伝えたいことは、

1 hosted環境のOSとのやりとりはmain関数で行う。
OSは最初にmain関数を呼ぶ。

2 OS等への出力は関数の副作用として行う。

printfの期待する機能は、主作用ではなく、副作用。
OSとのやりとりはmain関数、OSを含む外部出力はprintf関数を使う。

C言語にとって、OSとのやりとりは大事な機能。
OSのないプログラムも書けることがどこかへ飛んでいるかもしれない。

OSとのやり取りを重視したとしたら、次のようなプログラムがあってもいいかもしれない。

pr.c
#include <stdio.h>
int main(int argc, char* argv[]){
  printf("%s \n",argv[1]);
  return argc;
}
shell
$ cc pr.c
$ ./a.out Hello_World!
Hello_World!

最初のhello.cプログラムの次に、pr.cがあれば、main, printfが可変長引数の関数だということが伝わるかもしれない。

引数と戻り値

pr.cで引数を戻り値にしている。呼び出した時の戻ってきた時で、argcが変化しないか確かめる目的の時の記述方法。駄目なプログラム。

pr2.c
#include <stdio.h>
int main(int argc, char* argv[]){
  printf("%s \n",argv[--argc]);
  return argc;
}

argcの変化を確かめる用事がない時は、下記のように関数の戻り値をそのまま戻す。時々、どこからか怒られる。printfが何を返してきてるかを確かめたかったということにしている。

pr3.c
#include <stdio.h>
int main(int argc, char* argv[]){
  return printf("%s \n",argv[1]);
}

最後まで行ったら正常ならTRUE、異常ならFALSEを返す方法もある。
ただし、途中の処理で、TRUE, FALSEと同じ値を返す可能性があれば、違う値にするようにしている。

誤解3 Cの精神

ANSI C:1989からISO/IEC 9899:1999まで継続したC言語の基本理念。
C:1989およびC:1999のどちらにも掲載がある。

「Cの精神」が、どのようなCPUの分布状況で生まれたか。
どのCPUとどのCPUが競争している状況で生まれたか。
どの言語が生まれ、どの言語と競争している状況で生まれたか。
前節で話題になっているどのOSが活躍している状況で生まれたか。

Cの精神の背景の理解抜きに、Cの精神の意味が理解できないかもしれない。
OSにおけるUNIX、通信規約におけるTCP/IP、C言語の3つが時間的な誤差はあるものの、
ベル研究所や、US バークレーを中心とするプログラマの間で生まれてきた。

それまでのアセンブラ(z80, 8086系とそれ以外で大きく違うかもしれない)や、各種個別言語や、Pascal、LISP、Fortranという言語との関係についての立場で、意味が違うかもしれない。

ANSIで承認したX3 委員会に、CPUメーカ、コンピュータメーカだけでなく、プログラマの企業・組織も参加している。日本の標準化の実情とはかけ離れているかもしれない。
日立アメリカ、Sonyアメリカという日本の企業も参加している。
https://researchmap.jp/jo927rbbb-1797580/#_1797580
これらの組織、技術者一人一人で、内容も理解も異なるかもしれない。

Cの精神の文書は、JIS文書の解説に翻訳があります。
JISの解説は、JIS本文とは著作権の扱いが異なり、幅広くは公開されていません。
それに対して英文のRationaleは下記のURLで公開されています。
日本語の翻訳を読まれたい方は、廃止されたJISをご確認ください。
C言語規格が日本規格協会では、廃止されたJISも販売してくださっています。

C90のRationaleは本家のURLに見当たらず。
Rationale for American National Standard for Information Systems - Programming Language - C
https://www.lysator.liu.se/c/rat/title.html

C99のRationleは本家にあり。
Rationale for International Standard— Programming Languages— C
http://www.open-std.org/jtc1/sc22/wg14/www/docs/C99RationaleV5.10.pdf

「Keep the spirit of C. The C89 Committee kept as a major goal to preserve the traditional spirit
of C. There are many facets of the spirit of C, but the essence is a community sentiment of the 15 underlying principles upon which the C language is based. Some of the facets of the spirit of C
can be summarized in phrases like:

• Trust the programmer.
• Don’t prevent the programmer from doing what needs to be done.
• Keep the language small and simple.
• Provide only one way to do an operation.
• Make it fast, even if it is not guaranteed to be portable.

The last proverb needs a little explanation. The potential for efficient code generation is one of the most important strengths of C. To help ensure that no code explosion occurs for what appears to be a very simple operation, many operations are defined to be how the target machine’s hardware does it rather than by a general abstract rule. An example of this willingness to live with what the machine does can be seen in the rules that govern the widening ofcharobjectsforuseinexpressions: whetherthevaluesofcharobjectswidentosignedor unsigned quantities typically depends on which byte operation is more efficient on the target machine.
One of the goals of the C89 Committee was to avoid interfering with the ability of translators to generate compact, efficient code. In several cases the C89 Committee introduced features to improve the possible efficiency of the generated code; for instance, floating-point operations may be performed in single-precision, rather than double, if both operands are float.
At the WG14 meeting in Tokyo, Japan, in July 1994, the original principles were re-endorsed and the following new ones were added:
Support international programming. During the initial standardization process, support for internationalization was something of an afterthought. Now that internationalization has become an important topic, it should have equal visibility. As a result, all revision proposals shall be reviewed with regard to their impact on internationalization as well as for other technical merit.

Codify existing practice to address evident deficiencies. Only those concepts that have some prior art should be accepted. (Prior art may come from implementations of languages other than C.) Unless some proposed new feature addresses an evident deficiency that is actually felt by more than a few C programmers, no new inventions should be entertained.
Minimize incompatibilities with C90 (ISO/IEC 9899:1990). It should be possible for existing C implementations to gradually migrate to future conformance, rather than requiring a replacement of the environment. It should also be possible for the vast majority of existing conforming programs to run unchanged.
Minimize incompatibilities with C++. The Committee recognizes the need for a clear and 10 defensible plan for addressing the compatibility issue with C++. The Committee endorses the
principle of maintaining the largest common subset clearly and from the outset. Such a principle should satisfy the requirement to maximize overlap of the languages while maintaining a distinction between them and allowing them to evolve separately.
The Committee is content to let C++ be the big and ambitious language. While some features of 15 C++ may well be embraced, it is not the Committee’s intention that C become C++.
Maintain conceptual simplicity. The Committee prefers an economy of concepts that do the job. Members should identify the issues and prescribe the minimal amount of machinery that will solve the problems. The Committee recognizes the importance of being able to describe and teach new concepts in a straightforward and concise manner.
During the revision process, it was important to consider the following observations:
• Regarding the 11 principles, there is a tradeoff between them—none is absolute. However, the more the Committee deviates from them, the more rationale will be needed to explain the deviation.
• There had been a very positive reception of the standard from both the user and vendor communities.
• The standard was not considered to be broken. Rather, the revision was needed to track emerging and/or changing technologies and internationalization requirements.
• Most users of C view it as a general-purpose high-level language. While higher level constructs can be added, they should be done so only if they don’t contradict the basic principles.
• There are a good number of useful suggestions to be found from the public comments and defect report processing.

ISO/IEC 9899:2011からRationaleはない。

時代とともに変化する規格の意味を現在の状況だけで判断しようとすると無理があるかも。どういうCPUが存在し、どういう処理系が存在したから、どういう規定があるのか確認できないと、誤解も曲解も無理解も仕方がないかも。

誤解の原因は、未定義、未規定、処理系定義に対する一つのCPU、一つの処理系での振る舞いで理解しようとするあたりではないかと思い下記を記録。

誤解4 未定義の動作(undefined behavior)

JIS X 3010:2003 (ISO/IEC 9899:1999) 3.4.3
 「 可搬性がない若しくは正しくないプログラム構成要素を使用したときの動作,又は正しくないデータを使用したときの動作であり,この規格が何ら要求を課さないもの。」
「定義しない」ことを定義している。その前向きな意味を、「Cの精神」の範囲内で理解するとよい。
「Cの精神」だけではOSや通信規約のセキュリティを確保できないという壁がある。
どう理解するのかが正解かという「落とし所」は、正しいOS,正しい通信規約を記述できて初めて誤解でない理解ができるのかもしれない。

C言語分かってなかった (I Do Not Know C)
https://qiita.com/yohhoy/items/960ee7a7b502e5c764b4

誤解5 未規定の動作(unspecified behavior)

JIS X 3010:2003 (ISO/IEC 9899:1999) 3.4.4
「この規格が,二つ以上の可能性を提供し,個々の場合にどの可能性を選択するかに関して何ら要求を課さない動作。」
複数の定義のうち、どちらにするかを決めないことを未規定という。
その前向きな意味も、「Cの精神」の範囲で理解するのか、セキュリティを確保する設計ができて初めて誤解でない理解ができるのかもしれない。

誤解6 処理系定義の動作(implementation-defined behavior)

jis X 3010:2003 (ISO/IEC 9899:1999) 3.4.1
「未規定の動作のうち,各処理系が選択した動作を文書化するもの。」
処理系定義は、処理系が定義すればよいという任意性という側面と、
処理系は定義を利用者に提供しなくてはいけないという義務の側面があるかもしれない。自分が使っている処理系の全ての「処理系定義の動作」を調べてみてください。
未定義の動作についても、処理系で定義した内容を利用者に提供してはいけないことはないかもしれません。規格で言及していないだけだから、処理系の提供者に確認することは大事です。
自分が使っている処理系のすべてで、未規定、未定義に関する処理系の定義が同じであれば、その処理系定義の内容は、次の規格で、規定として決めることになる可能性を予測するとよいかもしれません。

誤解7 文化圏固有の動作(locale-specific behavior) 3.4.2

「国家,文化及び言語の地域規約に依存する動作であり,各処理系がその動作を文書化するもの。」
 文字コード、文字の並び・ルビなどの文化圏に依存した文字処理、文字形(font)の組み合わせなど、洗い出しておくとよい。(作業中)

誤解8 文字コード、trigraph, digraph

計算機には、文字コードが様々である。文化圏固有の動作の大きな部分は文字コードに関するものがある。trigraph, digraphは{}[]の文字が入力できないシステムの必要な技術。わざわざ{}[]が入力できるシステムで利用する必要がない。

https://www.misra.org.uk/forum/viewtopic.php?f=187&t=1686&sid=7af1d26c86bb359e8f73868505c3168d

I feel, the sentence "The use of digraphs may not meet developer expectations." is not clear.
The usage of digraphs are only system constraints. 
Digraph are just an alternative method for a systems that can not input '{','}','[',']'. 
Therefore, there is no point in leaving a digraph in the final source file. 
Even if anyone use a system that requires digraphs, it is better to replace in the final source file from digraph(alternative token) to primary token.

{}[]が入力できないシステムにおいてもC言語がコンパイルできるようにする仕組みである。{}[]が利用できるシステムで保存する際には、自動的に置き直すか、変換後のファイルをReview対象にする方法もある。digraph, trigraphの使用が問題なのではない。

曲解(wrest)

どんな曲解があるか捜索中。

無理解(uncomprehension)

どんな無理解が存在しているか調査中。

爽快(happy)

C++ における整数型の怪と "移植性のある" オーバーフローチェッカー (第1回 : 整数型の怪と対策の不足)
https://qiita.com/a4lg/items/541c9d9dd5d874eeef2f

C++ における整数型の怪と "移植性のある" オーバーフローチェッカー (第2回 : 符号無し整数型のチェック)
https://qiita.com/a4lg/items/3b92538049969715bf10

C++ における整数型の怪と "移植性のある" オーバーフローチェッカー (第3回 : C言語の整数の性質を知る)
https://qiita.com/a4lg/items/9546ea49b8c1f98e6603

C++ における整数型の怪と "移植性のある" オーバーフローチェッカー (第4回 : 符号付き整数型のチェックと動機の動機)
https://qiita.com/a4lg/items/68b7fab23678b5354b01

C++ における整数型の怪と "移植性のある" オーバーフローチェッカー (第5回 : 続・符号付き整数型のチェック)
https://qiita.com/a4lg/items/bc4d2cfbce22fe749589

C++のsize_tは範囲を超えるとどうなるか
https://qiita.com/daisukeokaoss/items/5615cd59a1432d8b96ee

C/C++はnull安全になる前に安全に差の絶対値を計算できるようになるべきではないか
https://qiita.com/yumetodo/items/4ea151e15b5e540cfef5

ISO/IEC 9899:1990(ANSI C 1989) and ISO/IEC 9899:1999

評価されない演算子
https://qiita.com/yz2cm/items/630759d841904619fb7b

ISO/IEC 9899:1990(ANSI C 1989), ISO/IEC 9899:1999 and ISO/IEC 9899:2011

(C言語)Array-to-pointer conversionの例外は3つだけではなかった
https://qiita.com/yz2cm/items/ff9b72afa1c412d17f35

現在コードと規格を確認中(to be confirmed)

C言語で暗黙の型変換が発生する16のパターン(+演算子の結果型5パターン)
https://qiita.com/yz2cm/items/0e24e1df40ef5cd43249

言い訳:複数の要因の組合せなど、どこまで検討し、どこまで一つと数えるか、厳密に考え始めると夜が寝られなくなり、まだ未確認です。ごめんなさい。

【初心者向け】ポインタはなぜ難しいか(ポインタのちょっとしたコツ)
https://qiita.com/yz2cm/items/01908cdfe56c304f2a14

C2011の変更点があるかどうかを確認中です。

intがなんのためにあるかという背景情報をどこまで含んで検討するか。
レジスタ幅、演算結果の幅、データ幅との関係についてどこまで言及すると分かりやすくなるか迷い中です。

ISO/IEC 9899:1990のRationaleなどの意味を解説しようと思うと、どういうCPUがあったから、こういう規定になっているという説明の方が、納得しやすい場合がありました。

明示的型変換には何が許されて何が許されないのか、そろそろハッキリさせておきたい。
https://qiita.com/yz2cm/items/9edc81a2b20e19441605

ISO/IEC9899:1990の integral conversion, ISO/IEC 9899:1999のinteger conversionだけでもややこしくて1日でうまく説明できません。ごめんなさい。

質問されるとその答えを1日で探すのはできるかもしれませんが。

単純代入演算子について
https://qiita.com/yz2cm/items/276b56b406e8cc13d133

C90の型分類と、演算子のオペランドの型
https://qiita.com/yz2cm/items/012ea4a02a2237322197

C90の電子ファイルが行方不明。現在捜索中。

式X+++++Yの読み方
https://qiita.com/yz2cm/items/279a6163c00e930ada08

gcc-7, clang(6.0.0)ともコンパイルエラーになる。
Open watcom Cでコンパイル予定。

const T[]の意味は「要素型Tのconst配列型」ではなく「要素型const Tの配列型」
https://qiita.com/yz2cm/items/4cd0dabcba80c5134ac0

$ clang --version
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-apple-darwin17.4.0

gcc-7では警告が出るが、clangでは警告がでない。

$ clang -o sample -std=c90 -pedantic -Wall sample.c

Clang, gcc, visual CのC規格断片の警告確認作業中。
違いはわかっても、その違いの理由が理解できていない。

参考文献(reference)

C2011コンパイル一覧@researchmap
https://researchmap.jp/jownvh0ye-1797580/#_1797580

[C][C++]の国際規格案の例題をコンパイルするときの課題7つ。
https://qiita.com/kaizen_nagoya/items/5f4b155030259497c4de

C Puzzle Bookの有り難み5つ、C言語規格及びCコンパイラの特性を認識
https://qiita.com/kaizen_nagoya/items/d89a48c1536a02ecdec9

MISRA C まとめ #include
https://qiita.com/kaizen_nagoya/items/f1a79a7cbd281607c7c9

どうやって MISRA Example Suiteをコンパイルするか
https://qiita.com/kaizen_nagoya/items/fbdbff5ff696e2ca7f00

MISRA-C 2012 Referenceに掲載している文献の入手可能性を確認
https://qiita.com/kaizen_nagoya/items/96dc8b125e462d5575bb

反省(regret)

この資料自体が、誤解を生みやすい表現、表記で満載。
C言語規格、Rationale、それぞれの規格が出た当時の処理系、今の処理系の比較を、わかりやすく整理しないと、曲解や無理解も生み出すかもしれない。
コンパイラでコンパイル・実行して確かめられることは確かめながら順次追記していきます。

フリースタンディング環境を意識したリアルタイムカーネルをオープンソースで提供しています。
C言語に対する誤解、曲解、無理解を増長するような情報提供だったと反省しています。

参考資料:Dockerどっかー使い方おかしかったんでしょうか。TOPPERS/SSP on RaspberryPi with Macintosh編:9つの関門
https://qiita.com/kaizen_nagoya/items/cbf40186ae4da48ec4c7

関連する記述が不十分です。C言語のフリースタンディング環境のオープンソースに置いて、フリースタンディング環境であることの記述を補強するための資料として利用するためにも整理中です。

プログラミング言語は、日本語で議論するより、英語で議論したほうが、誤解が少ないというのが経験則です。hostedとfreestandingの例のように。

RTL設計スタイルガイドでは日本人が作ったのに英語の方が分かり易かったという経験もあります。
参考資料:RTL設計スタイルガイド Verilog HDL編(System Verilog対応版
https://qiita.com/kaizen_nagoya/items/4c02f1575db1f28310a7

英語での資料補強が多くなるかもしれません。ごめんなさい。

p.s.(post script) いいねを頂く度に、いいねをしていただいた方の興味を確認し、ご興味の方向での追記をするようにしています。あるLTで、この資料を使ってプレゼンしたら、「可変長引数」ってなんですか?と質問いただきました。急遽、ISO/IEC 9899:1990の原本を探して追記し始めたところです。初めての計算機言語が、C++, JAVA, C#, Python, Ruby, Verilog HDL, VHDLという方々に分かるようなC言語の資料を目指します。

文書履歴(document history)

ver. 0.10 初稿 20180325
ver. 0.11 Cの精神、未定義、未規定、処理系定義、文化圏固有の追記 20180326
ver. 0.12 立場の違いを6から12に増強 20180327
ver. 0.13 立場の違いを12から14に増強、デバイスドライバに通信規約を追記 20180327
ver. 0.14 Ratinale:c1989のURL追記。ANSI C:1989から可変長引数関連追記 20180330
ver. 0.15 「初めに」追記 20180331
ver. 0.16 @ryohji さんからのコメントに関連してURL等を追記。フリースタンディング環境のオープンソースのリアルタイムカーネルTOPPERS/SSP とそのM16C用コンパイラの未定義関連等の追記。201804009
ver 0.17 誤解8 digraph, trigraphについて追記 20180410
ver 0.18 文書履歴を最後に。「C言語分かってなかった」URL追記 20180411
ver 0.19 初めにに「未定義、未規定」に関する記述を追記。20180516