問題タブ [pointer-conversion]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
3 に答える
2025 参照

c++ - 派生**からベース**への変換

私はこれを読んでいましたが、残念ながらコンパイラが Derived** から Base** への変換を許可しない理由を深く理解できませんでした。また、parashift.com のリンク以外の情報を提供しないthisも見ました。

編集:

このコードを 1 行ずつ分析してみましょう。

0 投票する
1 に答える
313 参照

c++ - ポインタからポインタから定数への変換

constポインタ間の変換について説明しているC++Gotchasという本を読んでいて、次のルールを理解するのに問題があります。

タイプTと整数n>0が存在する場合、2つのポインタタイプT1とT2は類似しており、次のようになります。

T1はcv1、0はcvへのポインタ、1は。へのポインタです。。。cv 1、n-1 cv 1、 nTへのポインタ

と、

T2は、 cv2,0からcv2,1へポインタです。。。cv 2、n-1 cv 2、 nTへのポインタ

ここで、各cvi、jは、const、volatile、const volatile、または何もありません。

誰かが私に説明を得ることができる正しい方向に私を向けることができますか、または上記の各シーケンスでcv1,0cv1,1が何を意味するかを知っている人はいますか?その本は私がそれを理解するのに十分助けていない。しかし、これはC++言語と関係があると確信しています。

0 投票する
1 に答える
14725 参照

c++ - 参照によるconstポインタの受け渡し

次のコードがコンパイルできない理由がわかりません

コンパイラは次のようにエラーを出します:

エラー:タイプ'float*'の式からのタイプ'const float *&'の参照の初期化が無効です

しかし、fooで参照せずに渡そうとすると、正常にコンパイルされます。

参照で渡すかどうかに関係なく、同じ動作を示すはずだと思います。

ありがとう、

0 投票する
1 に答える
1031 参照

c++ - C++ での reinterpret_cast

このコードを実行しようとすると、行にセグメンテーション違反があります

uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);

実際、ある場所では問題なく動作しています。別の場所では、セグフォルトが発生しています。

0 投票する
1 に答える
1083 参照

c - uchar 配列の uint8 型ポインタへの変換

uchar の配列を uint8 ポインターに変換したい。どちらも 8 ビットで、値の範囲は 0 から 255 であるため、原因と問題は発生しないと思います。

上記のリストを uint8t へのポインターを受け入れる関数に渡す必要があります。私はこのようにそれを渡すことができます:

uint8として読み取ったときに値に影響を与えないようにします。

0 投票する
2 に答える
276 参照

c - ポインターによる型変換

型キャストがポインターでどのように機能するかを理解するのに途方に暮れています

*(byte )&xで何が起こっていますか? &x は、変数xのアドレスを意味します。では、アドレスを型キャストすることは何を意味するのでしょうか? ptr は x も参照できるようになりましたか? はいの場合、データは失われませんか?

また、 ptrのサイズは?

0 投票する
1 に答える
430 参照

c++ - ポインター/整数演算 (未) 定義の動作

次の関数テンプレートがあります。

目的は、特定のタイプのオブジェクトを複製し、入力と同じサブオブジェクトによって「保持」されたオブジェクトを返すことです。原則として、HeldAsは のあいまいまたはアクセスできない基本クラスになる可能性があるMostDerivedため、ここではキャストは役に立たないことに注意してください。

これは私のコードですが、私の制御外の型で使用できます (つまり、MostDerivedまたはを変更することはできませんHeldAs)。関数には次の前提条件があります。

  • *original動的タイプですMostDerived
  • HeldAsMostDerivedまたは直接的または間接的な基底クラス( MostDerivedcv 修飾を無視)
  • *held*originalまたはその基本クラスのサブオブジェクトの 1 つを参照します。

前提条件が満たされているとしましょう。duplicateそのような場合の動作を定義していますか?

C++11 [expr.reinterpret.cast] は言います (太字は私のものです):

4 ポインターは、それを保持するのに十分な大きさの任意の整数型に明示的に変換できます。マッピング関数は実装定義です。[注:基礎となるマシンのアドレッシング構造を知っている人にとっては驚くべきことではありません。—終わりのメモ] ...

5 整数型または列挙型の値は、明示的にポインターに変換できます。十分なサイズの整数に変換され (実装に存在する場合)、同じポインター型に戻されるポインターは、元の値を持ちます。それ以外の場合、ポインターと整数の間のマッピングは実装定義です。[注: 3.7.4.3 で説明されている場合を除き、このような変換の結果は、安全に導出されたポインター値にはなりません。—終わりのメモ]

