明日使えるCの無駄知識(順不同)
以下の文章が全て正しいとは限りません.本当かどうかは各自で調べてください.
もし間違っていたらコメントで教えてください.
- compound literalを書くときに配列なら
(int[]){[10]=11,[100]=1}
,構造体なら(struct a){.a=1}
なんてことができる.詳しくはググれ - compound literalは実は左辺値
-
main
関数に限ってreturn
を書かなくても良い - 規格上(処理系定義でない)
main
の定義方法はint main(void)
かint main(int,char**)
のみ - forやwhileやifやswitchはぶら下がり防止のために暗黙のうちに{}が入る.
- _Static_assert ( constant-expression , string-literal ) ;というコンパイル時アサーション機能がある
- _Alignofや_Alignasなんかもある
- _Bool型,_Complex型,_Atomicもある
- アンダーバーがうざいと思ったら対応しているヘッダ(stdbool.hとか)で消せる
- なんかいろいろ(使わなさそうな)予約語が増えた.
- 例えば,C99でrestrictやinline出たし,C11で_Noreturnが出てきて,その結果quick_exit関数やat_quick_exit関数なんかもできた
- さらに言えば,getsが廃止された代わりに,I/O系の関数の末尾に_sがついた関数が大量に導入された.gets_sやprintf_sとか.多分殆どの関数は知られていないし,知っている人でも挙動を把握しているのはごく一部だと思う
- 地味にaligned_allocが追加された.使いどころがフリースタンディング環境くらいしか思いつかない.
- _Genericが追加されて黒魔術の闇が濃くなった
- sizeofや_Alignofの中身は通常評価されない.選択されなかった_Genericの中身もそう
- 無名unionや無名structが導入された.便利
- structやunionのタグ名とtypedefの型名は同じでも良い
- struct a {int a;}とstruct b {int b;} は違う型なのでこんなことができる.キモい
#include <stdio.h>
typedef struct a {int a;} a;
typedef struct b {int b;} b;
#define A(aa) ((a){.a=aa})
#define B(bb) ((b){.b=bb})
#define AorB(ab) (_Generic(ab,a:"A",b:"B",default:"default"))
int main(void) {
printf("%d\n",(int[100]){[3]=10,[20]=1}[3]);
printf("%s",AorB(A(1)));
}
- printfのフォーマット文字を間違えると未定義
- フォーマット文字と引数の対応が取れてなくても未定義
- scanfも同じ
- printfにunix拡張で*や$が使える.詳しくはman 3 printf
- 忘れてたけど,標準でスレッドがサポートされる.atomicができたのはこのため
- しかしメジャーな実装系はライブラリやヘッダを用意していない.頑張ってくれ
- unicoideに対応した.
u8""
やu16""
やu32""
が使える - 関数宣言に引数にint i[*]ってできる
- 可変長配列みたいなもん
**以上!!**他にもあるかも?