2017-03-27 29 views
4

次のコードでは、ポインタ変換の途中で(VOID *)が必要な理由は何ですか?ポインタ変換で(void *)が必要なのはなぜですか?

いくつかのコンテキストの定義:

#define VOID  void 
typedef unsigned char  UINT8; 


ErrorDest = (EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE *) 
      (VOID *) 
      ((UINT8 *)Hest + Hest->Header.Length); 
+1

'VOID'は' void'の何か奇妙なマクロ/ typedefですか?また、 '(VOID *)'なしでどんなエラーが出るのですか? – hyde

+1

(結果の)タイプが実際にどのようなものか推測できないので、いくつかのコンテキストが役立ちます。 – Eiko

+2

13Kのユーザーが本当に知っておくべきであるように、より多くの詳細が提供される必要があります。 – LPs

答えて

8

私が見ることができる唯一の理由は、ポインタの位置合わせに関する警告を与えることから、コンパイラを防ぐためです。

UINT8には位置合わせの要件はありません。

structは、メンバーに応じて他のアライメント要件を持つことができます。通常、構造体のアライメント要件は、メンバーの最大アラインメント要件と同じです。 EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTUREが不透明な型(宣言されていますがメンバーは不明です)または整列要件を持つメンバーが含まれている場合、コンパイラは整列に関する警告を発行することがあります。

void*は任意のアドレスを指すことができますが、別のポインタ型にキャストされている場合、その型が整列要件を持っていても境界整列の警告からは除外されます。

1

別の回答で指摘されているように、理由が整列の可能性があります。しかし、それはバグかもしれません - 互換性のないポインタ型エラーを避ける試みが失敗しました。

this_t* a = (that_t*)b;のようなコードを書くと、互換性のない型に関するコンパイラエラーが発生します。確かに、これはコンパイラエラーを沈黙さ

this_t* a = (void*)(that_t*)b; // bad, dont do this 

を書き込むことによって、このエラーを解決しようとする幾分よくある間違いです。そして、コンパイラエラーの代わりに、厳密なエイリアシング違反のために、実行時の未定義の動作のバグがあります。

EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTUREには、uint8_t []というメンバが含まれていない場合、厳密なエイリアシング違反のために問題のコードが未定義の動作を呼び出します。

関連する問題