私は宣言を右から左に読むための経験則を知っており、同僚が私に次のように言うまで、何が起こっているのかをかなり確信していました。
const MyStructure** ppMyStruct;
「ppMyStructは(可変)MyStructureへのconstポインタへのポインタ」(C++の場合)を意味します。
「ppMyStructはconst MyStructureへのポインタへのポインタ "」という意味だと思いました。私はC++仕様で答えを探しましたが、どうやら私はそれがあまり得意ではないようです...
C++ではどういう意味ですか?Cでも同じ意味ですか?
あなたの同僚は間違っています。これは、const MyStructureへの(非const)ポインターへの(非const)ポインターです。 CとC++の両方で。
このような場合、ツールcdecl(またはc ++ decl)が役立ちます。
[flolo@titan ~]$ cdecl explain "const struct s** ppMyStruct"
declare ppMyStruct as pointer to pointer to const struct s
あなたはあなたの解釈に正しかった。これを見る別の方法は次のとおりです。
const MyStructure * *ppMyStruct; // ptr --> ptr --> const MyStructure
MyStructure *const *ppMyStruct; // ptr --> const ptr --> MyStructure
MyStructure * *const ppMyStruct; // const ptr --> ptr --> MyStructure
これらはすべて、1つのconst修飾子を持つポインターからポインターへの代替手段です。右から左へのルールを使用して、宣言を解読できます(少なくともC++では、私はCの専門家ではありません)。
あなたの同僚は間違っています、そしてそれはCとC++についても同じです。次のことを試してください。
typedef struct foo_t {
int i;
} foo_t;
int main()
{
foo_t f = {123};
const foo_t *p = &f;
const foo_t **pp = &p;
printf("f.i = %d\n", (*pp)->i);
(*pp)->i = 888; // error
p->i = 999; // error
}
Visual C++ 2008では、最後の2行に次のエラーが表示されます。
error C2166: l-value specifies const object
error C2166: l-value specifies const object
GCC 4によると:
error: assignment of read-only location '**pp'
error: assignment of read-only location '*p'
G ++ 4によると:
error: assignment of data-member 'foo_t::i' in read-only structure
error: assignment of data-member 'foo_t::i' in read-only structure
あなたは正しいです。
別の回答 すでに " 時計回りのスパイラルルール "を指しています。私はそれがとても好きでした-しかし、少し手の込んだものです。
他のコメントの結果として、「const」を最初に置かないでください。それは本当にタイプの後に属します。それはすぐに意味を明らかにしたでしょう、いつものようにそれをRTLを読んでください:
MyStructure const** ppMyStruct;
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
}