C LANGUAGE TECHNOLOGY

【C言語】C23規格のプログラミング【GCC 13.1/Clang 16.0を利用】【使い方】

悩んでいる人

C言語のC23規格のプログラミングを教えて!

こういった悩みにお答えします.

本記事の信頼性

  • リアルタイムシステムの研究歴12年.
  • 東大教員の時に,英語でOS(Linuxカーネル)の授業.
  • 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校(UNC)コンピュータサイエンス学部で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発.
  • プログラミング歴15年以上,習得している言語: C/C++PythonSolidity/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)の業務委託の経験あり.
    • (スマートコントラクトのプログラミングを含む)イーサリアムや仮想通貨全般の記事を250本以上執筆.イギリスのロンドンの会社で仮想通貨の英語の記事を日本語に翻訳する業務委託の経験あり.

こういった私から学べます.

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のビルド方法を紹介していきます.

まずは以下のコマンドを入力してビルド環境をインストールして下さい.

GCC 13.1のソースコードをダウンロード,ビルドします.

ビルドは1時間以上かかります.

上記のビルドエラーが出る場合は,以下を入力して修正して下さい.

ビルドが成功したら,以下のコマンドでインストールして下さい.

GCC 13.1が正常にインストールできているか以下のコマンドで確認して下さい.

Clang 16.0のインストール方法

Clang16.0のインストール方法はこちらが参考になります.

まずは/etc/apt/source.listをバックアップします.

次に/etc/apt/source.listに以下を追加します.

Clang 16.0をインストールします.

clang-16をclangで利用できるように変更します.

clangを実行してバージョンが16になっているか確認して下さい.

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.1Clang 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を利用するコードは以下になります.

GCC 13.1の実行結果は以下になります.

コンパイル時にC23規格を有効にするオプション「-std=c2x」をつけるのを忘れないようにして下さい.GCC 13.1のデフォルトではC17規格になります.

GCC 13.1で-std=c2xオプションがないとコンパイル時に警告が発生し,dがdouble型ではなくint型と認識されてしまうため,「d = 0.000000」と表示されてしまいます.

Clang 16.0ではauto(型推論)をサポートしていないため,コンパイルエラーになります.

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は正常に動作します.

興味があるあなたはコメントを外してみましょう.

GCC 13.1の実行結果は以下になります.

GCC 13.1で-std=c2xオプションがないとコンパイルエラーになります.

Clang 16.0はconstexprをサポートしていないので,コンパイルエラーになります.

digit separator

digit separatorは,数字の区切り記号「'」をサポートする機能です.

digit separatorがあると,桁数の多い数字が読みやすくなります.

digital separatorを利用するコードは以下になります.

例えば21行目でnumに代入する「0xffff'ffff'ffff'ffff」を「'」で区切ることで読みやすくなっていることがわかります.

GCC 13.1の実行結果は以下になります.

GCC 13.1で-std=c2xオプションがないとコンパイルエラーになります.

Clang 16.0の実行結果(-std=c2xオプションあり/なし)は以下になります.同様です.

2進数リテラル

2進数リテラルは,「0b10100101」のように2進数表記ができる機能です.

2進数で値を設定したい時に便利です.

2進数リテラルのコードは以下になります.

以下のコードでは利用していませんが,先述したdigit separatorと組み合わせると読みやすくなります.

また,printf関数の%bは2進数を表示するGCCの拡張機能です.

GCC 13.1の実行結果は以下になります.

GCC 13.1で-std=c2xオプションがない場合,GCCの拡張機能でサポートしているので,正常に動作します.

Clang 16.0の実行結果(-std=c2xオプションあり/なし)は以下になります.同様です.

#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のコードは以下になります.

GCC 13.1の実行結果は以下になります.

GCC 13.1で-std=c2xオプションがない場合,GCCの拡張機能でサポートしているので,正常に動作します.

実行結果は省略します.

Clang 16.0で-std=c2xオプションありも同様です.

実行結果は省略します.

Clang 16.0で-std=c2xオプションなしの場合は,コンパイル時に警告がでますが,正常に動作します.

実行結果は省略します.

typeof/typeof_unqual

typeof/typeof_unqualは,式から型情報を取り出すことができる演算子です.

typeofは型情報をそのまま取り出し,typeof_unqualは型修飾子(例:const)を削除して取り出します.

typeof/typeof_unqualのコードは以下になります.

GCC 13.1の実行結果は以下になります.

GCC 13.1で-std=c2xオプションがない場合,コンパイルエラーになります.

Clang 16.0の実行結果(-std=c2xオプションあり/なし)は以下になります.同様です.

まとめ

C言語のC23規格のプログラミングを紹介しました.

具体的には,C23規格の便利な機能の使い方を解説しました.

C23規格の有用な情報は以下になります.

C言語を独学で習得することは難しいです.

私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.

私のキャパシティもあり,一定数に達したら終了しますので,今すぐ追加しましょう!

友だち追加

独学が難しいあなたは,元東大教員がおすすめするC言語を学べるオンラインプログラミングスクール5社で自分に合うスクールを見つけましょう.後悔はさせません!

-C LANGUAGE, TECHNOLOGY
-, , , , ,