リンカはオブジェクトファイル単位でしか要らないものを捨ててくれない

リンカはオブジェクトファイル単位でしか要らないものを捨ててくれないのだと知った。
少なくとも GCC とか VC6 での実験結果はそうだった。
てっきりシンボル単位でやってくれるものだと思ってた。
スタートアップルーチンから到達可能かどうかを調べるのが難しいからやってくれないんだろうか?


以下、実験に使ったファイル。


■file1.cpp

int g_Var1 = 0;

int FuncA(int arg1, int arg2)
{
	g_Var1 = arg1 + arg2;
	return g_Var1;
}

int FuncB(int arg1, int arg2, int arg3)
{
	return arg1 + arg2 + arg3 + g_Var1;
}

■file1.h

extern int g_Var1;

int FuncA(int arg1, int arg2);
int FuncB(int arg1, int arg2, int arg3);

■file2.cpp

int g_Var2 = 0;

int FuncC(int arg1, int arg2)
{
	g_Var2 = arg1 + arg2;
	return g_Var2;
}

int FuncD(int arg1, int arg2, int arg3)
{
	return arg1 + arg2 + arg3 + g_Var2;
}

■file2.h

extern int g_Var2;

int FuncC(int arg1, int arg2);
int FuncD(int arg1, int arg2, int arg3);

■file3.cpp

#include "file1.h"

int g_Var3 = 0;

int FuncE(int arg1, int arg2)
{
	g_Var3 = arg1 + arg2;
	return g_Var3 + FuncA(arg1, arg2);
}

int FuncF(int arg1, int arg2, int arg3)
{
	return arg1 + arg2 + arg3 + g_Var3;
}

■file3.h

extern int g_Var3;

int FuncE(int arg1, int arg2);
int FuncF(int arg1, int arg2, int arg3);

■main.cpp

#include <stdio.h>
#include "file2.h"
#include "file3.h"

int main(int argc, char** argv)
{
	int v = FuncD(3, 4, 5);
	int n = FuncF(1, 2, 3);
	printf("%d\n", v + n);
	
	return 0;
}

■libs.bat

g++ -c file1.cpp -o file1.gcc.o
g++ -c file2.cpp -o file2.gcc.o
g++ -c file3.cpp -o file3.gcc.o
ar -r libabc.a file1.gcc.o file2.gcc.o file3.gcc.o

cl /Zi /c file1.cpp /Fofile1.vc.o
cl /Zi /c file2.cpp /Fofile2.vc.o
cl /Zi /c file3.cpp /Fofile3.vc.o
lib file1.vc.o file2.vc.o file3.vc.o /OUT:abc.lib

■main.bat

g++ -c main.cpp -o main.gcc.o
g++ main.gcc.o libabc.a
nm a.exe > gcc.txt

cl /Zi /c main.cpp /Fomain.vc.o
"E:\Program Files\Microsoft Visual Studio\VC98\Bin\link.exe" /DEBUG /DEBUGTYPE:COFF main.vc.o abc.lib
dumpbin /SYMBOLS main.vc.exe > vc.txt