14

これは有効ですか

void *p = &X; /* some thing */
p += 12;

もしそうなら、pは今何を指しているのですか?私はこれを行う(そしてきれいにコンパイルする)(サードパーティの)コードを持っています、そして私の推測では、void*はchar*として扱われました。私の信頼できるK&Rは、このトピックについて沈黙しています。

編集:私の小さなテストアプリはgcc 4.1.1で正常に動作し、void*をchar*として扱います。しかし、g++バーフ

私はそれを正しく行う方法を知っています。このコードベースをクリーンアップして、すべての場所を見つける必要があるかどうかを知る必要があります。

ところで、gcc-pedanticは警告をスローします

概要:

C仕様はあいまいです。表現と関数パラメータとしての使用に関しては、void * =char*と書かれています。しかし、ポインタ演算に関しては沈黙しています。

  • gcc(4)はそれを許可し、charとして扱います*
  • g++はそれを拒否します
  • gcc-pedanticはそれについて警告します
  • vs2010cとc++の両方がそれを拒否します
4

6 に答える 6

17

いいえ、これは合法ではありません。Avoid*を任意にインクリメントすることはできません。最初に特定の型にキャストする必要があります。

特定のバイト数だけインクリメントしたい場合は、これが私が使用するソリューションです。

p = ((char*)p) + 12;

このchar型は定義されたサイズが 1 バイトであるため便利です。

編集

警告付きで gcc で実行されるのは興味深いことです。Visual Studio 2010 でテストし、コンパイルされないことを確認しました。標準についての私の限られた理解では、gcc がここでエラーになっていると言うでしょう。次のコンパイル フラグを追加できますか

-Wall -ansi -pedantic
于 2010-10-25T23:30:16.293 に答える
12

仕様から引用するには:

§6.5.6/2 : 加算の場合、両方のオペランドが算術型を持つか、一方のオペランドがオブジェクト型へのポインターで、もう一方が整数型でなければなりません。(増加は 1 を追加することと同じです。)

これらの抜粋によると、void へのポインターはオブジェクト型へのポインターではありません。

§6.2.5/1 : [...] 型は、オブジェクト型 (オブジェクトを完全に記述する型)、関数型 (関数を記述する型)、および不完全型 (オブジェクトを記述するが、それらを決定するために必要な情報を欠いている型) に分割されます。サイズ)。

§6.2.5/19 : void 型は値の空のセットで構成されます。完成できない不完全型です。

そのため、 void 型へのポインタにはポインタ演算が定義されていません。

于 2010-10-26T00:24:07.907 に答える
5

コンパイラに依存します。それを許可するものは、sizeof(*(void *)) を 1 と見なします。

編集: void ポインター演算専用です。この場合、sizeof(int) または 0 のステップを使用しても意味がありません。それを使用する人の一般的な期待は、可能な限り最小のステップです。

于 2010-10-25T23:31:52.987 に答える
2

この質問に対する投票数が最も多かった回答をご覧になることをお勧めします。

C の void ポインターのポインター演算

于 2014-02-17T06:30:31.483 に答える
2

あなたの推測は正しいです。

標準 ISO C99 のセクション 6.2.5 パラグラフ 26 では、void ポインターと文字ポインターが同じ表現とアラインメントの要件を持つことを宣言しています (言い換え)。

于 2010-10-25T23:59:55.757 に答える
1

タイプがわからないため、正しいバイト数を探すことができないため、できないと思います。

最初に型にキャストし(int)ます。

于 2010-10-25T23:45:58.937 に答える