はい、私は考えています(おい、ごめんなさい、あなたに尋ねました)。コードをそのように書かないでください。さて、これを最後まで正しい方法で予約します。しかし、限りあなたの質問に行く:はい、これは、ODRの違反になりますあなたのビルドプロセスの一環としてCとC + +の両方のコンパイラを使用する場合。実際のファイル拡張子は無関係かもしれません(コンパイラのデフォルトを変更するかもしれませんが、ビルドシステムはコンパイラの言語を明示的に指定するかもしれません)。つまり、CはC++の適切なサブセットであるため、C++コンパイラで構築できるCコードを書くのがはるかに一般的になるため、これは非常に悪い考えであり、非常に珍しいことです。また、CとC++の両方のコンポーネントを持つプロジェクトでは、C++コンパイラを使用し、純粋なCのプロジェクトでもそのコードを使用できます。したがって、ファイルの拡張子に関係なく、指定されたプロジェクトが1つのコンパイラのみに依存する限り、これは問題ありません。
// 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コンパイラで '驚き 'しか使用しないことを覚えている限り、あなたはうまくいくはずです。これらの条件文のうちの1つだけがコンパイルされるので、コンパイラはそれを見ません。 –
@GillBates私が取り組んでいるプロジェクトには、CとC++の両方のソースファイルがあります(両方のコンパイラが使用されています)。ああ、あなたは2つのリンカーもあるので、probもないということですか? –
C++は実際には、プログラムの一部が別の言語で書かれているときに何が起こるかを指定していますか?それともこれは未定義ですか? – Leushenko