本文出處連接, by Ray FAN(
ielnaf@qq.com)
今天又發現了我的一個“不良習慣”,C語言的源文件用C還是CPP做后綴完全視心情而定,今天我就嘗到苦頭了,工程總是編不過去,准確的說是鏈接錯誤,后來發現工程下的文件多是c后綴的,只有一個是cpp后綴的,就把cpp后綴的改成了c后綴,編譯、鏈接,OK了。
在Google上搜索了一圈,發現就這一問題的文章比較少,也不是很系統,所以有了此篇小文,也是為了加深我的印象。
結論:
1.gcc認為.c的為C程序,.cpp的為C++程序;
2.g++認為.c的為C++程序,.cpp的為C++程序;
3.VC++的編譯器cl認為.c的為C程序,.cpp的為C++程序;
4.C程序與C++程序中同樣的函數在編譯后的obj文件中的symbol是不同的,所以以C方式編譯的obj文件與以C++方式編譯的obj文件無法成功鏈接。
1.gcc認為.c的為C程序,.cpp的為C++程序;
2.g++認為.c的為C++程序,.cpp的為C++程序;
3.VC++的編譯器cl認為.c的為C程序,.cpp的為C++程序;
4.C程序與C++程序中同樣的函數在編譯后的obj文件中的symbol是不同的,所以以C方式編譯的obj文件與以C++方式編譯的obj文件無法成功鏈接。
使個demo說明一下:
准備工作:
為gcc、g++、cl(VC++編譯器)、link(VC++鏈接器) 設置好環境變量
//demo.cpp
#include
#include "foo.h"
int main()
准備工作:
為gcc、g++、cl(VC++編譯器)、link(VC++鏈接器) 設置好環境變量
//demo.cpp
#include
#include "foo.h"
int main()
{
printHello();
return 0;
}
//foo.h
void printHello();
void printHello();
//foo.c
#include
void printHello()
#include
void printHello()
{
printf("Hello MM");
}
1.gcc、g++測試,在windows的cmd下:
D:\> g++ demo.cpp -o demo.obj -c (以C++方式編譯生成demo.obj文件,-c選項表示只編譯不鏈接)
D:\> gcc foo.c -o foo.obj -c (以C方式編譯生成foo.obj文件)
D:\> g++ demo.obj foo.obj -o demo (鏈接demo.obj、foo.obj文件)
demo.obj(.text+0x2b):demo.cpp: undefined reference to `printHello()'
collect2: ld returned 1 exit status
提示說 找不到printHello,因為按照C++的編譯方式去找printHello應該對應某一種格式的symbol,但是我們
D:\> g++ demo.cpp -o demo.obj -c (以C++方式編譯生成demo.obj文件,-c選項表示只編譯不鏈接)
D:\> gcc foo.c -o foo.obj -c (以C方式編譯生成foo.obj文件)
D:\> g++ demo.obj foo.obj -o demo (鏈接demo.obj、foo.obj文件)
demo.obj(.text+0x2b):demo.cpp: undefined reference to `printHello()'
collect2: ld returned 1 exit status
提示說 找不到printHello,因為按照C++的編譯方式去找printHello應該對應某一種格式的symbol,但是我們
的foo.obj中printHello的symbol是另外一種格式的,所以找不到了。
把foo.c改成foo.cpp就可以成功鏈接了。
把foo.c改成foo.cpp就可以成功鏈接了。
2.
cl、link測試,在windows的cmd下:
D:\> cl demo.cpp /c (以C++方式編譯生成demo.obj文件,/c選項表示只編譯不鏈接)
D:\> cl foo.c /c (以C方式編譯生成foo.obj文件)
D:\> link demo.obj foo.obj
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
D:\> cl demo.cpp /c (以C++方式編譯生成demo.obj文件,/c選項表示只編譯不鏈接)
D:\> cl foo.c /c (以C方式編譯生成foo.obj文件)
D:\> link demo.obj foo.obj
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
demo.obj : error LNK2001: unresolved external symbol "void __cdecl printHello(void)"(
?printHello@@YAXXZ)
demo.exe : fatal error LNK1120: 1 unresolved externals
理由同上,把foo.c改成foo.cpp就可以成功鏈接了。
demo.exe : fatal error LNK1120: 1 unresolved externals
理由同上,把foo.c改成foo.cpp就可以成功鏈接了。
參考文章:
1.gcc和g++的區別(開源CEO)
http://www.linuxdiyf.com/bbs/viewthread.php?tid=109684
2.在 console mode 中使用 C/C++ 編譯器(jjhou候俊傑)
http://jjhou.csdn.net/article99-10.htm
1.gcc和g++的區別(開源CEO)
http://www.linuxdiyf.com/bbs/viewthread.php?tid=109684
2.在 console mode 中使用 C/C++ 編譯器(jjhou候俊傑)
http://jjhou.csdn.net/article99-10.htm