C言語のC23規格のプログラミングを教えて!
こういった悩みにお答えします.
本記事の信頼性
- リアルタイムシステムの研究歴12年.
- 東大教員の時に,英語でOS(Linuxカーネル)の授業.
- 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校(UNC)コンピュータサイエンス学部で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発.
- プログラミング歴15年以上,習得している言語: C/C++,Python,Solidity/Vyper,Java,Ruby,Go,Rust,D,HTML/CSS/JS/PHP,MATLAB,Assembler (x64,ARM).
- 東大教員の時に,C++言語で開発した「LLVMコンパイラの拡張」,C言語で開発した独自のリアルタイムOS「Mcube Kernel」をGitHubにオープンソースとして公開.
- 2020年1月~現在はアメリカのノースカロライナ州チャペルヒルにあるGuarantee Happiness LLCのCTOとしてECサイト開発やWeb/SNSマーケティングの業務.2022年6月~現在はアメリカのノースカロライナ州チャペルヒルにあるJapanese Tar Heel, Inc.のCEO兼CTO.
- 最近は自然言語処理AIとイーサリアムに関する有益な情報発信に従事.
- (AI全般を含む)自然言語処理AIの論文の日本語訳や,AIチャットボット(ChatGPT,Auto-GPT,Gemini(旧Bard)など)の記事を50本以上執筆.アメリカのサンフランシスコ(広義のシリコンバレー)の会社でプロンプトエンジニア・マネージャー・Quality Assurance(QA)の業務委託の経験あり.
- (スマートコントラクトのプログラミングを含む)イーサリアムや仮想通貨全般の記事を200本以上執筆.イギリスのロンドンの会社で仮想通貨の英語の記事を日本語に翻訳する業務委託の経験あり.
こういった私から学べます.
C言語を独学で習得することは難しいです.
私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.
私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!
独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!
目次
【C言語】C23規格
C23規格は2024年に予定されているC言語の規格です.
C23規格を含むC言語の規格策定のプロジェクトは,「C - Project status and milestones」で公開されています.
上記のページでは,ISO/IECの正式なC言語の規格書(有料)とドラフト(無料)が提供されています.
C23規格のプログラミングをしたいけど,どのようにプログラミングして良いのかわかりませんよね.
そこで本記事では,C23規格で私が有用だと思う機能を紹介します.
※GCC 13.1/Clang 16.0がサポートしているC23規格の機能のみを紹介します.コンパイラが新しい機能をサポートし次第,追加していきます.
C23規格のプログラミング環境の構築
本記事のC23規格のプログラミング環境の構築は以下になります.
- CPU:Intelマルチコア
- OS:Linux(Ubuntu 22.04 LTS)
- コンパイラ:GCC 13.1,Clang 16.0
GCC 13.1のビルドとインストール
2023年6月現在,Ubuntu 22.04 LTSでGCC 13.1をaptでインストールできません.
そこで,GCC 13.1のビルド方法を紹介していきます.
まずは以下のコマンドを入力してビルド環境をインストールして下さい.
1 2 3 |
$ sudo apt update $ sudo apt install build-essential bzip2 flex $ sudo apt install libgmp-dev libmpfr-dev libmpc-dev |
GCC 13.1のソースコードをダウンロード,ビルドします.
ビルドは1時間以上かかります.
1 2 3 4 5 6 7 |
$ wget https://ftp.gnu.org/gnu/gcc/gcc-13.1.0/gcc-13.1.0.tar.gz $ tar zxvf gcc-13.1.0.tar.gz $ cd gcc $ mkdir build $ cd build $ ../configure --enable-languages=c,c++ $ make -j4 |
1 2 3 4 5 6 7 8 |
In file included from /usr/include/bits/errno.h:26, from /usr/include/errno.h:28, from ../../../../libgcc/../gcc/tsystem.h:93, from ../../../../libgcc/libgcc2.c:27: /usr/include/linux/errno.h:1:10: fatal error: asm/errno.h: No such file or directory 1 | #include <asm/errno.h> | ^~~~~~~~~~~~~ compilation terminated. |
上記のビルドエラーが出る場合は,以下を入力して修正して下さい.
1 2 |
$ cd /usr/include $ sudo ln -s asm-generic asm |
ビルドが成功したら,以下のコマンドでインストールして下さい.
1 |
$ sudo make install |
GCC 13.1が正常にインストールできているか以下のコマンドで確認して下さい.
1 2 3 4 5 6 7 8 9 |
$ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/13.1.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../configure --enable-languages=c,c++ Thread model: posix Supported LTO compression algorithms: zlib gcc version 13.1.0 (GCC) |
Clang 16.0のインストール方法
Clang16.0のインストール方法はこちらが参考になります.
まずは/etc/apt/source.listをバックアップします.
1 2 |
$ cd /etc/apt $ sudo cp -a sources.list sources.list.org |
次に/etc/apt/source.listに以下を追加します.
1 2 |
deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main deb-src http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main |
Clang 16.0をインストールします.
1 2 |
$ sudo apt update $ sudo apt clang-16 |
clang-16をclangで利用できるように変更します.
1 |
$ sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-16 1 |
clangを実行してバージョンが16になっているか確認して下さい.
1 2 3 4 5 |
$ clang --version Ubuntu clang version 16.0.6 (++20230610113458+7cbf1a259152-1~exp1~20230610233511.102) Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin |
C23規格のプログラミング
C23規格のプログラミングを紹介します.
C23規格の機能の使い方がわかります.
C23規格で新しく追加された予約語(キーワード)は以下になります.
- bool/true/false
- nullptr
- _BitInt
- _Decimal32/_Decimal64/_Decimal128
- constexpr
- auto(C23規格から採用された型推論)
- thread_local
- alignas
- alignof
- static_assert
C言語の予約語(キーワード)を知りたいあなたはこちらからどうぞ.
本記事で紹介するC23規格の機能におけるGCC/Clangコンパイラのサポート状況は下表になります.
※コンパイラがサポートし次第,C23規格のプログラミングの内容は追加していきます.
機能 | GCC 13.1 | Clang 16 |
---|---|---|
auto(型推論) | ✓ | |
constexpr | ✓ | |
digit separator | ✓ | ✓ |
2進数リテラル | ✓ | ✓ |
#elifdef/#elifndef | ✓ | ✓ |
typeof/typeof_unqual | ✓ | ✓ |
auto(型推論)
auto(型推論)は,変数の型を初期化子から推論できるようになるキーワードです.
いわゆる,C++言語のC++11規格から採用されたauto(型推論)のC言語版です.
C言語で自動変数を表すautoとは異なるので注意して下さい.
C++言語のautoとは異なり,C23のauto(型推論)は変数の型に対してのみ型推論が可能です.
つまり,C23のauto(型推論)は,関数の返り値の型や関数のパラメータの型を推論できないことに注意して下さい.
autoを利用するコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> int main(void) { auto i = 123; auto d = 45.67; printf("i = %d, d = %lf\n", i, d); return 0; } |
GCC 13.1の実行結果は以下になります.
コンパイル時にC23規格を有効にするオプション「-std=c2x」をつけるのを忘れないようにして下さい.GCC 13.1のデフォルトではC17規格になります.
1 2 3 |
$ gcc auto.c -std=c2x $ a.out i = 123, d = 45.670000 |
GCC 13.1で-std=c2xオプションがないとコンパイル時に警告が発生し,dがdouble型ではなくint型と認識されてしまうため,「d = 0.000000」と表示されてしまいます.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ gcc auto.c auto.c: In function 'main': auto.c:9:8: warning: type defaults to 'int' in declaration of 'i' [-Wimplicit-int] 9 | auto i = 123; | ^ auto.c:10:8: warning: type defaults to 'int' in declaration of 'd' [-Wimplicit-int] 10 | auto d = 45.67; | ^ auto.c:12:25: warning: format '%lf' expects argument of type 'double', but argument 3 has type 'int' [-Wformat=] 12 | printf("i = %d, d = %lf\n", i, d); | ~~^ ~ | | | | double int | %d $ a.out i = 123, d = 0.000000 |
Clang 16.0ではauto(型推論)をサポートしていないため,コンパイルエラーになります.
1 2 3 4 5 6 7 8 |
$ clang auto.c -std=c2x auto.c:9:8: error: a type specifier is required for all declarations auto i = 123; ~~~~ ^ auto.c:10:8: error: a type specifier is required for all declarations auto d = 45.67; ~~~~ ^ 2 errors generated. |
constexpr
constexprはコンパイル時に変数の初期化を要求する型修飾子です.
※C++言語のconstexprとは異なり,C言語のC23規格のconstexprは関数には利用できないことに注意して下さい.
また,浮動小数点数にconstexprを利用する場合,精度が低いfloat型では数値によっては正常に初期化できないことがあります.
これに対して,constexprと似ているconstは,実行時に変数を初期化しても良いです.
つまり,(C言語のC23規格の)constは,コンパイル時に変数を初期化しなくてもコンパイルエラーにはなりません.
※C++言語のconstは,コンパイル時に変数を初期化しないとコンパイルエラーになります.ややこしいですね...
constexprを利用するコードは以下になります.
11行目のconstexprで初期化しない変数kはエラーになります.
14行目のconstexprで0.2を代入するf2は精度不足でエラーになります.
※13行目のconstexprで0.5を代入するfや,15行目のconstexprで0.2を代入するdは正常に動作します.
興味があるあなたはコメントを外してみましょう.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> int main(void) { constexpr int i = 123; constexpr int j = i + 45; // constexpr int k; // NOTE: error if uncomment. constexpr float f = 0.5; // constexpr float f2 = 0.2; // NOTE: error if uncomment. constexpr double d = 0.2; printf("i = %d, j = %d\n", i, j); printf("f = %f, d = %lf\n", f, d); return 0; } |
GCC 13.1の実行結果は以下になります.
1 2 3 4 |
$ gcc constexpr.c -std=c2x $ a.out i = 123, j = 168 f = 0.500000, d = 0.200000 |
GCC 13.1で-std=c2xオプションがないとコンパイルエラーになります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
$ gcc constexpr.c constexpr.c: In function 'main': constexpr.c:9:3: error: 'constexpr' undeclared (first use in this function) 9 | constexpr int i = 123; | ^~~~~~~~~ constexpr.c:9:3: note: each undeclared identifier is reported only once for each function it appears in constexpr.c:9:12: error: expected ';' before 'int' 9 | constexpr int i = 123; | ^~~~ | ; constexpr.c:10:12: error: expected ';' before 'int' 10 | constexpr int j = i + 45; | ^~~~ | ; constexpr.c:13:12: error: expected ';' before 'float' 13 | constexpr float f = 0.5; | ^~~~~~ | ; constexpr.c:15:12: error: expected ';' before 'double' 15 | constexpr double d = 0.2; | ^~~~~~~ | ; constexpr.c:17:30: error: 'i' undeclared (first use in this function) 17 | printf("i = %d, j = %d\n", i, j); | ^ constexpr.c:17:33: error: 'j' undeclared (first use in this function) 17 | printf("i = %d, j = %d\n", i, j); | ^ constexpr.c:18:31: error: 'f' undeclared (first use in this function) 18 | printf("f = %f, d = %lf\n", f, d); | ^ constexpr.c:18:34: error: 'd' undeclared (first use in this function) 18 | printf("f = %f, d = %lf\n", f, d); | ^ |
Clang 16.0はconstexprをサポートしていないので,コンパイルエラーになります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
$ clang constexpr.c -std=c2x constexpr.c:9:3: error: use of undeclared identifier 'constexpr' constexpr int i = 123; ^ constexpr.c:10:3: error: use of undeclared identifier 'constexpr' constexpr int j = i + 45; ^ constexpr.c:13:3: error: use of undeclared identifier 'constexpr' constexpr float f = 0.5; ^ constexpr.c:15:3: error: use of undeclared identifier 'constexpr' constexpr double d = 0.2; ^ constexpr.c:17:30: error: use of undeclared identifier 'i' printf("i = %d, j = %d\n", i, j); ^ constexpr.c:17:33: error: use of undeclared identifier 'j' printf("i = %d, j = %d\n", i, j); ^ constexpr.c:18:31: error: use of undeclared identifier 'f' printf("f = %f, d = %lf\n", f, d); ^ constexpr.c:18:34: error: use of undeclared identifier 'd' printf("f = %f, d = %lf\n", f, d); ^ 8 errors generated. |
digit separator
digit separatorは,数字の区切り記号「'」をサポートする機能です.
digit separatorがあると,桁数の多い数字が読みやすくなります.
digital separatorを利用するコードは以下になります.
例えば21行目でnumに代入する「0xffff'ffff'ffff'ffff」を「'」で区切ることで読みやすくなっていることがわかります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> #include <stdint.h> int main(void) { uint64_t num; num = 0xffff; printf("num = %016lx\n", num); num = 0xffff'ffff; printf("num = %016lx\n", num); num = 0xffff'ffff'ffff; printf("num = %016lx\n", num); num = 0xffff'ffff'ffff'ffff; printf("num = %016lx\n", num); return 0; } |
GCC 13.1の実行結果は以下になります.
1 2 3 4 5 6 |
$ gcc digit_separator.c -std=c2x $ a.out num = 000000000000ffff num = 00000000ffffffff num = 0000ffffffffffff num = ffffffffffffffff |
GCC 13.1で-std=c2xオプションがないとコンパイルエラーになります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
$ gcc digit_separator.c digit_separator.c: In function 'main': digit_separator.c:15:15: warning: missing terminating ' character 15 | num = 0xffff'ffff; | ^ digit_separator.c:15:15: error: missing terminating ' character 15 | num = 0xffff'ffff; | ^~~~~~ digit_separator.c:15:15: error: expected ';' before 'printf' 15 | num = 0xffff'ffff; | ^ | ; 16 | printf("num = %016lx\n", num); | ~~~~~~ digit_separator.c:18:15: warning: multi-character character constant [-Wmultichar] 18 | num = 0xffff'ffff'ffff; | ^~~~~~ digit_separator.c:18:15: error: expected ';' before '\x66666666' 18 | num = 0xffff'ffff'ffff; | ^~~~~~ | ; digit_separator.c:21:15: warning: multi-character character constant [-Wmultichar] 21 | num = 0xffff'ffff'ffff'ffff; | ^~~~~~ digit_separator.c:21:15: error: expected ';' before '\x66666666' 21 | num = 0xffff'ffff'ffff'ffff; | ^~~~~~ | ; digit_separator.c:21:25: warning: missing terminating ' character 21 | num = 0xffff'ffff'ffff'ffff; | ^ digit_separator.c:21:25: error: missing terminating ' character 21 | num = 0xffff'ffff'ffff'ffff; | ^~~~~~ |
Clang 16.0の実行結果(-std=c2xオプションあり/なし)は以下になります.同様です.
1 2 3 4 5 6 |
$ clang digit_separator.c -std=c2x $ a.out num = 000000000000ffff num = 00000000ffffffff num = 0000ffffffffffff num = ffffffffffffffff |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
$ clang digit_separator.c digit_separator.c:15:15: warning: missing terminating ' character [-Winvalid-pp-token] num = 0xffff'ffff; ^ digit_separator.c:15:15: error: expected ';' after expression num = 0xffff'ffff; ^ ; digit_separator.c:15:15: error: expected expression digit_separator.c:18:15: error: expected ';' after expression num = 0xffff'ffff'ffff; ^ ; digit_separator.c:18:21: error: expected ';' after expression num = 0xffff'ffff'ffff; ^ ; digit_separator.c:18:21: error: use of undeclared identifier 'ffff' digit_separator.c:21:15: error: expected ';' after expression num = 0xffff'ffff'ffff'ffff; ^ ; digit_separator.c:21:21: error: expected ';' after expression num = 0xffff'ffff'ffff'ffff; ^ ; digit_separator.c:21:25: warning: missing terminating ' character [-Winvalid-pp-token] num = 0xffff'ffff'ffff'ffff; ^ digit_separator.c:21:21: error: use of undeclared identifier 'ffff' num = 0xffff'ffff'ffff'ffff; ^ digit_separator.c:18:15: warning: expression result unused [-Wunused-value] num = 0xffff'ffff'ffff; ^~~~~~ digit_separator.c:21:15: warning: expression result unused [-Wunused-value] num = 0xffff'ffff'ffff'ffff; ^~~~~~ |
2進数リテラル
2進数リテラルは,「0b10100101」のように2進数表記ができる機能です.
2進数で値を設定したい時に便利です.
2進数リテラルのコードは以下になります.
以下のコードでは利用していませんが,先述したdigit separatorと組み合わせると読みやすくなります.
また,printf関数の%bは2進数を表示するGCCの拡張機能です.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> #include <stdint.h> int main(void) { uint8_t num = 0b10100101; printf("num = 0b%08b\n", num); return 0; } |
GCC 13.1の実行結果は以下になります.
1 2 3 |
$ gcc binary_literal.c -std=c2x $ a.out num = 0b10100101 |
GCC 13.1で-std=c2xオプションがない場合,GCCの拡張機能でサポートしているので,正常に動作します.
1 2 3 |
$ gcc binary_literal.c $ a.out num = 0b10100101 |
Clang 16.0の実行結果(-std=c2xオプションあり/なし)は以下になります.同様です.
1 2 3 |
$ clang binary_literal.c -std=c2x $ a.out num = 0b10100101 |
1 2 3 |
$ clang binary_literal.c $ a.out num = 0b10100101 |
#elifdef/#elifndef
#elifdef/#elifndefは,#ifdefの制御文とペアで利用する時のマクロです.
つまり,以下が同等になります.
- 「#if defined(A) ... #elif defined(B) ...」と「#ifdef A ... #elifdef B ...」が同等
- 「#if !defined(A) ... #elif !defined(B) ...」と「#ifndef A ... #elifndef B ...」が同等
#elifdef/#elifndefのコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> int main(void) { char c; int i; #ifdef A c = 'A'; #elifdef B c = 'B'; #else c = 'Z'; #endif #ifndef NOT_ONE i = 1; #elifndef NOT_TEN i = 10; #else i = 0; #endif printf("c = %c, i = %d\n", c, i); return 0; } |
GCC 13.1の実行結果は以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ gcc elifdef_elifndef.c -std=c2x $ a.out c = Z, i = 1 $ gcc elifdef_elifndef.c -std=c2x -D=A $ a.out c = A, i = 1 $ gcc elifdef_elifndef.c -std=c2x -D=B $ a.out c = B, i = 1 $ gcc elifdef_elifndef.c -std=c2x -D=NOT_ONE $ a.out c = Z, i = 10 $ gcc elifdef_elifndef.c -std=c2x -D=NOT_ONE -DNOT_TEN $ a.out c = Z, i = 0 |
GCC 13.1で-std=c2xオプションがない場合,GCCの拡張機能でサポートしているので,正常に動作します.
実行結果は省略します.
1 |
$ gcc elifdef_elifndef.c |
Clang 16.0で-std=c2xオプションありも同様です.
実行結果は省略します.
1 2 3 |
$ clang elifdef_elifndef.c -std=c2x $ a.out c = Z, i = 1 |
Clang 16.0で-std=c2xオプションなしの場合は,コンパイル時に警告がでますが,正常に動作します.
実行結果は省略します.
1 2 3 4 5 6 7 8 |
$ clang elifdef_elifndef.c elifdef_elifndef.c:14:2: warning: use of a '#elifdef' directive is a C2x extension [-Wc2x-extensions] #elifdef B ^ elifdef_elifndef.c:22:2: warning: use of a '#elifndef' directive is a C2x extension [-Wc2x-extensions] #elifndef NOT_TEN ^ 2 warnings generated. |
typeof/typeof_unqual
typeof/typeof_unqualは,式から型情報を取り出すことができる演算子です.
typeofは型情報をそのまま取り出し,typeof_unqualは型修飾子(例:const)を削除して取り出します.
typeof/typeof_unqualのコードは以下になります.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/* * Author: Hiroyuki Chishiro * License: 2-Clause BSD */ #include <stdio.h> int main(void) { const int i = 123; // const int typeof(i) j = 45; // const int typeof_unqual(i) k = 6; // int // j++; // NOTE: error if uncomment. k++; printf("i = %d, j = %d, k = %d\n", i, j, k); return 0; } |
GCC 13.1の実行結果は以下になります.
1 2 3 |
$ gcc typeof_typeof_unqual.c -std=c2x $ a.out i = 123, j = 45, k = 7 |
GCC 13.1で-std=c2xオプションがない場合,コンパイルエラーになります.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ gcc typeof_typeof_unqual.c typeof_typeof_unqual.c: In function 'main': typeof_typeof_unqual.c:11:3: warning: implicit declaration of function 'typeof_unqual' [-Wimplicit-function-declaration] 11 | typeof_unqual(i) k = 6; // int | ^~~~~~~~~~~~~ typeof_typeof_unqual.c:11:19: error: expected ';' before 'k' 11 | typeof_unqual(i) k = 6; // int | ^~ | ; typeof_typeof_unqual.c:14:3: error: 'k' undeclared (first use in this function) 14 | k++; | ^ typeof_typeof_unqual.c:14:3: note: each undeclared identifier is reported only once for each function it appears in |
Clang 16.0の実行結果(-std=c2xオプションあり/なし)は以下になります.同様です.
1 2 3 |
$ clang typeof_typeof_unqual.c -std=c2x $ a.out i = 123, j = 45, k = 7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ clang typeof_typeof_unqual.c typeof_typeof_unqual.c:11:3: error: call to undeclared function 'typeof_unqual'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] typeof_unqual(i) k = 6; // int ^ typeof_typeof_unqual.c:11:19: error: expected ';' after expression typeof_unqual(i) k = 6; // int ^ ; typeof_typeof_unqual.c:11:20: error: use of undeclared identifier 'k' typeof_unqual(i) k = 6; // int ^ typeof_typeof_unqual.c:14:3: error: use of undeclared identifier 'k' k++; ^ typeof_typeof_unqual.c:16:44: error: use of undeclared identifier 'k' printf("i = %d, j = %d, k = %d\n", i, j, k); ^ 5 errors generated. |
まとめ
C言語のC23規格のプログラミングを紹介しました.
具体的には,C23規格の便利な機能の使い方を解説しました.
C23規格の有用な情報は以下になります.
C言語を独学で習得することは難しいです.
私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.
私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!
独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!