はじめに
Linuxのシェル環境で利用される c++ コマンドの実体と、OS内部における動作メカニズムを解説します。定番コンパイラである g++ との関係性を整理したうえで、サンプルコードを用いた実際のコンパイルおよびバイナリ実行までの一連の手順を詳しく見ていきましょう。
C++ビルド環境の導入とバージョン検証
Ubuntu上でC++プログラムの構築を始めるにあたり、標準的なコンパイラ群とライブラリを含むメタパッケージを導入します。端末で apt-get update -qq && apt-get install -y build-essential を実行し、必要なツールチェーンを一括でセットアップしましょう。

続いて、OS内で参照されている c++ コマンドがどのパスに配置されているかを調査するため、which c++ を実行します。

c++ --version を投入すると、システムが呼び出しているコンパイラの正確なリリース番号やターゲットアーキテクチャなどの詳細情報を取得できます。
⚙️ [押さえておきたい主要コンパイルオプション]
-o <file> : 出力されるバイナリ実行ファイルの名前を任意に定義します。-c : 実行可能バイナリへのリンク処理を行わず、中間ファイルであるオブジェクトファイル(.o)の生成にとどめます。-Wall : 潜在的なバグの原因となり得る記述を広く検知するため、主要な警告出力をすべて有効化します。-O2 : 実行速度とバイナリサイズのバランスを取りながら、実用的なコード最適化を施します。-std=<standard> : ビルド時に準拠させる言語規格(例: c++17, c++20)を明示的に指定します。-g : GDBなどのデバッガでソースコード追跡ができるよう、バイナリ内にデバッグ用シンボルを埋め込みます。

/usr/bin/c++のシンボリックリンク構造とg++の実体を紐解く
ファイルシステムの詳細を表示する ls -l /usr/bin/c++ を実行し、このコマンドがどのようなファイル属性を持ち、どこへシンボリックリンクが張られているかを確認します。
この検証を行うことで、コマンドが単なるエイリアスなのか、あるいは特定の管理機構下にあるのかが浮き彫りになります。

Debian/Ubuntu系ディストリビューションでは、コンパイラの切り替えを管理するためにalternativesシステムが採用されています。update-alternatives --display c++ 2>/dev/null || readlink -f /usr/bin/c++ を実行することで、リンク階層を末端までたどり、最終的にどの実体バイナリ(多くは特定のバージョンの g++)が呼び出されているのかを特定できます。

サンプルコード作成とc++コマンドによる実行バイナリの生成
動作検証用として、標準出力にメッセージを表示する最小限のソースコード hello.cpp を作成します。

作成した hello.cpp に対し、最適化と警告チェックを有効にした c++ コマンドを実行して実行可能ファイル hello をビルドします。
構文上の不備や警告対象が存在しなければ、標準出力には何も表示されず静かにプロンプトが戻り、ビルドが完了します。

カレントディレクトリに生成された hello バイナリを直接キックし、プログラムの稼働状態を確かめます。
ソース内で指定した文字列 "Hello from Linux c++!" がコンソール上に出力されていれば、正常にビルドが成功しています。

最新言語仕様の適用:-std=c++20によるモダンC++ビルド実践
近年のモダンな言語機能を活用するため、コンパイル時評価を行う constexpr や効率的な文字列参照を可能にする std::string_view を盛り込んだ modern.cpp を用意します。

新しい文法規則をコンパイラに認識させるため、-std=c++20 フラグを付与して c++ コマンドを実行し、modern という名前のバイナリを生成します。
文法エラーがなければ、追加のエラーメッセージを出すことなく即座にバイナリ構築が終了します。

完成した modern 実行ファイルを起動し、最新規格で書かれたロジックが期待通りに動作しているかを検証します。
ターミナルに "Modern C++20 on Ubuntu" というテキストが正しく表示されることを確認してください。

Linux環境における c++ コマンドの実態、g++ との内部的な結びつき、そして日常の開発で役立つコンパイル手法を一通り整理しました。
本稿で紹介した主要オプションを状況に応じて使い分けながら、快適なC++開発・ビルド環境を整えてみてください。