これに対する答えはわかっていますが、それを分析して楽しむことができます。そして、私たちは楽しみながら学びます!
これらのテストには gcc 4.1.2 を使用しました。
まず第一に、インライン関数は異なる翻訳単位で異なる定義を持つため、このコードは標準ではありません。そんなこと知ってる。しかし、何が起こっているのかを分析して、私が作る 3 つの質問に答えてみましょう。私たちはそれから学びます:)
ファイルをシンプルに保ちます (たとえば、#ifndef ガードはありません)。
これらのファイルがあるとします:
インクリメント.h :
inline int increment()
{
static int value = 0;
return ++value;
}
decrement.h :
int decrement();
decrement.cpp :
inline int increment()
{
static int value = 0;
return --value; // Attention to this
}
int decrement()
{
return increment();
}
main.cpp :
#include <iostream>
#include "increment.h"
#include "decrement.h"
using namespace std;
int main()
{
cout << increment() << endl;
cout << increment() << endl;
cout << decrement() << endl;
}
この Makefile でそれらをコンパイルすると:
CC=gcc
CFLAGS=-I. -O2
crazy: main.o decrement.o
$(CC) -lstdc++ main.o decrement.o -o crazy
main.o: main.cpp increment.h decrement.h
$(CC) $(CFLAGS) -c main.cpp -o main.o
decrement.o: decrement.cpp decrement.h
$(CC) $(CFLAGS) -c decrement.cpp -o decrement.o
clean:
rm -f *.o *.~ crazy
出力は次のとおりです。
1
2
1
Makefile から -O2 フラグを削除すると、次のようになります。
CFLAGS=-I.
出力は次のとおりです。
1
2
3
main.o と decrement.o の順序も変更した場合 (先ほど行ったように -O2 フラグを付けずに残します):
$(CC) -lstdc++ decrement.o main.o -o crazy
結果は次のとおりです。
-1
-2
-3
ここで何が起こっているのですか?-O2 フラグとオブジェクト ファイルのリンク順序によって、出力がこのように変わるのはなぜですか?