1
ProtobufCAllocator *kvs_pb_allocator()
{
    static ProtobufCAllocator allocator;
    //do something here

    return &allocator; //print the address, it is 0x2aaaaafc12c0
}

別のプログラムで、この関数を (別のファイルから) 呼び出します。

ProtobufCAllocator *alloctor = kvs_pb_allocator(); 
//print the address, it is 0xffffffffaafc12c0 

なぜこの問題が発生したのですか?私が書いた他のデーモン プログラムは正常に動作します。この状況では、間違った値が出力されます。

4

2 に答える 2

7

あなたは64ビットマシンを使用しており、2番目の場所にアドレスを出力するためにタイプセーフメカニズムを使用していません. 値は 32 ビットに切り刻まれ、次に 64 ビットに符号拡張されます。

0x00002aaa_aafc12c0
0xffffffff_aafc12c0

ここで、下線は値の中間にある 32 ビット境界を示します。問題は、値自体よりも値を出力する方法にある可能性が高くなります。

これは、住所をより注意深く印刷することで確認できます。あなたが使用することができます:

printf("Address: %p\n", (void *)alloctor);

これはCだから。


関数を宣言するkvs_pb_allocator()ヘッダーがあり、関数を定義するファイルと関数を呼び出すファイルの両方でヘッダーが使用されていると思います (おそらく理由はありません)。そうでない場合は、すべての関数が使用される前に宣言されている (または静的関数の場合は定義されている) ことを確認する規則に取り掛かります。すべての外部関数はヘッダーで宣言する必要があります。特定の関数を参照するすべてのコードは、その関数を宣言する単一のヘッダーを使用する必要があります。これは、C99 および C2011 で必要です。C89 コンパイラで行き詰まっている場合は、自分自身に規律を課す必要があります。

GCC を使用する場合は、次を使用できます。

gcc -std=c99 -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition

警告を取得します。以下を定義する必要があるため、コードは古いスタイルの定義に対して警告を受け取ります。

ProtobufCAllocator *kvs_pb_allocator(void)
{
    ...
}
于 2012-11-13T06:48:31.740 に答える
0

呼び出し元のファイルで関数を宣言しましたか。そうでない場合、コンパイラは int を返すと想定し、コードは int をポインタに拡張します。

于 2012-11-21T03:26:32.460 に答える