問題タブ [language-lawyer]
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.
c++ - (++i)++ は未定義の動作ですか?
(++i)++
未定義の動作ですか?後置インクリメントのインクリメントされたオブジェクトを取得した後に、前置インクリメントの副作用が発生する可能性はありますか? それは私には奇妙に思えるでしょう。
私の直感では、これは C++03 では定義されていませんが、C++11 では明確に定義されています。私は正しいですか?
c++ - `basic_streambuf::setbuf`の効果
私の問題は次のとおりです。MartinYorkは、これ、これ、およびこれstringstream
は、次のように使用することで、あるメモリから読み取ることができると答えていますbasic_stringbuf::pubsetbuf
。
残念ながら、私は標準全体を掘り下げて、それがどこで機能することが保証されているのかわかりませんでした。私が見ているのは、それは単なる実装定義です。実際、Microsoftの実装(おそらく他の実装でも)では、この呼び出しは効果がありません。
これが、前回のC++0xドラフトで見つけた関連する引用です。basic_streambuf::setbuf
[streambuf.virt.buffer]の場合:
1効果:この節(27.8.1.4、27.9.1.5)のbasic_streambufから派生したクラスごとに個別に定義される方法で、ストリームのバッファリングに影響を与えます。
2デフォルトの動作: 何もしません。これを返します。
ただし、派生クラスでは、動作は実装定義のままになっているようです。それbasic_stringbuf::setbuf
は[stringbuf.virtuals]と言っています:
1効果: setbuf(0,0)が効果を持たないことを除いて、実装定義。
それbasic_filebuf::setbuf
は[filebuf.virtuals]と言っています:
12効果: setbuf(0,0)[...]の場合、ストリームはバッファリングされなくなります。それ以外の場合、結果は実装定義です。「バッファなし」[...]
以上です。したがって、私が見ているように、有効な実装はこれらの呼び出しを完全に無視できます(null以外のパラメーターの場合)。
私が間違っている?規格の正しい解釈は何ですか?C ++ 98/03 / 0xにも同じ保証がありますか?上記のコードが機能する実装と機能しない実装について、より多くの統計がありますか?どのようbasic_streambuf::setbuf
に使用することを意図していますか?
c++ - null参照は可能ですか?
このコードは有効ですか(そして定義された動作)?
-Wall
g++とclang++はどちらも、、、、、、 ..を使用している場合でも-Wextra
、警告なしにコンパイルします。-std=c++98
-pedantic
-Weffc++
もちろん、参照はアクセスできないため(nullポインターの逆参照を意味するため)、実際にはnullではありませんが、アドレスを確認することでnullかどうかを確認できます。
c++ - プレースメント new から取得したポインターで演算子 delete を使用することの合法性
このコードは明らかに機能しないため、違法であるべきだと確信していますが、C++0x FCD では許可されているようです。
おそらく、言語弁護士の1人が、標準がこれをどのように禁止しているかを説明できるでしょう.
配列形式もあります:
これは私が見つけることができた最も近い質問です。
編集:関数への引数を制限する標準の言語が、delete-expressionvoid ::operator delete(void*)
のオペランドに意味のある方法で適用されるという引数を購入していません。せいぜい、2 つの間の接続は非常に希薄であり、多くの式がに渡すのに有効でないオペランドとして許可されます。例えば:delete
delete
void ::operator delete(void*)
void operator delete(void*)
これが、ポインタを に渡すことができるかどうかが、同じポインタを のオペランドとして使用できるかどうかに関係がないことを示していることを願っていますdelete
。
c++ - typedef および new での typename キーワードの使用
このコードを考えてみましょう。
typename
上記のコードでは、テンプレート内のネストされた型とネストされた値の間のあいまいさを解消できるように、キーワードがコンパイラによって必要とされます。つまり、typename
キーワードがない場合、コンパイラはこれを T::X と x の乗算として解釈します。
このようなあいまいさが生じ得る状況では、あいまいさを取り除くためにキーワードtypename
が必要になります。しかし、コンテキスト自体があいまいさを取り除く状況はほとんどありません。もう1 つのトピックでは、基本クラスと関数パラメーターのコンテキストについて説明します (ただし、後者はあいまいさを取り除きません)。このトピックでは、明確に思われる他の 2 つのコンテキストについて特に説明したいと思いますがtypename
、それでも書く必要があります。
これらの 2 つの状況では、キーワードtypedef
とは、その後に続くものはすべてtypeであり、 valueではないnew
ことをコンパイラーに十分に明確にします。
だから私の質問は、 andを使用するときのような明確な状況でも、なぜコンパイラはまだtypename
キーワードを必要とするのですか?typedef
new
編集(Johannes Schaubからのこの応答を読んだ後):
この構文では、質問を少し変更して、私が言おうとしている点が他の人に見えるようにする必要があります。
このことを考慮、
したがって、コンテキストから、 T::X が の前 typedef
または後 のどちらに表示されても、コンパイラには T::X が型であることはまだ十分に明らかtypedef
です。C++でtypedef 5 five
or typedef T::value t_value
(ここで T::value はvalue ) の記述が許可されていない限り、それ自体が存在することでtypedef
すべてのあいまいさが取り除かれるため、 typename
(そのような状況では) 標準による不要な要件のように思われます。についても同じことが言えnew
ます。
また、この構造体をテンプレート引数として使用するクラス テンプレートを作成しました。
特に、次のコード (コンストラクターから) が正しい (移植可能) かどうかを知りたいのですが、
完全なコードはideoneにあります。返信する前にご覧ください。:-)
c++ - C ++での削除演算子の効果を手動でシミュレートすることは正式に違法ですか?
私はこれが賢明ではないことを認識しており、そうすることを提案していませんが、次のことが実際に正式に違法であるかどうかについて興味があります。
delete x;
デストラクタを呼び出してから呼び出すのと同じことは私の理解ですが::operator delete(x);
、標準に従って手動で行うことは合法ですか?これは、新しい配置を使用する場合に有効なことですが、配置以外の場合はどうでしょうか。delete
私の勘では、それぞれに対して実行する必要があるため(ではなくoperator delete
) 、違法である可能性がありますがnew
、確実に知りたいと思います。
c++ - 基本クラスの「デフォルト」アクセス指定子の違いの根拠
C++ ではstruct
との間にほとんど違いがないことを私は知っています。class
また、いくつかの違いの理由も理解しています。このように、
- struct のメンバーはデフォルトで public です。class のメンバーは
デフォルトで private です。struct のメンバーがデフォルトで public になって
C++-struct
いるのは、 との互換性を持たせるためC-struct
です。また、クラスのメンバーがデフォルトでプライベートである理由は、データのカプセル化の概念を導入するためです(つまり、オブジェクト指向の原則/テクニック/その他を適用します)。
私が理解していないのは、標準 $11.2/2 [class.access.base] を引用して、これです
基本クラスのアクセス指定子がない場合、派生クラスが struct として宣言されている場合は public が想定され、クラスが class として宣言されている場合は private が想定されます。
このねじれと反均一性の根拠は何ですか? なぜこの違いが必要なのですか?
標準からの例、
ここで、B は D2、D4、および D6 のパブリック ベース、D1、D3、および D5 のプライベート ベース、および D7 および D8 の保護ベースです。
編集
構造体とクラスのデフォルトのアクセスが異なることを考えると、この違いは理にかなっていると言う人もいるかもしれません (違いは上記の箇条書きに示されています)。しかし、どのように派生させても、inherited-struct
完全に(継承をサポートしていない)と互換性がないと思います。C-struct
私は間違っているかもしれませんが。そのため、おそらく例を使用して、適切な説明を求めています! :-)
c++ - 明示的なメンバーの特殊化
g++ 3.4.5 は次のコードを受け入れます。
しかし、それが実際に合法的な C++03 であるかどうかはわかりません。特に、
[14.7p3] クラス テンプレート、クラス テンプレートのメンバー、またはクラス メンバー テンプレートの明示的な特殊化宣言では、明示的に特殊化されるクラスの名前は template-id になります。
この要件は、この例の最後で非 typedef バージョンを使用する必要があることを示していますか? それとも私は何かを誤解しましたか?
編集: さらなる証拠:欠陥レポート 403は、型 (そのコンテキストでは、関数呼び出し式の引数の型) を template-id と言うのは正しくないことを示唆しています。 1。標準のその後のドラフトでは、3.4.2の「 template-id 」の代わりに「クラス テンプレートの特殊化」が使用されています。
A<B>
これは、 と が同じ型をC
表している (そして、同一またはほぼ同一の意味的意味を持っている)が、テンプレート ID でありA<B>
、テンプレートIDでC
はないという引数をサポートします。それらのトークンの意味。
c - printf("%x",1) は未定義の動作を引き起こしますか?
C 標準 (6.5.2.2 パラグラフ 6) によると
呼び出された関数を示す式の型がプロトタイプを含まない場合、各引数に対して整数昇格が実行され、float 型の引数は double に昇格されます。これらは、デフォルト引数プロモーションと呼ばれます。引数の数がパラメーターの数と等しくない場合、動作は未定義です。関数がプロトタイプを含む型で定義されていて、プロトタイプが省略記号 (, ...) で終わっているか、昇格後の引数の型がパラメーターの型と互換性がない場合、動作は未定義です。関数がプロトタイプを含まない型で定義されており、昇格後の引数の型が昇格後のパラメーターの型と互換性がない場合、次の場合を除き、動作は未定義です。
- 一方の昇格型は符号付き整数型で、もう一方の昇格型は対応する符号なし整数型であり、値は両方の型で表現可能です。
- 両方の型は、文字型または void の修飾または非修飾バージョンへのポインターです。
したがって、一般に、渡された値が両方の型に適合する限り、int
an を期待する可変引数関数に an を渡すこと (またはその逆) に問題はありません。unsigned int
ただし、printf
読み取りの仕様 (7.19.6.1 パラグラフ 9):
変換指定が無効な場合、動作は未定義です。引数が対応する変換指定に対して正しい型でない場合、動作は未定義です。
符号付き/符号なしの不一致は例外ではありません。
printf("%x", 1)
これは、未定義の動作を呼び出すことを意味しますか?
c - mbrtowc の s==NULL ケースの目的は何ですか?
mbrtowc
(マルチバイト文字ポインター) 引数のポインターを次NULL
のように処理するように指定されています。s
s がヌル ポインターの場合、mbrtowc() 関数は次の呼び出しと同等になります。
この場合、引数 pwc と n の値は無視されます。
私が知る限り、この使用法はほとんど役に立ちません。が部分的に変換された文字を格納していない場合ps
、呼び出しは副作用なしで単に 0 を返します。ps
が部分的に変換された文字を格納している場合'\0'
、 はマルチバイト シーケンスの次のバイトとして有効ではないため ('\0'
文字列ターミネータのみを指定できます)、呼び出しは を返し(size_t)-1
ますerrno==EILSEQ
。ps
未定義の状態のままにします。
意図された使用法は、状態変数をリセットすることだったようです。特にNULL
が渡され、内部状態が使用された場合、ステートフル エンコーディングでの の動作ps
に似ていますが、これは私が知る限りどこにも指定されていません。部分的に変換された文字の のストレージのセマンティクスと競合します (潜在的に有効な初期サブシーケンスの後に 0 バイトに遭遇したときに状態をリセットすると、この危険で無効なシーケンスを検出できなくなります)。mbtowc
mbrtowc
mbrtowc
が の場合mbrtowc
にのみ状態変数をリセットするように指定されていて、それが 0 バイトを指している場合s
はNULL
そうでない場合、望ましい状態リセット動作は可能ですが、そのような動作は書かれている標準に違反します。これは規格の欠陥ですか?私が知る限り、不正なシーケンスに遭遇すると内部状態 ( is の場合に使用) をリセットする方法はまったくないため、正しいプログラムは を使用できps
ません。NULL
mbrtowc
ps==NULL