2016-06-16 1 views
2

ソースコードにcppのエラーを追加しようとしています。誰がそれを変更しているかを通知するには小さすぎます。プリプロセッサとの比較のために文字列のサイズを取得する方法

は、私は、コードの連続した部分に

#if STRING_LENGTH < MAX_STRING_LENGTH 
#error "you need to extend the value of MAX_STRING_LENGTH" 
#endif 

のようなものを持ちたいあなたが

#define STRING "Hello world" 

のようないろいろ書いがあると仮定そこで質問です:どのように私はSTRING_LENGTHを定義することができますか?

+5

私はそれが答えられて以来、質問を閉じるために投票しなければならない[ここ](http://stackoverflow.com/q/5022067/strlen-in-the-c-preprocessor)を参照してください。プリプロセッサにはないのにコンパイル時に解決されたsizeof()を使用してください –

+0

私が理解する限り、sizeofはcpp条件文では使用できません。 –

+0

@Ottavio_Campanaあなたは右です(http://stackoverflow.com/questions/4079243/how-can-i-use-sizeof-in-a-preprocessor-macro) –

答えて

3

プリプロセッサでは実行できません。あなたができることは、コンパイル時定数を得ることです。

_Static_assert(sizeof(STRING) - 1 < MAX_STRING_LENGTH, "you need to extend the value of MAX_STRING_LENGTH") 
0

Cプリプロセッサは、の長さを取得する任意のメカニズムを提供していません:

sizeof("string literal") - 1あなたは、コンパイル時のチェックを行うにはC11から_Static_assertを使用することができますstrlen("string literal")

と同じになります文字列リテラル。

static void validateSTRING(void) { 
    (void)(char[MAX_STRING_LENGTH]){STRING}; 
} 

(注:MAX_STRING_LENGTHの使用は意図的だった

しかし、GCC/C99やC11モードで打ち鳴らすと、-Wallオプションを使用すると、あなたは次のようなものを挿入することにより、コンパイラの警告を強制することができます。実際に配列を割り当てていた場合は、MAX_STRING_LENGTH+1にNULターミネータのためのスペースを許してもらいたいが、ここでは警告を出そうとしているだけで、故意にNULのスペースを残さないと警告は出ない。

+0

この方法は問題があります。なぜなら、Cは奇妙な文字列リテラルからの初期化にのみ適用される特別な場合の規則:6.7.9/14 "文字型の配列は、文字列リテラルまたはUTF-8文字列リテラルによって初期化することができます(オプションで中かっこで囲みます)。配列が未知のサイズの場合には空文字を終端する文字を含む)配列の要素を初期化します。 "これは何のコンパイラ診断も得られないかもしれないという意味です。だから、この答えは良い勧告ではありません。ここでCはC++とは異なることに注意してください。 – Lundin

+0

たとえば、gccはヌルターミネータが適合しなかった 'char str [5] =" hello ";'の診断を与えることができません。 – Lundin

+0

@ lundin:私は私の推薦が最大の弦の長さを持たないことを忘れていました。ほとんどの場合、彼らはmallocの不合理な恐怖の原因です。だから私はそれが推奨ではないことに同意する。しかし、gccは警告を出します。あなたが言うように、それはエラーではなく、他のコンパイラは得ることができないかもしれませんが、答えはそれがうまくいく特定のケースを指定します。 – rici

関連する問題