【C++】DebugとReleaseビルドの違いとは?|使い分けをわかりやすく解説

サムネイル画像 C++

今回は、C++での「Debug ビルドと Release ビルドの違い」について解説していきます。

「DebugとReleaseって何が違うの?」「どっちを使えばいいの?」と疑問に思ったことはありませんか?

この記事を読み終えると、あなたはDebugとReleaseの違いを理解し、適切に使い分けられるようになると思いますので、ぜひ最後まで読んでいただけると嬉しいです。

ビルド構成とは?

ビルド構成とは、プログラムをコンパイルする際の設定の組み合わせのことです。

C++の開発では、主に2つのビルド構成があります。

  • Debug(デバッグ)ビルド:開発中に使う
  • Release(リリース)ビルド:配布・公開する時に使う

それぞれ詳しく見ていきましょう。

Debugビルドとは?

Debugビルドは、開発者がプログラムをデバッグしやすいように作られたビルドです。

Debugビルドの特徴

  • デバッグ情報が含まれる:変数名、行番号などが保持される
  • 最適化が無効:コードが書いた通りに実行される
  • ブレークポイントが使える:デバッガで一時停止できる
  • 変数の値を確認できる:実行中に変数を監視できる
  • 実行速度が遅い:最適化されていないため
  • ファイルサイズが大きい:デバッグ情報が含まれるため

Debugビルドの使い道

  • プログラムの開発中
  • バグの原因を調査する時
  • 変数の値を確認したい時
  • ステップ実行でコードを追いかけたい時

Releaseビルドとは?

Releaseビルドは、配布・公開するために最適化されたビルドです。

Releaseビルドの特徴

  • 最適化が有効:実行速度が速くなる
  • ファイルサイズが小さい:デバッグ情報が削除される
  • 実行速度が速い:コンパイラが最適化する
  • デバッグ情報がない:変数名や行番号が失われる
  • デバッグしにくい:ブレークポイントが正しく動作しない場合がある
  • 最適化により動作が変わる:コードの実行順序が変わることがある

Releaseビルドの使い道

  • ユーザーに配布する時
  • 性能測定(ベンチマーク)をする時
  • 最終的な動作確認をする時
  • 製品版として公開する時

具体的な違いを見てみる

簡単なプログラムで、DebugとReleaseの違いを確認してみましょう。

▼main.cpp

#include <iostream>
#include <chrono>

int main() {
    auto start = std::chrono::high_resolution_clock::now();
    
    // 大量の計算
    long long sum = 0;
    for (int i = 0; i < 100000000; i++) {
        sum += i;
    }
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
    std::cout << "sum: " << sum << "\n";
    std::cout << "time: " << duration.count() << "ms\n";
    
    return 0;
}

実行結果の例

Debug ビルド: 約200ms
Release ビルド: 約5ms

Releaseビルドは、Debugビルドに比べて数十倍速くなることもあります

最適化の具体例

Releaseビルドでは、コンパイラがさまざまな最適化を行います。

1. 不要なコードの削除

▼main.cpp

#include <iostream>

int main() {
    int x = 10;
    int y = 20; // この変数は使われていない
    
    std::cout << x << "\n";
    
    return 0;
}

Releaseビルドでは、使われていない変数yが削除される場合があります。

2. インライン展開

▼main.cpp

#include <iostream>

int add(int a, int b) {
    return a + b;
}

int main() {
    int result = add(3, 5);
    std::cout << result << "\n";
    
    return 0;
}

Releaseビルドでは、関数呼び出しがインライン展開されることがあります。

つまり、内部的には以下のように変換されます。

int result = 3 + 5; // 関数呼び出しのオーバーヘッドがなくなる

3. ループの最適化

▼main.cpp

#include <iostream>

int main() {
    int sum = 0;
    for (int i = 0; i < 100; i++) {
        sum += 1;
    }
    std::cout << sum << "\n";
    
    return 0;
}

Releaseビルドでは、ループが展開されたり、計算結果が事前計算されることがあります。

int sum = 100; // ループを実行せずに結果だけ代入

デバッグ情報の違い

Debugビルドには、デバッグ情報(PDB ファイルなど)が含まれます

Debugビルド

  • 変数名が保持される
  • ソースコードの行番号が保持される
  • 関数名が保持される
  • ブレークポイントで止められる
  • 変数の値をウォッチできる

Releaseビルド

  • 変数名が削除される
  • 行番号が不正確になる
  • 関数名が短縮される
  • ブレークポイントが正しく動作しない場合がある
  • 変数が最適化で消される場合がある

切り替え方法

主要な開発環境でのビルド構成の切り替え方法です。

Visual Studio

  1. 上部のツールバーで「Debug」または「Release」を選択
  2. または、プロジェクトのプロパティから設定

Visual Studio Code

  1. CMakeLists.txtでCMAKE_BUILD_TYPEを指定
  2. または、コマンドラインで-DCMAKE_BUILD_TYPE=DebugまたはReleaseを指定

コマンドライン(g++)

# Debug ビルド
g++ -g -O0 main.cpp -o main_debug

# Release ビルド
g++ -O2 main.cpp -o main_release
  • -g:デバッグ情報を含める
  • -O0:最適化なし
  • -O2:最適化レベル2

注意点

1. Releaseでしか起きないバグがある

最適化により、Debugでは正常に動いてもReleaseでバグが出る場合があります。

▼main.cpp

#include <iostream>

int main() {
    int x;
    // 初期化を忘れている!
    
    // Debugでは偶然0になることが多い
    // Releaseではゴミ値が入ることがある
    std::cout << x << "\n";
    
    return 0;
}

このような場合、必ずReleaseビルドでもテストすることが重要です。

2. 性能測定は必ずReleaseで

プログラムの実行速度を測定する場合は、必ずReleaseビルドで行いましょう

Debugビルドの速度は、実際の性能を反映していません。

3. 配布するのはReleaseビルド

ユーザーに配布するのは、必ずReleaseビルドです。

Debugビルドを配布すると、以下の問題があります。

  • 実行速度が遅い
  • ファイルサイズが大きい
  • ソースコードの情報が漏れる可能性がある

どちらを使うべき?

状況使うべきビルド
プログラムを開発中Debug
バグを調査しているDebug
変数の値を確認したいDebug
性能測定をするRelease
最終動作確認Release
ユーザーに配布するRelease

開発中はDebug、配布前にはReleaseでテストというのが基本です。

まとめ

Debug ビルドと Release ビルドの違いをまとめます。

  • Debug:開発・デバッグ用。遅いがデバッグしやすい
  • Release:配布・公開用。速いがデバッグしにくい
  • Releaseは最適化により実行速度が大幅に向上する
  • デバッグ情報の有無が大きな違い
  • 開発中はDebug、配布前はReleaseでテスト
  • 性能測定は必ずReleaseで行う

これでDebugとReleaseの違いはバッチリですね!

適切なビルド構成を選んで、効率的な開発を進めてください。

ここまで読んでくださり、ありがとうございました。

この記事が皆様の学習に役立てば幸いです。