2012-07-13 33 views
3

有人可以解釋幕後導致此用戶錯誤不一致崩潰的原因。C C++函數名稱衝突和崩潰不一致

這裏的主要功能是

#include "foo.h" 
inline int Bar(const int &a) 
{ 
... 
} 
... 
int b=Bar(a); 

在 「foo.c的」 也有功能

inline int Bar(const int &a) 

副本這是問題所在。我不擁有foo.h也不擁有foo.C,並且在foo.h中沒有Bar(int)的聲明。 所有編譯和工作正常與舊版本的foo.h和foo.C
在我的同事更新他的foo.C中的一些其他功能後,代碼仍編譯好,但它開始崩潰執行。
通過ddd進行調試表明,當我的主函數調用Bar()時,它實際上調用了foo.C中的Bar()而不是我自己定義的Bar()。
因爲修復是靜態我自己的功能或更改我自己的Bar()函數的名稱。

我知道寫這樣的代碼是混亂的,並且很容易出現這樣的錯誤。有人可以向我解釋爲什麼代碼崩潰不一致?

謝謝大家

問候

+2

是有一些原因,你不能只命名函數別的東西嗎?的 – Wug 2012-07-13 20:41:35

+1

可能重複[它是一個未定義的行爲有一個內聯函數的定義不同?(http://stackoverflow.com/questions/11200805/is-it-an-undefined-behavior-to-have-different-definitions內聯函數) – 2012-07-13 21:19:18

+0

這個問題有點混亂,因爲標題中顯示「C」,而你的文件是「foo.c」(而不是「foo.cxx」或「foo.cpp」),但你顯然是用C++編寫的(參考文獻)。無論如何,這違反7.1.2(4)。 – 2012-07-13 21:21:40

回答

2

內聯函數還有外部鏈接。也就是說,它們被編譯器發送到相應的目標文件中,並且當鏈接器鏈接應用程序時,它認爲具有相同簽名(包括它們的名稱和封裝名稱空間)的所有函數都是相同的。由於該函數被定義爲inline,它隨機選擇一個定義並刪除另一個,而不會出錯。 (這是違反了一個定義規則,根據標準導致未定義的行爲。)

爲了避免這個問題使用匿名命名空間,就像這樣:

namespace { 
inline int Bar(const int &a) 
{ 
... 
} 
} 

在你的情況下這樣做無論是foo.C還是main都可以做到這一點。等效您可以添加static

static int Bar() {} 

如果你在C.

編寫使用匿名命名空間或static關鍵字使功能本地的翻譯單元,所以鏈接器並不把它看成一個外部符號。這樣,您可以在不同的翻譯單元中擁有相同簽名的任意數量的函數。

+0

謝謝大家的解釋。 – elgnoh 2012-07-13 21:58:12

0

我想你使用的是foo定義的Bar函數,因爲它是在定義你自己的Bar函數之前通過foo.h #included。

我很驚訝你的編譯器不會警告你的 重複定義(非法的),但如果你已經確定你的#include之前 酒吧功能「foo.h中」錯誤應該有 被拋出。

該URL說內嵌的重新定義是非法的,除非 內聯是一樣的:

C static inline function redefinition rules

我的編譯器在此拋出一個錯誤。避免最好的方法是使用一個單獨的命名空間或宏衛..