開発環境を整える編集

Windowsの場合編集

Visual Stuido による方法編集

2021年現在、マイクロソフト社が開発・販売しているVisual Studio は、C/C++コンパイラを内包しており、配布条件に従えば無料で使えるバージョンもあります。 Visual Studio の利用にはアカウント登録(無料)が必要です。


GNU/Linuxの場合編集

GNU/Linux(リナックス)で「C++(シープラスプラス)」プログラムを開発する場合、ペッケージ「gcc-c++」を用意する。(リナックス の一っ種「Fedora」(フェドラ)で実機で確認。)

なお、「gcc」(ジーシーシー)については、『C言語/はじめに#開発環境を整える』を参照せよ。


とにかく、C++プログラミングのために、まず「gcc-c++」をインストールする必要がある。 Fedoraをインストールしたばかりの標準状態では、まだ「gcc-c++」はインストールされてないので、自分で追加インストールする必要がある。

「gcc-c++」を利用するには、コマンド端末(いわゆる「ターミナル」(terminal) )を使い、端末内部にてコマンド「g++」を入力する。つまり、

g++ ファイル名.cpp

のようなコマンドである。 (リナックスfedora26で動作を確認)

このように、コマンド端末(いわゆる「ターミナル」(terminal) )が必要である。ターミナルの使い方が分からない場合は、まず、ターミナルの使い方を勉強する必要がある。 (コマンド端末の最低限の使い方については、『プログラミング/共通知識』で紹介してある。)

clang編集

GCC系のコンパイラ以外にも、clangというオープンソースのC言語系コンパイラがある。

なお、(GNU/Linuxではないが)FreeBSDやOpenBSDなどBSD系Unixでは、gcc のライセンス GPL を回避と性能面やコードのメンテナンスの容易さなどの理由で、clangが標準のC言語コンパイラとして採用されている。 マックで有名なアップル・コンピュータも、clangを援助している(macOSのユーザーランドは FreeBSD のフォーク)。


さて、その clang のインストールは、Fedora なら

sudo dnf install clang

でclang用の標準C言語コンパイラもC++コンパイラも一緒に入る。

C++のコンパイルのコマンドは

clang++ ファイル名.cpp

である。

C++の用途編集

C++には、下記のような利点があります。

Windowsで標準的な言語として採用されている編集

一般的には、Windowsでアプリケーション開発をする際、Windowsが提供する統合開発環境 Visual Studio において基盤のプログラミング言語として採用している言語が、C++系のVisual C++ および C#系のVisual C# ですので、Windowsアプリを作成したい場合に、C++ の知識が必要になる可能性があります(C#はC++とは別の言語です。また標準C言語とのソース互換性は、C#にはありません。)。

なお余談ですが、Visual Studio は標準C言語のコンパイラを内包しており、C言語のソースを(C++のソースとしてではなく、ネイティブに)コンパイルすることが出来ます。例えば、ソースファイルの拡張子が(.cppではなく).c であれば標準C言語のコンパイラでコンパイルされ、sizeof(char) == sizeof(int) のような標準Cとしての挙動を示します[1]

また、Linux kernel は記述言語にGCCを採用しています[2][3]。ただし、GNU/Linuxと称されるLinuxカーネルとGNUプロジェクトの成果物などのオープンソースのプログラムを組み合わせてOSの体をなした「ディストリビューション」のユーザーランドではC++で記述されたものもあります。例えば、GCC自身はC++で記述されています)。

標準C言語とのイイとこ取りができるか?編集

C++の規格上、C++には標準Cと間にある程度のソース互換性があるので、プログラマ視点では、標準C言語のコードの流用が可能です。

なので、C言語で書くと記述が長くなったり複雑になったりするコードに関してはC++で書く、などといったご都合主義な利用方法を企てることの可能です。

ただし、細かい意味論の違いなどで生じるトラブルに見舞われた場合、両言語の標準仕様に精通していないと原因究明以前に、何が起こっているかの理解もままならないので、ミックスドランゲージプロジェクトには相応のリクスを伴い、問題解決にアセンブリ言語の知識を必要とする状況が珍しくありません。

