2017-01-05 3 views
1

浮動小数点数の配列の初期化を実装したいと思います。あらかじめ計算された16進値を使用する。結果は次のようになります。あらかじめ計算された16進値で二重配列を初期化する方法は?

double arr[3]; 
memcpy(&arr[0], "\xe3\x3b\xef\xf6\xc1\x78\xc6\x3f\xf9\x37\x5a\x8d\xfd\xae\x75\x3f\x62\xe9\x58\x48\x4f\x49\xc6\x3f",24); 

そして、このような初期化を1行で行いたいと思います。この例のように(私の場合は浮動小数点数の場合):

const char s[] = "\x48\x69\x21"; 

構文的に可能ですか?

+3

いいえ、定義点でオブジェクトのオブジェクト表現を初期化する構文はありません。 –

+0

@KerrekSB:これはあまりにも一般的ではないですか? – alk

+0

@ Jarod42 - Cではそうではありません。これは、トラップ値、または実装定義されたUBではないかもしれません。 – StoryTeller

答えて

1

もっと近いものは組合になります。問題は、文字列litteralがnullの最後の文字を持っていることですが、それは動作するはずです:

union { 
    char chr[3 * sizeof(double) + 1]; 
    double arr[3]; 
} val = { "\xe3\x3b\xef\xf6\xc1\x78\xc6\x3f\xf9\x37\x5a" 
    "\x8d\xfd\xae\x75\x3f\x62\xe9\x58\x48\x4f\x49\xc6\x3f" }; 

、それは追加のバイトを使用し、単に無駄にいくつかのメモリ(32ビットマシンで、通常4バイト)が存在します標準へ


参考文献:Cで

(非規範的)ノートは、それが6.5.2.3構造と組合員

で働くべきであると述べています

ユニオンオブジェクトの内容にアクセスするために使用されたメンバが、最後に使用されたメンバと同じでない場合、オブジェクトの値のオブジェクト表現の適切な部分が のオブジェクト表現として再解釈されます。私はC++、それが許可されているかどうかを言ったりしませ用の参照を見つけることができませんでしたが、すべて共通のコンパイラはそれを受け入れる6.2.6で説明したように、新しいタイプ(時には「タイプ punning」と呼ばれるプロセス)

。私は見つけることができるより多くの関連は[class.union]組合で

、非静的データメンバの多くても1つの任意の時点でアクティブにできる、つまり、値

9.5労働組合です の非スタティックデータメンバーのほとんどは、いつでもユニオンに格納できます。ユニオンオブジェクトのすべての非スタティックデータメンバーは、同じアドレスを持ちます。プログラムは、ANの格納された値にアクセスしようとする場合

3.10左辺値と右辺値[basic.lval]

§10:それは

とを働くことができる理由を説明

以下のタイプのglvalue以外のオブジェクトを介してオブジェクトが動作していません... [ユニオンアクセスが引用されていません]

これは明らかに未定義の動作につながると言います。問題は、同じ段落(厳密エイリアシング規則として知られている)がC 6.5式§7にも存在することです。

TL/DR:ユニオンウェイは、Cでは明示的に有効ですが、おそらくC++ではUBです。私の助言は、C++プログラムにリンクされたCコンパイルユニットに置くことです。

+0

C言語ではなくC++に関する質問があり、C++でのAFAIKは 'union ' – Olaf

+1

@Olaf:場合によっては許可されています。他の用途は非標準であり、UBになりますが、実際には期待どおりに動作するでしょう。 – AndyG

+0

@Olafは質問にコメントを読んで、私はその質問がもともとCとC++の両方にタグ付けされていると仮定し、Cのみに関連する回答が適切であったと思います。 –

関連する問題