2017-01-02 24 views
1

「ptr」をキャストして、2行書き込まずに直接zend_longを割り当てる方法は?Cポインタ型キャスト

zend_long *val = *ptr; 
*val = *(ISC_LONG*)var->sqldata; 
+1

タイプの 'ptr' ??? –

+0

"char ** ptr" 実際には単なるバッファバッファです – Marcodor

+1

_compatible_type_でない限り、これは未定義の動作を呼び出します。 – Olaf

答えて

3

元のコードが正しいと仮定するとは、対応する割り当ては次のようになります。2つの構造体は、互換性のあることが起こる場合を除き

ポインタがこれらのようなキャスト
*((zend_long*)*ptr) = *(ISC_LONG*)var->sqldata; 
+1

それは、多くのありがとう! – Marcodor

+0

これは、厳密なエイリアシング違反のために未定義の動作を引き起こす可能性が非常に高いです。 'zend_long'が' ISC_LONG'と型互換性を持たない限り、 – Lundin

+0

@ Lundinそうです。これが、元のコードが正しい場合にのみ上記が機能すると書いた理由です。 – dasblinkenlight

0

は、Cで明確に定義された行動ではありませんタイプ。つまり、同じメンバーを同じ順序で持つ必要があります。

もしそれがなければ、残念なことにCでこれを行う簡単な方法はありません。どうにかして "働く"ことができれば、それは単に不運です。あなたのコードはいつでもクラッシュする可能性があります未定義の挙動が原因です。

これは、このようなキャストがいわゆるstrict aliasing ruleに違反しているためです。たとえば、ユニオンタイプの中に構造体をラップすることによって、そのルールをかわす必要があります。

+0

ありがとうございました。私はオーバーキャストも好きではありません。しかし、これはこの場合強制されます。ここで定義されているISC_LONG:https://github.com/FirebirdSQL/firebird/blob/c6d9135586fde54b52e5c26f74d5dfd20c188f3f/src/include/types_pub.h#L111とzend_longは、PHPソースでほぼ同じ定義をしています。価値によって割り当てることは安全でなければなりません。 – Marcodor

+0

@Marcodor同じサイズの整数型であれば問題ありません。それらのサイズが異なる場合、または構造体である場合、問題が発生します。 – Lundin

関連する問題