例えばここで示す、C/C++の1つのソースコードでの混在例の初期のコードは、printf()関数を使っているのに #include <cstdio> を忘れていたり、C++のストリームへの出力の後に printf() を呼出しているのに、<< flush を忘れており、環境によってはコンパイルにすら失敗していました。

CとC++の標準ライブラリーをミックスして使ったC++のコード
#include <iostream>
#include <cstdio>
using namespace std;

int main() {
    cout << "ようこそwelcome C++" << endl << flush; // C++のコード。ストリームバッファのフラッシュを忘れずに
    printf("こっちは標準C言語で出力\n"); // Cのコード
}

上記コードの出力結果は、

ようこそwelcome C++
こっちは標準C言語で出力

です。

このように、C++はCとの間に相互運用性があります。

C++特有の文法には「クラス」など、標準Cにない機能があり、そこは学習コストが高いのですが、しかしそういった学習コストの高い部分を後回しにしてプログラミングを開始することがC++では可能です。

CとC++の非互換性編集

とはいえ、CとC++は別の言語なので、根本的な意味論に差異に直面することはしばしばあります。

自動昇格の有無編集

Cと異なりC++では、 char は自動的に int には昇格しません。 CとC++で文字リテラルに sizeof 演算子を適用した結果を比較しましょう。

C言語のsizeof 'a'の値
#include <stdio.h>

int main() {
  printf("sizeof 'a' ⇒  %zu\n",  sizeof 'a');
}
実行結果
sizeof('a') => 4
C言語では、char は int に自動昇格するのでintのバイト数(この場合は 4)が返ります。
つぎに、同じソースコードを C++ でコンパイルして実行してみます。
C++のsizeof 'a'の値
#include <stdio.h>

int main() {
  printf("sizeof 'a' ⇒ %zu\n", sizeof 'a');
}
実行結果
sizeof('a') => 1
結果が異なりますね。
これは、C言語はcharがintに自動昇格する仕様であるのに対し、C++では自動昇格されないためです。

この違いは、C++には関数オーバーロードの仕組みがあり

int func(int i);
int func(char ch);

上記の2つの関数があったとき、両者は引数の違いによってのみ区別され、勝手に int に昇格される仕様では都合が悪いからです。

1文字をパラメーターとする関数のパラメーターを int で定義すると、Cなら有効ですがC++では未定義関数の呼出しとなります。

新しいキーワード編集

C++では、classなどが新しくキーワードになり変数名や関数名などの識別子に使えなくなりました。

 int class = 0; // C++ ではエラー
ポインタの代入の厳密さ編集

Cではポインタをvoid*に変換することができますが、C++では明示的な変換が必要です。以下は、C++では違法ですが、Cでは合法です。

void* ptr = NULL;
int* iptr = ptr; // C++ ではエラー
初期化を含む宣言の飛越し編集

C++では、gotoやswitchで初期化を無視することはできません。 以下は、C言語では有効ですが、C++では無効です。

goto label;
int skip = 1; // C++では初期化される
label:
再宣言の禁止編集

C++では、再宣言は許されません。

struct X { int i; struct X *next; }; 
static struct X a; 
static struct X b = { 0, &a }; 
static struct X a = { 1, &b };
このコードはCならば正しいのですが、C++では a が再宣言となりエラーとなります。
struct スコープ編集

C++では、struct はスコープを持ちます(structはclassです)。 Cでは、struct はスコープを持ちません(classはありません)。


この様に、CとC++とには有意な差異があるのでCをバックグランドとするプログラマーが、C++に転向するときには新機能以外にも差異を学ぶ転換教育が必要です。

脚註編集

  1. ^ /std (言語の標準バージョンの指定) §C 標準のサポート
  2. ^ 基本的に標準C言語ですが、一部に asm goto などのGNU拡張を使用しています
  3. ^ GCCに対して高い互換性をもつClang/LLVMでも9.0.0からLinuxカーネルをコンパイルできます。