C++
 Computer >> コンピューター >  >> プログラミング >> C++

64ビット版GCCでC/C++の32ビットプログラムをコンパイルする方法

近年のGCCコンパイラは、デフォルトで64ビット版として提供されています。しかし、開発の現場では32ビット環境向けにコードをコンパイル・実行する必要が生じることがあります。そんなときに役立つのが、GCCの-m32オプションです。

この記事では、64ビット版GCCを使って32ビットプログラムをコンパイルする手順と、発生しうるエラーへの対処法を解説します。

1. 現在のGCCのターゲット環境を確認する

まず、使用しているGCCがどのアーキテクチャ向けにビルドされているかを確認しましょう。以下のコマンドを実行します。

gcc –v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
...........
...........
...........

出力に「Target: x86_64-linux-gnu」と表示されている場合、これは64ビット版のGCCを使用していることを意味します。

2. -m32オプションで32ビット向けにコンパイルする

32ビット環境向けにコンパイルするには、以下のように-m32フラグを付けてコンパイルします。

gcc –m32 program_name.c

3. 標準ライブラリが不足している場合の対処法

このコマンドを実行すると、環境によっては次のようなエラーが発生することがあります。これは、32ビット用のGCC標準ライブラリがインストールされていないことを示しています。

In file included from test_c.c:1:0:
/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file
or directory
#include <bits/libc-header-start.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

この場合は、以下のコマンドで32ビット用の標準ライブラリ(multilib)をインストールしましょう。

sudo apt-get install gcc-multilib
sudo apt-get install g++-multilib

C言語だけでなくC++でも32ビットコンパイルを行いたい場合は、g++-multilibのインストールが必要です。

4. 32ビットと64ビットの実行結果の違いを確認する

それでは、実際に32ビット環境と64ビット環境での実行結果の違いを見てみましょう。ここでは、long型のサイズを出力する簡単なプログラムを使用します。

サンプルコード

#include<stdio.h>
main() {
    printf("The Size is: %lu\n", sizeof(long));
}

64ビットでコンパイルした場合の出力

$ gcc test_c.c
test_c.c:3:1: warning: return type defaults to ‘int’ [-Wimplicit-int] main(){
^~~~
$ ./a.out
The Size is: 8

64ビット環境では、long型のサイズは8バイト(64ビット)として出力されます。

32ビットでコンパイルした場合の出力

$ gcc -m32 test_c.c
test_c.c:3:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
main(){
^~~~
test_c.c: In function ‘main’:
test_c.c:4:28: warning: format ‘%lu’ expects argument of type ‘long unsigned
int’, but argument 2 has type ‘unsigned int’ [-Wformat=]
printf("The Size is: %lu\n", sizeof(long));
~~^
%u
$ ./a.out
The Size is: 4

一方、32ビット環境ではlong型のサイズは4バイト(32ビット)になります。このように、同じソースコードでもターゲットのアーキテクチャによってデータ型のサイズが異なるため、移植性を考慮したコーディングが重要になります。

なお、32ビットコンパイル時には「%lu」フォーマット指定子と実際の引数の型が一致しないという警告(-Wformat=)が表示されることがあります。これは、32ビット環境ではsizeof(long)の戻り値の型がunsigned intとして扱われるためです。警告を避けたい場合は、フォーマット指定子を環境に応じて調整するとよいでしょう。

まとめ

64ビット版GCCで32ビットプログラムをコンパイルするには、-m32オプションを使用し、必要に応じてgcc-multilibおよびg++-multilibをインストールします。32ビットと64ビットではデータ型のサイズが異なる点に注意し、クロスプラットフォーム開発では型のサイズに依存しないコードを心がけましょう。

  1. C++で対角行列・スカラー行列を判定するプログラムの書き方

    行列 M[r][c] が与えられたとき、「r」は行数、「c」は列数を表し、r = c のとき正方行列となります。本記事では、与えられた正方行列が対角行列であるか、スカラー行列であるかを判定し、該当する場合には「yes」を出力する方法を解説します。 対角行列とは 正方行列 m[][] が対角行列であるのは、主対角線以外の要素がすべてゼロである場合、かつその場合に限ります。 下図のように、赤色で示された要素が主対角成分(非ゼロ)であり、それ以外の要素はすべてゼロになっているため、この行列は対角行列です。 入出力例 Input: m[3][3] = { {7, 0, 0}, {0, 8, 0}

  2. C++で立方体の体積と表面積を求めるプログラム

    立方体とは? 立方体とは、正方形の面を6つ持つ三次元の立体図形です。すべての辺の長さが等しいという特徴があります。立方体は唯一の正六面体であり、以下のような性質を持ちます。 面の数:6つ 辺の数:12本 頂点の数:8つ 以下は立方体の図です。 問題の概要 立方体の一辺の長さが与えられたとき、その立方体の表面積と体積を求めることが課題です。ここで、表面積とは立方体の各面が占める面積の合計を指し、体積とはその図形が内包できる空間の大きさを指します。 立方体の表面積と体積を計算するには、次の公式を使用します。 表面積 = 6 × 辺 × 辺 体積 = 辺 × 辺 × 辺 入力例と出力例 入力