7.

C / C++(.c/.h/.cpp/.hpp)完全ガイド — Dennis Ritchie・Stroustrup・gcc/clang・CMake

編集
この記事の要点
  • C は Dennis Ritchie が 1972 年に Bell 研究所で開発。UNIX 実装のために設計された静的型付きコンパイル言語
  • C++ は Bjarne Stroustrup が 1979 年に「C with Classes」として開始、1985 年に C++ 命名。オブジェクト指向・テンプレート・RAII を追加
  • ファイル構成は .c / .cpp(実装) と .h / .hpp(ヘッダ宣言)に分離。#include でテキスト的に貼り付ける
  • コンパイラは gcc / clang / msvc。ビルド管理は make / cmake / ninja
  • 標準ライブラリは C が stdio.h / stdlib.h 等、C++ は STL(<vector> / <map> / <string>
  • C++ はテンプレート(コンパイル時ジェネリクス)が強力。std::vector<int> は型ごとに具象化される
  • OS カーネル・ゲームエンジン(Unreal)・組み込み・ブラウザ(Chromium)・データベースなど低レベル領域で不可欠

概要

C 言語は、Dennis Ritchie が 1972 年に AT&T Bell 研究所で UNIX オペレーティングシステムを実装するために設計した、静的型付きの構造化プログラミング言語です。1989 年に ANSI C(C89)として標準化され、その後 C99 / C11 / C17 / C23 と改訂されています。ソースの拡張子は .c、宣言を分離するヘッダは .h。「ハードウェアに薄い抽象を被せただけ」と評されるほど低レベルで、ポインタ・手動メモリ管理・直接的なビット演算を備えます。OS カーネル・組み込み・デバイスドライバ・他言語のランタイムが今も C で書かれています。

C++ は、Bjarne Stroustrup が 1979 年に「C with Classes」として Bell 研で開発を開始し、1985 年に「C++」と命名、1998 年に ISO 標準化(C++98)された C 言語のスーパーセットです。C との互換性を保ちつつ、クラス・オブジェクト指向・テンプレート・例外処理・RAII(Resource Acquisition Is Initialization)を追加しました。拡張子は .cpp / .cc / .cxx、ヘッダは .hpp / .h / .hxx。C++11(2011 年)が「モダン C++」の起点で、auto・ラムダ式・スマートポインタ・ムーブセマンティクスが導入されました。以降 C++14 / 17 / 20 / 23 と 3 年周期で改訂されています。

両者ともコンパイラは GCC(GNU Compiler Collection)Clang(LLVM)MSVC(Microsoft Visual C++)が主要 3 種。ビルド管理には伝統的な make と Makefile、現代的には CMake(クロスプラットフォーム) + Ninja(高速ビルドツール)の組み合わせが主流です。パッケージマネージャは vcpkg(Microsoft)と Conan(コミュニティ)が二大ですが、Rust の cargo や Go の go modules ほど統一されていません。

C++ で特に強力なのがテンプレート(コンパイル時ジェネリクス)です。std::vector<int>std::vector<double> はコンパイル時にそれぞれ別の型として具象化(インスタンス化)され、Java の型消去とは対照的に実行時オーバーヘッドがゼロです。これがゼロコスト抽象の典型例です。

ファイル種類とビルド成果物

拡張子役割変換
.cC ソース入力
.hC / C++ 共用ヘッダ(宣言)#include で展開
.cpp / .cc / .cxxC++ ソース入力
.hpp / .hxxC++ 専用ヘッダ#include で展開
.o / .objオブジェクトファイル(中間)コンパイル結果
.a / .lib静的ライブラリリンク時に取り込まれる
.so / .dll / .dylib動的ライブラリ実行時にロード
実行バイナリ(拡張子なし / .exeリンク後の最終成果物gcc / clang / link.exe の出力

ビルドフロー: main.cpp → プリプロセッサ(#include 展開)→ コンパイル → main.o → リンク(標準ライブラリ・他オブジェクトと結合)→ 実行バイナリ。複数ファイルでは各 .cpp を独立にコンパイルし、最後にリンカが結合します。

「Hello, World」

// hello.c
#include <stdio.h>

int main(void) {
    printf("Hello, World\n");
    return 0;
}
// hello.cpp
#include <iostream>
#include <vector>
#include <string>

int main() {
    std::vector<std::string> words = {"Hello", "World"};
    for (const auto& w : words) {
        std::cout << w << " ";
    }
    std::cout << "\n";
    return 0;
}
$ gcc hello.c -o hello && ./hello
Hello, World

$ g++ -std=c++17 hello.cpp -o hello && ./hello
Hello World

パッケージ管理・ビルドツール

C / C++ には Rust の cargo や Go の go modules のような公式パッケージマネージャが存在しないのが弱点です。代わりに以下が広く使われます。

  • CMake: クロスプラットフォームのビルド構成記述。CMakeLists.txt から Makefile や Visual Studio プロジェクトを生成。
  • Make / Ninja: 実際にビルドを走らせる実行エンジン。Ninja は CMake と組み合わせて高速化。
  • vcpkg: Microsoft 製パッケージマネージャ。vcpkg install fmt で取得。
  • Conan: Python ベースのパッケージマネージャ。conanfile.txt で依存記述。
# CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(myapp CXX)
set(CMAKE_CXX_STANDARD 17)
add_executable(myapp main.cpp)
cmake -B build -G Ninja
cmake --build build
./build/myapp

関連言語との比較

項目CC++RustGo
メモリ管理完全手動 malloc/freeRAII + スマートポインタ所有権(コンパイル時)GC
オブジェクト指向なしあり(多重継承可)trait ベース埋め込み + interface
ジェネリクスなし(マクロで代用)テンプレート(具象化)ジェネリクス + trait bound1.18+ 型パラメータ
パッケージマネージャなし(OS パッケージ)vcpkg / Conan(非統一)cargo(公式統一)go modules(公式統一)
主用途OS / 組み込み / ドライバゲーム / ブラウザ / 高性能システム / WASMクラウド / サーバー

注意点・落とし穴

  • 未定義動作(Undefined Behavior, UB):配列範囲外アクセス・未初期化変数の使用・整数オーバーフロー(C++ では signed のみ)など、コンパイラが想定外の最適化を行う原因になる。
  • メモリリーク・use-after-free・二重解放:手動管理ゆえの古典的バグ。C++ では std::unique_ptr / std::shared_ptr で大幅に軽減できる。
  • ヘッダの循環インクルード#pragma once またはインクルードガード(#ifndef FOO_H)が必須。
  • テンプレートエラーが超長文:C++ のテンプレート展開エラーは数百行になることがある。concept(C++20)で改善。
  • ABI 非互換:コンパイラやバージョン違いで生成されたライブラリが互いにリンクできないことがある(特に C++)。C ABI は比較的安定。
  • クロスプラットフォーム差異:エンディアン・整数サイズ(long は LP64 / LLP64 で違う)・パスセパレータなど、移植時の罠が多い。

関連リンク

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Python(.py / .pyc)
  2. JavaScript(.js / .mjs / .cjs)
  3. TypeScript(.ts / .tsx)
  4. Go(.go)
  5. Rust(.rs)
  6. Java(.java / .class / .jar)
  7. C / C++(.c / .h / .cpp / .hpp)
  8. Ruby(.rb)
  9. Swift(.swift)
  10. Kotlin(.kt / .kts)

最近更新/作成されたページ