副作用が発生する式の評価順序に依存しないようにすること
解説
1, 2のようなコードの動作は未定義であり、 func1から実行されるのかfunc2から実行されるかは処理系依存。 必ず3のような書き方を行い、func1, func2が実行される順番を明示的に指定すること。
#include <stdio.h> int G_a; int x, y, z; int main(void){ /* 1. 非適合例 */ G_a = 11; x = func1() + func2(); //func1から実行されるとは限らない //func1から実行されたのはたまたま printf("x: %d\n", x); /* 2. 非適合例 */ G_a = 11; y = func2() + func1(); //func2から実行されるとは限らない //func2から実行されたのはたまたま printf("y: %d\n", y); /* 3. 適合例 */ G_a = 11; z = func1(); //確実にfunc1から実行される z += func2(); printf("z: %d\n", z); return 0; } int func1(void) { G_a = G_a / 2; return G_a; } int func2(void) { G_a = G_a * 2; return G_a; }
出力
x: 15 y: 33 z: 15
extern宣言した配列のサイズをsizeofで取得するには
正しく配列のサイズを取得できるケース
test.c
int array[] = {1,2,3};
Main.c
#include <stdio.h> extern int array[3]; int array2[] = {1,2,3}; int main(void){ printf("array size is %d\n",(int)sizeof(array)); printf("array2 size is %d\n",(int)sizeof(array2)); return 0; }
出力
array size is 12 array2 size is 12
正しく配列のサイズを取得できないケース
test.c
int array[] = {1,2,3};
Main.c
#include <stdio.h> extern int array[]; int array2[] = {1,2,3}; int main(void){ printf("array size is %d\n",(int)sizeof(array)); printf("array2 size is %d\n",(int)sizeof(array2)); return 0; }
出力
Main.c:9:44: error: invalid application of 'sizeof' to an incomplete type 'int []' printf("array size is %d\n",(int)sizeof(array)); ^~~~~~~ 1 error generated.
なぜ正しく配列のサイズが取得でいないのか
要素数を指定していないextern宣言した配列は不完全型であるため、 arrayにはsizeofを使うことができない。
不完全型とはなにか?
C言語の方は、大きく次の3つに分かれる。
- 関数型
- オブジェクト型
- 不完全型
不完全型には次のようなものがあります。
- メンバーがまだ指定されていない構造体型
- メンバーがまだ指定されていない共用体型
- 次元がまだ指定されていない配列型
今回は「次元がまだ指定されていない配列型」に該当するため、 配列のサイズを取得することができませんでした。
ちなみに、arrayのサイズはMain.cのコンパイル時に決定されるのですが。 不完全型のサイズは決定することができないため、コンパイルエラーとなりました。
回避方法
extern宣言の配列の要素数に正しい値を入れる
test.h
#define ARRAY_SIZE 3
test.c
#include "test.h" int array[ARRAY_SIZE] = {1,2,3};
Main.c
#include <stdio.h> #include "test.h" extern int array[ARRAY_SIZE]; int array2[] = {1,2,3}; int main(void){ printf("array size is %d\n",(int)sizeof(array)); printf("array2 size is %d\n",(int)sizeof(array2)); return 0; }
出力
array size is 12 array2 size is 12
Eclipse に C/C++ 開発ツール (CDT) を導入
Eclipseとは
Eclipseは、IBMによって開発された統合開発環境 の一つです。 統合開発環境が何かというと、ソフトウェアの開発において用いられるエディタ、コンパイラ、リンカ、デバッガ、その他の支援ツールなどを統合・統一化した開発環境のことです。 統合開発環境のことをIDE(Integrated Development Environment)とも言いますね。
Eclipse CDTってなに?
Eclipseのパッケージのひとつであり、 Eclipseのプラットフォームに基づいた、C, C++で開発するための統合開発環境を提供します。
パッケージというのは、 開発に必要なプラグインを組み合わせてセットにしたものです。 Eclipse CDT以外には、下記のようなパッケージが存在します。
- Eclipse IDE for Java EE Developers Java EE および Webアプリケーション を開発するための構成
- Eclipse for PHP Developers PHP開発を行うための構成
- Eclipse IDE for Automotive Software Developers 組み込み車載ソフトの開発に使われる Framework と ツール を含む構成。
どのバージョンのEclipseがいいの?
Eclipseには様々なバージョンがあります。 執筆時点では、Eclipse Photon (4.8)が最新のようです。 新しいバージョンのEclipseは私のPCでは重いため、少し古いバージョンである Eclipse Indigoを使用しています。
ちなみに私のPCのスペックは下記です。
メーカ:Panasonic 型番:CF-NX2 CPU:Intel Core i5-3340M メモリ:8GB SSD:256GB
Eclipse Indigoでも問題なく使用できていますが、 追加するプラグインによっては古いバージョンをサポートしていない可能性があります。
PCのスペックに余裕のあるかたは、最新のバージョンを入れてください。
Eclipseのダウンロード
Eclipse Indigo SR2 Packagesをダウンロードします。
Eclipseのインストール
ダウンロードした eclipse-cpp-indigo-SR2-incubation-win32-x86_64.zip を解凍してください。 Eclipseはインストーラは付属せず、インストールは不要です。 実行ファイルを直接実行します 私の場合は、解凍してできたeclipseフォルダをCドライブ直下に置いています。 C:\eclipse
これでインストール完了です。
プロジェクトの作成方法
C:\eclipse\eclipse.exe を実行してください。
ワークスペースの作成場所を設定して、OKをクリックします。 今後、ワークスペースのあるディレクトリで作業を進めていくことになります。
プロジェクトを作成します。 File->New->C Projectを選択します。
適当なProject nameを入力し、 Project TypeはHello World ANSI C Projectを選択します Tool chainsにはCygwin GCCを選択します。