OK、私のコンパイラが GCC (または実装定義の動作の GCC の定義を使用するため、Clang) であるとしましょう。C ++実装定義の動作に関するGCCドキュメントの第5章を引用:

... いくつかの選択肢は、C 言語の対応するドキュメントに記載されています。C の実装を参照してください。...

4.7 章(C 実装、配列、およびポインター) に進みます。

ポインターを整数に、またはその逆に変換した結果 (C90 6.3.4、C99 および C11 6.3.2.3)。

ポインターから整数へのキャストは、ポインター表現が整数型よりも大きい場合は最上位ビットを破棄し、ポインター表現が整数型よりも小さい場合は符号拡張し、そうでない場合はビットを変更しません。

整数からポインタへのキャストは、ポインタ表現が整数型よりも小さい場合は最上位ビットを破棄し、ポインタ表現が整数型よりも大きい場合は整数型の符号に従って拡張し、それ以外の場合はビットを変更しません。

ここまでは順調ですね。whichを使用しstd::uintptr_tているため、どのポインターに対しても十分な大きさであることが保証されており、同じ型を扱っているため、 asが指していcopyHeldたのと同じHeldAsサブオブジェクトを指す必要があるように思われます。*copyheld*original

残念ながら、GCC ドキュメントにはもう 1 つの段落があります。

ポインターから整数にキャストし、再びキャストする場合、結果のポインターは元のポインターと同じオブジェクトを参照する必要があります。そうでない場合、動作は未定義です。つまり、C99 および C11 6.5.6/8 で禁止されているように、ポインター演算の未定義の動作を回避するために整数演算を使用することはできません。

ワム。そのため、最初の 2 つの段落のルールに従っての値copyHeldが計算されたとしても、3 番目の段落ではこれが未定義動作領域に送信されているようです。

基本的に 3 つの質問があります。

  1. 私の読みは正しく、duplicate未定義の動作はありますか?

  2. これはどのような未定義の動作ですか? 「正式には定義されていませんが、とにかくやりたいことをします」種類、または「ランダムなクラッシュおよび/または自発的な焼身自殺を期待する」種類ですか?

  3. 本当に未定義の場合、明確に定義された (おそらくコンパイラに依存する) 方法でそのようなことを行う方法はありますか?

私の質問は、コンパイラに関する限り GCC (および Clang) の動作に限定されていますが、一般的なデスクトップからエキゾチックなものまで、あらゆる種類のハードウェア プラットフォームを考慮した回答を歓迎します。

0 投票する
1 に答える
114 参照

c++ - Derived T::* を Base T::* にキャストできないのはなぜですか?

背景:多くの関数型言語は代数データ型をサポートしており、仮想関数と継承である程度エミュレートできます。

派生型のサイズが異なるため、最も明白な解決策はヒープの割り当てです。ただし、ユニオンを使用して、追加の割り当てなしでスタック上の最大の型を保持できるはずです。これには、ベースへの追加のポインターを共用体と共に格納する必要があり、同時にコピーと代入が複雑になります。

アクティブなユニオン メンバーを指すユニオンの先頭からのオフセットとしてメンバー セレクターを格納することにより、後者の問題を解決することは非常に重要です。C++には、各メンバーへのポインターが異なる型を持つことを除いて、目的にほぼ適合しているように見えるメンバーポインターがあります。

質問: Derived T::* を Base T::* にキャストできないのはなぜですか?

上記とは関係のない、同じ制限にぶつかるおもちゃの例を次に示します。

生成されたコンパイル エラー:

0 投票する
1 に答える
1130 参照

c - C 関数ポインター型の互換性

関数コールバックで動作するライブラリを作成して、同じ呼び出し規則と同じシグネチャを持つ型への関数ポインターを頻繁に型キャスト (および呼び出し) しましたが、1 つの例外があります: それらには異なる型 (すべてのデータ) を指すパラメーターがありました。または無効なポインター。

最近、これによると、それほど安全ではない可能性があることを発見しました: https://stackoverflow.com/a/14044244/3079266

基本的には、引数の型に互換性があるということは、関数ポインタの型にも互換性があるということであり、問​​題ないはずだということがわかりました。

さて、質問が3つあります。

最初:これは、異なる型へのポインターは技術的に互換性がないため、私がしていることは未定義の動作を引き起こす可能性があるということですか?

2番目:どこで(どのアーキテクチャで)それを回避できますか?その中に Windows x86 または x64 バージョンはありますか?

3番目:どこで逃げられないのですか?