2011-06-17 2 views
3

C言語の関数で 'const'を使用して、特定のchar *引数が関数によって変更されていないことに注意したいと思います。Cで 'const'を使用すると、どのような移植上の問題が起こる可能性がありますか?

このコードをさまざまなプラットフォームに移植する際に、どのような問題が発生する可能性がありますか? Cコードの 'const'のサポートはかなり標準ですか?これは公式にC標準になったのはいつですか?

答えて

5

constはどのコンパイラでもサポートされていないとは想像もできません。したがって、移植は問題ではありません。あなたは、このような獣を見つけるためにた場合、あなただけのconstのキーワードはすべて消える作るためにどこか共通ヘッダファイル内

#define const 

を置くことができます。あなたのプログラムのランタイムセマンティクスは(あなたのコンパイラがキーワードをサポートしていないので)全く変わらないでしょう。

+0

の場合、MSVCは確かに「最小公約数」です。これは、 'const'文字列を' const '文字列を 'const'文字列を渡すC++呼び出しを' const '' #define''は離れています。 – WilliamKF

+0

@WilliamKF、C++はどこでこの議論に入りましたか?また、 'const'をサポートするC++コンパイラがあれば、それを使わないでCコードをコンパイルする必要があるのはなぜですか?そして、それ以外にも、両方のコンパイラを使用したとしても、リンカは 'const 'とは何が分かっているのか、どのように知っていますか?あなたのC++プログラムに不一致のプロトタイプを与えても、 'const'フリーのCライブラリとリンクする際には問題はありません。 –

1

ほとんどの現代のコンパイラは、正しくconstを処理する必要があります。人気のある選択肢は間違いなくそれをサポートします。それは、C89、IIRC以来の標準になっています。

3

かなり標準です。私はそれがC89に付属していると思います。

3

MSVCで動作しますが、これはCの移植性を克服する上での最大の障害です。

+2

+1:クロスプラットフォームのCコード –

1

他の答えとして、constが標準です。実行する唯一の問題は、間違って使用していることです。ポインタのconstは厄介なことがあります。あなたは正しいことをしconstingしていることを確認します:

ポインタと参照型の場合

See the wikipedia article on const-correctness:

、構文が少し微妙です。ポインタオブジェクトは、constポインタまたはconstオブジェクトへのポインタ(またはその両方)として宣言することができます。 constポインタは、最初に割り当てられたオブジェクトとは別のオブジェクトを指すように再割り当てすることはできませんが、指し示すオブジェクト(「pointee」と呼ばれます)を変更するために使用できます。したがって、参照変数はconstポインタの代わりの構文です。一方、constオブジェクトへのポインタは、同じタイプまたは変換可能なタイプの別のオブジェクトを指すように再割り当てできますが、オブジェクトの変更には使用できません。 constオブジェクトへのconstポインタも宣言することができ、pointeeを変更したり、別のオブジェクトを指すように再割り当てすることはできません。次のコードは、これらの微妙な違いを示している:

void Foo(int  *  ptr, 
     int const *  ptrToConst, 
     int  * const constPtr, 
     int const * const constPtrToConst) 
{ 
*ptr = 0; // OK: modifies the pointee 
ptr = 0; // OK: modifies the pointer 

*ptrToConst = 0; // Error! Cannot modify the pointee 
ptrToConst = 0; // OK: modifies the pointer 

*constPtr = 0; // OK: modifies the pointee 
constPtr = 0; // Error! Cannot modify the pointer 

*constPtrToConst = 0; // Error! Cannot modify the pointee 
constPtrToConst = 0; // Error! Cannot modify the pointer 
} 
1

実装は ストレージの読み取り専用領域に揮発性でないconstオブジェクトを配置することができます。

(WG14/N1336秒6.7.3、脚注117)

一部の(クロス)コンパイラは、この約風変わりです。非const変数をRAMに配置する変数として扱い、const変数を実際の読み出し専用メモリデバイス(EEPROMまたはフラッシュ)に配置するものとして扱います

このような場合、型*およびconst型*は異なるメモリ領域を参照します。

void foo(const char* arg); /* intent is not to modify anything through arg, but arg refers to a memory location in ROM */ 
/* ... */ 
char bar[] = "abc"; 
const char baz[] = "def"; 
foo(bar); /* behavior is undefined! */ 
foo(baz); /* should be ok */ 

私はこれを行うPCベースのコンパイラを認識していないんだけど、これはマイクロコントローラのクロスコンパイラに共通するようだ:

を考えてみましょう。私は最近、PSoC1用のImageCraftのコンパイラでFatFを移植するときにこの問題に直面し、カールが示唆するようにconstを#defineする必要がありました。

関連する問題