是的,我有一個想法(嘿,對不起,你問):請不要這樣寫代碼。好的,我會保留正確的方式來做到最後。但是,就你的問題而言:是的,如果你同時使用C和C++編譯器作爲構建過程的一部分,這將導致ODR違規。實際的文件擴展名可能不相關(它可能會改變編譯器的默認值,但是您的編譯系統可能會明確指定編譯器的語言)。也就是說,這是一個非常糟糕的想法,並且非常不尋常,因爲C離C++的真正子集非常近,所以簡單編寫也可以用C++編譯器編譯的C代碼會更加普遍。在同時擁有C和C++組件的項目中,您可以使用C++編譯器,而在純C項目中,您仍然可以使用該代碼。所以,不管文件擴展名是什麼,只要給定的項目只支持一個編譯器就沒有問題。
// my_header.h
#ifdef __cplusplus
constexpr bool is_cpp = true;
#else
constexpr bool is_cpp = false;
#endif
struct cpp {
std::size_t member;
int surprise;
};
struct cc {
unsigned member;
};
template <bool CPP>
struct MyStructImpl : private std::conditional_t<cpp, cc, CPP>
{
};
using MyStruct = MyStructImpl<is_cpp>;
這使得在結構中的代碼量可能被定義以同樣的方式和無條件不管宏選項,並按照相關的東西,以儘可能晚的宏。這在工具和測試方面也是一個巨大的勝利,例如您可以在不重新編譯的情況下爲兩個版本的結構運行單元測試。
一點都不,只要你記得只在CPP編譯器中使用'surprise',你應該沒問題。只有其中一個條件將被編譯,因此編譯器將永遠不會看到它。 –
@GillBates我正在做的項目有C和C++源文件(都使用了編譯器)。哦,那麼你的意思是說有2個連接器,所以沒有問題? –
C++實際上是否在指定使用其他語言編寫程序的某些部分時會發生什麼?或者這只是未定義的? – Leushenko