C言語の_Genericキーワードとは?型に応じて動作するマクロの作り方
C言語やC++では、#defineによるマクロが広く使われています。しかし、従来のマクロには型チェックの仕組みが存在しないという大きな弱点があります。そのため、マクロにはint・float・charなど、どんな型の引数でも渡せてしまいます。次の例で、この挙動を確認してみましょう。
例:従来のマクロの場合
#include<stdio.h>
#define INCREMENT(X) ++X
main() {
int x = 5; float y = 2.56; char z = 'A';
printf("Integer Increment: %d\n", INCREMENT(x));
printf("Float Increment: %f\n", INCREMENT(y));
printf("Character Increment: %c\n", INCREMENT(z));
}
出力結果
Integer Increment: 6
Float Increment: 3.560000
Character Increment: B
このように、同じINCREMENTマクロがすべての型に対して一律に++Xを適用してしまうのが問題です。整数なら1加算されますが、char型では文字コードが1つ進むだけであり、型ごとに異なる処理を行うことはできません。これが従来のマクロの限界です。
そこで登場したのが、C11規格で導入された_Genericキーワードです。_Genericを使えば、引数の型をコンパイル時に判定し、型に応じて異なる式を選択する「型ジェネリックなマクロ」を定義できます。実際のコードを見てみましょう。
例:_Genericを使った場合
#include<stdio.h>
#define INCREMENT(X) _Generic( (X), char: X+10, int: X+1, float: X+2.5, default: 0)
main() {
int x = 5; float y = 2.56; char z = 'A';
printf("Integer Increment: %d\n", INCREMENT(x));
printf("Float Increment: %f\n", INCREMENT(y));
printf("Character Increment: %c\n", INCREMENT(z));
}
出力結果
Integer Increment: 6
Float Increment: 5.060000
Character Increment: K
_Genericのポイント
- int型の場合:
X+1が選ばれ、値は6になります。 - float型の場合:
X+2.5が選ばれ、2.56 + 2.5 = 5.06が出力されます。 - char型の場合:
X+10が選ばれ、'A'(65番)から10進んで'K'になります。
このように_Genericを活用することで、マクロでありながら型ごとに最適な処理を振り分けられるようになり、より安全で柔軟なコードを書くことが可能になります。なお、_GenericはC11以降で利用できる機能のため、古いコンパイラを使用している場合は対応バージョンへの更新が必要です。
-
JavaScriptのclassキーワードとは?クラス定義の基本をわかりやすく解説
ES6(ECMAScript 2015)で導入されたJavaScriptのクラスは、プロトタイプベースの継承に対する「構文糖衣(シンタックスシュガー)」と呼ばれています。実体は「特別な関数」であり、classキーワードを使うことで、より直感的で読みやすいコードとしてオブジェクト指向プログラミングを実現できます。 classキーワードによる基本的なクラス定義 classキーワードを使用したクラス定義の基本構文は以下の通りです。 class Person { // このクラスのコンストラクタ constructor(name) { this.name = name;
-
JavaScriptのthisキーワードとは?参照先のオブジェクトをわかりやすく解説
JavaScriptのthisキーワードは、そのキーワードが属しているオブジェクトを参照します。大きな特徴として、使用される文脈によって参照先が変化するという点があり、これがthisの挙動を理解するうえで重要なポイントとなります。 thisが参照するオブジェクトの一覧 単独で使用した場合、または通常の関数内: グローバルオブジェクト(ブラウザ環境では window オブジェクト)を参照します。 オブジェクトのメソッド内: そのメソッドを所有するオブジェクト自身を参照します。 イベントリスナー内: イベントを受け取ったHTML要素を参照します。 サンプルコード 以下は、JavaScriptの