今回は、C++(C++11以降)にあってC11にない機能を紹介します。といっても、細かい機能については次回以降の関連する記事で説明するとして、今回は比較的大きな機能に限って扱うことにします。

C言語からC++に取り込まれた機能を除いて、C++14以降で追加された機能はC11にもありませんので、以下はC++11との比較と考えてください。

クラス

C++では、クラスキーがstructのクラスを「構造体」、クラスキーがunionのクラスを「共用体」と呼びました。しかし、C11にはクラスという概念はありませんので、構造体や共用体はクラスではなく、別の概念になります。ただし、それはあくまでも考えかただけの話であり、実際にプログラミングで使用する際には同じだと考えても差し支えありません。なお、機能は大幅に制限されています。

まず、コンストラクタやデストラクタを含めて、メンバ関数を定義することができません。静的メンバを定義することもできません。アクセス指定子を使うこともできません。継承もできません。単純にデータメンバを並べることしかできません。

構造体と共用体は後ほど詳しく解説したいと思います。

テンプレート

C11にはテンプレートの機能はまったくありません。テンプレートの機能に近いことを実現するには、マクロを使うのが普通です。

例外処理

C11には例外処理はありません。近いことを実現するにはふたつの方法があります。ひとつは gotoを使う方法であり、もうひとつはsetjmpとlongjmpを使う方法です。ただし、gotoは関数の外へ分岐することはできません(C++でも同じです)。また、setjmpとlongjmpは必ずしも一般的ではありませんので、C++の例外のように、あたりまえのように使われるものではありません。longjmpで関数から飛び出してくることを想定するプログラマーはほぼいませんので、できれば避けた方がよさそうです。

名前空間

C++の名前空間の機能はC11にはありません。C11の標準規格にも「名前空間(name space)」という用語が出てきますが、まったく別の意味です。すなわち、識別子は次に挙げるどれかの名前空間に属し、異なる名前空間どうしであれば、同じ名前をつけても別物として扱われるというものです。

  • 関数原型
  • ラベル名
  • 構造体、共用体、列挙体のタグ名
  • 構造体と共用体のメンバ
  • その他の識別子

C++における名前空間がないため、関数の外部の有効範囲(いわゆるグローバルなスコープ)は、「大域的名前空間有効範囲」ではなく「ファイル有効範囲」という呼びかたをします。また、クラス有効範囲というものもありませんので、構造体や共用体のメンバは特別な有効範囲に属しているのではなく、(C11でいうところの)名前空間が異なるという扱いになります。

ラムダ式

C11ではラムダ式を使うことはできません。類似の機能もありませんが、GCCやClangであればブロックを丸括弧で囲んで式にする独自拡張があります。

属性構文

C11では[[fallthrough]]のような属性構文を使うことができません。ただし、処理系の独自拡張で類似の機能が使える場合はあります。


↑ モダンC++プログラマーのためのC11入門