我知道这个问题的答案,但我们可以从中获得一些乐趣来分析它。我们将学会玩得开心!
我在这些测试中使用了 gcc 4.1.2。
首先,这段代码不是标准的,因为一个内联函数在不同的翻译单元中会有不同的定义。我知道。但是让我们分析一下发生了什么,并回答我将提出的三个问题。我们会从中学习:)
我将保持文件简单(例如,没有#ifndef 保护)。
假设我有这些文件:
增量.h:
inline int increment()
{
static int value = 0;
return ++value;
}
递减.h:
int decrement();
递减.cpp:
inline int increment()
{
static int value = 0;
return --value; // Attention to this
}
int decrement()
{
return increment();
}
主.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 标志和目标文件链接的顺序会以这种方式改变输出?