2017-08-01 31 views
1

閱讀定義C++函數在C中的結構

  1. possible to define a function inside a C structure? [duplicate]
  2. Define functions in structs

不知下面的解決方法是可行的,哪些可以在編譯器級的最深影響後。

// foo.h 
typedef struct foo 
{ 
    int i; 
#ifdef __cplusplus 
    foo(int _i) : i(_i) {}; 
#endif 
} foo; 

// bar.c 
#include "foo.h" 
foo bar; 
bar.i = 1; 

// bar.cpp 
#include "foo.h" 
foo bar(2); 

在我看來是一個偉大的伎倆利用「結構多態性」,能夠保持便攜性爲C遺留代碼,但我的感覺是,在某些方面,我現在做兩份不同類型。

+1

你也在使用兩種不同的語言......你想達到什麼目的? –

+1

如果使用C編譯器進行編譯,則在結構中沒有C++函數。如果使用C++編譯器編譯,則沒有C結構。是的,你有兩種完全不同的類型。 – Gerhardh

+0

環境是一個自己的C++ 11庫,它依賴於舊的C89庫在其他庫中。我的一些c文件是這個lib的客戶端,並且是C11編譯的;該示例結構將主要在我的庫上共享,並且我想確保它是*完全相同的類型。 –

回答

4

看從你的問題這struct定義:

typedef struct foo 
{ 
    int i; 
#ifdef __cplusplus 
    foo(int _i) : i(_i) {}; 
#endif 
} foo; 

這是可能導致相同的內存中表示,當使用C和C++編譯器針對同一平臺編譯。但你應該從來沒有依靠這個。 C++編譯器看到的類型比C編譯器看到的類型多一個成員,因此它們基本上是不同的類型。因此,將它們視爲未定義的行爲。如果按照您的預期工作,則可以通過純運氣,並可能隨時中斷。

如已經評論的,引入virtual功能幾乎可以保證打破它,如C++編譯器將需要存儲的vtable某處struct。但即使沒有,也有很多其他方式可能會中斷,例如編譯器會添加不同的填充。只是不要這樣做。

你可以做的反而是用普通的Çstruct用C添加包裝類 ++當你需要它。

3

這兩個是不同的類型。作爲C編譯的結果與編譯爲C++的類型不同。在同一個程序中同時使用兩者(即將C和C++對象鏈接成一個exectuable),並且由於違反C++中的單一定義規則,結果將是未定義的行爲。

這不是保持C和C++之間可移植性的方法。行爲是不確定的,所以你可能會很幸運,並發現它的工作原理就像你打算的那樣。但是,同樣,這種行爲是不確定的,所以它可能無法正常工作。

2

如果您想確保與C庫的兼容性,這不是方法。

你想定義一個類型,是-afoo並且可以傳遞給庫函數。因此,繼承:

class shiny_foo : foo { 
    // Member functions and anything that changes the object layout. 
}; 

extern "C" void c_bar_func(foo *); 

void cxx_bar_func(shiny_foo& obj) { 
    // do stuff 
    c_bar_func(&obj); // obj *is-a* foo as well, remember 
}