2009-06-10 6 views
1

複数の環境をサポートする必要があるCプロジェクトがある場合、プリプロセッサを使用して1つの環境が定義されていることをどのように強制するのですか?正確に1つの定義を実施するにはどうすればよいですか?

私はすでに行うことができます。

 
    #if defined PROJA 
    (blah blah blah) 
    #elif defined PROJB 
    (etc) 
    #else 
    #error "No project defined" 
    #endif 

しても、そのすべてが、しかし、0のプロジェクトが定義されているなら、私に教えています。プロジェクトAとプロジェクトBの両方を定義している人がいれば、プリプロセッサはプロジェクトAだけを引き受けることになります。しかし、私の見解では、エラーにフラグを立てるのが正しい動作です。

2つのプロジェクトしか定義されていませんが、この問題は簡単です。 200でどのように解決するのですか?

+3

プリプロセッサハックは維持するために全く苦痛になり、その後はむしろ、この種のことは、システムを構築するものである」この –

答えて

2

はたぶん異なるファイル

include_proja.h 
include_projc.h 

を持って、あなたのMakefileを使用するか、右のファイルをインクルードするものは何でも。コードを使用して200の異なるファイルを生成し、コンパイル時に正しいファイルを含めることができます。

この種類のものは、のビルドシステムです。マクロでこれほど奇妙なことをしているのなら...ソースコードの外でもっと良い方法を見つけることができます。

各ファイルには、(ここでは冗長性をすみません)

#define A_PROJECT_INCLUDE_WAS_INCLUDED 

を行い、その後、

#ifndef A_PROJECT_INCLUDE_WAS_INCLUDED 
    #error "No project include" 
#endif 

を行うしかし、いくつか欠けているシンボルは、すべての可能性で、とにかくそれを破るだろうことができます。

グッドラック

+1

の世話をmakesystem作成する必要がありますのためのものです。あなたは奇妙な何かをしている場合マクロでこのように...ソースコードの外側でもっと良い方法を見つけることができます。 あなたはまったく正しいです。 – JXG

3

このような何か:

#if defined PROJA 
    #ifdef HAVE_PROJ 
    #error 
    #endif 

    #define HAVE_PROJ 
#endif 

#if defined PROJB 
    #ifdef HAVE_PROJ 
    #error 
    #endif 

    #define HAVE_PROJ 
#endif 

#ifndef HAVE_PROJ 
    #error No project selected (you need to define PROJA, PROJB, or ...) 
#endif 
+0

これはすばやく大騒ぎになると思うし、本当にマクロimhoで行うべきものではない。 –

0

ネストされたIFSの問題点は、n個^ n個のプロジェクトのための2回の異なるテストで終わるだろうということです。

この場合、コンパイル時エラーが発生する式が必要です。多分:次に

#ifdef PROJA 
#define PROJA-TEST " 
#else 
#define PROJA-TEST "" 
#endif 

等B、C、等のために

const char *test_only_one_project = PROJA-TEST PROJB-TEST PROJC-TEST " "More than one project is defined!"; 

EDIT:プロジェクトの奇数が定義されている...もちろん、このテストのみ。しかし、これは動作するはずです:

#ifdef PROJA 
#define PROJA-TEST (
#endif 

というように、その後、

const char *test_only_one_project = PROJA-TEST PROJB-TEST PROJC-TEST "More than one project is defined!"); 
+1

私の最初の考えは「うん、それもやっているよ」私の2番目は、「誰もCをもう誰も好まない理由は?」 –

+0

正確に。プリプロセッサはかなり悪いです。 –

-1

をのようなもの、おそらくあなたが行うことができます。

#if PROJ==A 
(blah blah blah) 
#elif PROJ==B 
(etc) 
#else 
#error "No project defined" 
#endif 
2

は今、この

#define ENV_UNKNOWN 0 
#define ENV_MACOSX 1 
#define ENV_LINUX 2 
#define ENV_WIN32 3 
/* and so on */ 


#ifndef ENVIRONMENT 
/* no environment given, default to something (perhaps) */ 
#define ENVIRONMENT ENV_UNKNOWN 
#endif 

/* and now the environment specific parts */ 
#if (ENVIRONMENT == ENV_MACOSX) 
#include "macosx_port.h" 
#endif 

#if (ENVIRONMENT == ENV_LINUX) 
#include "linux_port.h" 
#endif 

#if (ENVIRONMENT == ENV_WIN32) 
#include "win32_port.h" 
#endif 

#if (ENVIRONMENT == ENV_UNKNOWN) 
#error You have to specify the ENVIRONMENT. 
#endif 

をあなたがすることができます試してみてくださいコンパイルする環境をコマンドラインで指定し、

cc -DENVIRONMENT=2 ... 

もう1つの方法は、コンパイルする環境に応じてビルドシステムから異なるモジュールを組み込むことです。 200と

2
#if defined PROJA 
bool one_project_defined = true; 
#endif 

#if defined PROJB 
bool one_project_defined = true; 
#endif 

#if defined PROJC 
bool one_project_defined = true; 
#endif 

#if defined PROJD 
bool one_project_defined = true; 
#endif 

one_project_defined; // Won't compile in wrong builds 
+1

これは短くてシンプルです。しかし、私はハッキーのように私を襲う。 – Brian

+0

メンテナンス作業をしている有用な協業が始まるまで、「ねえ、この変数はもう使用されていません...」 – David

関連する問題