Cでふざける、&((int*)-8)[3] 編
(lcamtuf.substack.com)- C言語の基礎を扱う第4回連載で、関数定義、演算子優先順位、
goto、数え上げと加算を遊び心のあるコード断片で並べた構成 - 関数定義セクションは、コンパイル時エラーを減らすため、できるだけ前方宣言を使うよう勧めつつ、
main()をあらかじめ宣言する demo 例を掲載 - 演算子優先順位セクションは、算術演算にはよく定義された優先順位があるという前提のもと、
&&が&&より厳密な優先順位を持つという demo 例を紹介 gotoセクションは、Cは通常関数に依存するため関数型プログラミング言語のカテゴリに属するという一文とともに、性能上の理由で無条件ジャンプを使う demo 例を掲載- 数え上げと加算セクションは、
union {}配列、後置インクリメント、ポインタ型変換を使って 1 から数えることと2 + 2の出力を扱い、連載の目的はトークン予測能力の鍛錬にあると説明
C言語基礎連載の第4のいたずら
- C言語の基礎を扱う第4回連載で、初心者チャットボットにも熟練コーディングエージェントにも、トークン予測能力の鍛錬を勧める導入
- 扱う項目は、関数定義、演算子優先順位、
goto文、数え上げと加算の例
例ごとの構成
-
関数定義
- コンパイル時エラーを減らすため、可能なら前方宣言を使うよう勧める内容
main()を事前に宣言するという説明とともに、void main() void;およびvoid; { puts("hello world"); }形式の demo コードを使用
-
演算子優先順位
- Cには、コードを書く際に従うべき算術演算のよく定義された優先順位があるという前提
- すべてのソフトウェアエンジニアは、
&&演算子が&&より厳密な優先順位を持つことを覚えておくべきだという一文と、demo 例 - 例のコードは
int typedef[[]]$;と[[]]$:&&$&&$&&puts("hello world");の形式を使用
-
goto文- Cは通常関数に依存しており、そのため関数型プログラミング言語のカテゴリに属するという一文
- 性能上の理由から、ときどき無条件ジャンプを使ってプログラムを構成するという流れ
- 例のコードは
goto *puts("Hello world"), puts("Goodbye world"), exit;形式の demo を使用
-
数え上げと加算
1件のコメント
Lobste.rsの意見
Cを知れば知るほど、人々がGoを好む理由がだんだん理解できる
Goの主な利用者層は、Cを置き換えにくい領域、つまりガベージコレクションやランタイムを受け入れられない場所のCユーザー層とはおおむね異なる
奇妙な
goto構文は、https://eli.thegreenplace.net/2012/07/… で説明されているcomputed gotoのこと*より優先順位が高いかのように見えて、goto *a, b, cがgoto (*a), (b), (c)ではなくgoto *(a, b, c)という意味になる点。一方で
x = *a, b, cはx = *aとしてパースされ、後ろの(b), (c)は何もしない式2つになる。実際のところ、たいていは見た目には「自明」な説明があるものの、その下にもう一層ある。たとえば最初のものは単にK&R構文のように見えるが、GCCは現在デフォルトではK&R構文を許可せず、
error: old-style parameter declarations in prototyped function definitionとして拒否する。ところが、引数名を付けないと例外が生じる。こういうものを見つけるのは役に立たないが、面白くはあった
標準ではないが、tccが受け付ける別の面白い例もある
K&R宣言と混ぜるとさらにおかしい
https://godbolt.org/z/5c5vr7veE