但是最近撰寫了一支程式,把它切成多個file,卻莫名其妙地出現了"multiple definition of [function name] ... "這種錯誤訊息...
我仔細地觀察了又觀察,不管是正著看、反著看、倒著看…都看不出錯誤來…正當對分檔的寫法失望之餘,想回復到原本一個檔案的寫法後,才驚覺原本寫法的漏洞與缺點…
原本的一個file寫到底的code....
#include<iostream> void a_function(){ int a; } void a_problem_function(){ int problem; } int main(int argc, char**argv){ return 0; }把它切成多個file... 包括 .h && .cpp
a.h的內容
#ifndef A_H #define A_H void a_function(); void a_problem_function(){ int problem; } #endifa.cpp的內容
#include "a.h" void a_function(){ int a; }main.cpp的內容
#include<iostream> #include "a.h" int main(int argc, char**argv){ return 0; }compile過程:
% g++ -c a.cpp % g++ a.o main.cpp ...... multiple definition of `a_problem_function()'
照上面的寫法實作後 會產生這樣的問題...
奇怪!? 明明a.h不是寫了「#ifndef ... #define .... 」怎麼還會有問題呢!?
沒錯! 這樣的寫法的確是會有問題的... 並不是說寫了「#ifndef ... #define .... 」,在compile過程中,就應該只有一份a_problem_function() 而不應該出現multiple definition的問題才對呀...
其實問題是在於g++ -c a.cpp後,產生了a.o檔,這個a.o檔裡面,已經包含了一個a_problem_function()的definition,然而接下來g++ a.o main.cpp時,main.cpp又去include a.h,因此,它又想產生了一份a_problem_function(),問題就此產生了!
所以把變數definition寫入.h檔也會產生一樣的問題喲!
所以問題的徵結就在於.h檔裡面,寫入了function的definition或是變數definition,這樣子容易在多個檔案互相include時,產生multiple definition的問題,所以說囉,千萬別偷懶…直接把function definition寫在.h檔裡,是很不明智的決定!!!
9 則留言:
大大,可以幫我看一下這個問題嗎?
c++的多重include
http://csie-tw.blogspot.com/2008/12/c-multiple-include.html
在 C 中若使用到外部 func 可用 extern 告之.
例:
uart.h
----------
#ifndef _UART_H
#define _UART_H
extern unsigned char TXState;
extern void InitUart(void);
#endif //_UART_H
uart.c
----------
unsigned char TXState;
void InitUart(void)
{
...;
}
main.c
----------
#include "uart.h"
main()
{
TXState = 123;
InitUart();
}
但不知 C++ 可否有此關鍵字
我的看法:
一般來講 .h 檔是要給別的程式用的
例如你的範例:
a.h 是要給 main.cpp #include 用
因此 a.cpp 就不用 #include 了
除非 a.h 裡有些定義是 a.cpp 沒有的
但 a.cpp #include "a.h" 時
可能會引發重複定義的問題
因此可能要避開, 例如:
a.h
----------
#ifndef A_H
#define A_H
#ifndef A_CPP
extern void a_function();
#endif
void a_problem_function(){ int problem; }
#endif
a.cpp
----------
#define A_CPP
#include "a.h"
void a_function(){ int a; }
以上看若有不對之處請指正, 謝謝!
抱歉沒看清問題是出現在a_problem_function 的程式碼是寫在 a.h
又 a.h 被 #include 兩次, 所以就有兩份
a_problem_function 的程式碼啦! ^^
所以我前兩篇回的是文不對題啦! 請海函! ^^"
Dear ak,
沒關係,我們觀念一致就好... XD
應該是我寫得太爛了,讓你看完後不能馬上了解我在說什麼...Orz..
其實這邊只要 g++ a.cpp main.cpp 即可.
你之所以會錯是因為你是分開compile 2個.o檔
當你各自compile,當然都會各自把a_problem_function()把在.o檔裏
所以在link的時候就會在不同的.o看到相同的a_problem_function()...才會出錯
Hi,
感謝你的見解,這的確是個方法可以解決這個問題
只是當project一大時,必須把某些module build成.lib檔,這時候就會可能會出錯了
所以我才覺得,以好的coding習慣而言,最好不要把 function or 變數的 definition 放在 .h
可以避免掉很多問題~
我看了甚麼Orz
This article expressed a wrong concept. It's better to separate implementations and definitions into header (.h) and implementation (.cpp) files.
To author,
I suggest you to make sure how to build a complexity project (using makefile), and, how to distribute your code as an library (as .so or .a). They are different.
張貼留言