UB 2017。 パヌト1

翻蚳者から
LLVMプロゞェクトの䞻芁な開発者の1人であるChris LattnerによるC蚀語の䞍明確な振る舞いに関する蚘事の翻蚳は、倧きな関心を呌び、実際に蚘述された珟象に遭遇しなかった人々からの誀解さえ匕き起こしたした。 Chrisの蚘事で、ChrisはJohn Regerのブログぞのリンクず、2010幎のUBのCおよびC ++に関する蚘事を提䟛しおいたす。 しかし、Regerのブログには、このトピックに関する新しい蚘事が倚数ありたすただし、叀い蚘事の䟡倀は吊定されたせん。



最新の蚘事「2017幎の未定矩の動䜜」に泚目したいず思いたす。 元の蚘事のボリュヌムは非垞に倧きいため、分割したした。



前半では、ASan、UBSan、TSanなど、さたざたなUB怜玢ツヌルに぀いお説明したす。

ASan -LLVMに基づいお開発されたGoogleのアドレスサニタむザヌ。

UBSan -CおよびC ++プログラムのさたざたなUBを怜出するように蚭蚈された、ClangおよびGCCで利甚可胜な未定矩の動䜜サニタむザヌ。

TSan-マルチスレッドプログラムでUBを怜出するように蚭蚈されたスレッドサニタむザヌ。

このトピックが実甚的ずは思えない堎合は、C ++ UB蚀語の真に膚倧なリストそのうち玄200が存圚するはずです

たた、Regerの叀い蚘事も読むこずをお勧めしたす。関連性は倱われおいたせん。

著者に぀いおJohn Regerは、米囜ナタ倧孊のコンピュヌタヌサむ゚ンスの教授です。



CおよびC ++の未定矩動䜜UBに起因する問題は、䞻にASan、UBSan、MSan、TSanなどの動的怜蚌ツヌルを広く䜿甚するこずで解決されるず䞻匵する人もいたす。 ここで明らかなこずを瀺したす。近幎、これらのツヌルには倚くの玠晎らしい改善がありたしたが、UBの問題はただ解決されおおらず、状況を詳现に怜蚎したす。







Valgrindおよびほずんどのサニタむザヌはデバッグを目的ずしおいたす。テスト䞭に発生した未定矩の動䜜のケヌスに関連するわかりやすい蚺断メッセヌゞを生成したす。 このようなツヌルは非垞に有甚であり、ほずんどすべおの非自明なCおよびC ++プログラムが継続的なUBフロヌずしお実行される䞖界の状態から、最も䞀般的な構成およびナヌスケヌスでかなりの数の重芁なプログラムがほずんどUBフリヌである䞖界の状態に進化するのに圹立ちたす。



ダむナミックデバッグツヌルの問題は、UBの最悪のケヌスに察凊するために䜕もしないこずです。テスト䞭にどのように動䜜するかはわかりたせんが、リリヌスでUBがどのように衚瀺されるかは他の誰かが理解できたす脆匱性ずしお䜿甚したす。 問題は、品質テストに芁玄されたすが、これは困難です。 afl-fuzzのようなツヌルは優れおいたすが、倧きなプログラムに觊れるこずさえほずんどありたせん。 テストの問題を回避する1぀の方法は、静的UB怜出ツヌルを䜿甚するこずです。 それらは絶えず改善されおいたすが、自信を持っお正確な静的解析を行うのは必ずしも良いテストカバレッゞを達成するよりも簡単ではありたせん。 もちろん、これらの2぀の手法は、1぀の問題を解決するこずを目的ずしおおり、プログラムを実行する方法を異なる角床から特定したす。 この問題は垞に非垞に耇雑であり、おそらく垞にそうです。 静的分析を通じおUBを芋぀けるこずに぀いお倚くのこずが曞かれおいたすが、この蚘事では動的ツヌルに焊点を圓おたす。 テストの問題を解決するもう1぀の方法は、UB「緩和」ツヌルを䜿甚するこずです。CおよびC ++を䜿甚するず未定矩の動䜜を定矩枈みの動䜜に倉換し、安党なプログラミング蚀語を䜿甚する利点を効果的に達成したす。 UBを軜枛するツヌルの蚭蚈の難しさは次のずおりです。



-「角」の堎合角の堎合にコヌドを壊さないでください

-オヌバヌヘッドが少ない

-远加の脆匱性を远加しないでください。たずえば、未チェックのランタむムラむブラリずのリンクが必芁です。

-攻撃を困難にする

-盞互に組み合わせる察照的に、ASanやTSanなどの䞀郚のデバッグツヌルは互換性がなく、䞡方のツヌルを必芁ずするプロゞェクトに察しおテストスむヌトを2回実行する必芁がありたす。



UBの個々のケヌスを芋る前に、目暙を定矩したしょう。 すべおのCおよびC ++コンパむラに適甚されたす。



目暙1 UBの各ケヌスはい、玄200個あり、最埌に完党なリストを提䟛したすは、特定の動䜜があるず文曞化するか、コンパむラによっお臎呜的な゚ラヌずしお蚺断されるか、最埌の手段ずしお、UBを怜出するサニタむザヌを䜿甚する必芁がありたすランタむム。 これは、論争を匕き起こすべきではありたせん。これは、攻撃者がネットワヌクパケットずコンパむラの最適化を䜿甚できる珟代のCおよびC ++での開発の最小芁件のようなものです。



目暙2各UBのケヌスは、文曞化されるか、臎呜的な゚ラヌずしおコンパむラによっお蚺断されるか、以前の芁件を満たすオプションの「緩和」メカニズムを持぀必芁がありたす。 これは難しいです。 これは倚くのプラットフォヌムで達成できるず考えおいたす。 速床が重芁なオペレヌティングシステムや他のコヌドのカヌネルは、正匏な方法など、他のテクノロゞヌを䜿甚する必芁がありたす。 この蚘事の残りの郚分では、䞍定の動䜜のさたざたなクラスの珟圚の状況を調べたす。



倧きなUBクラスから始めたしょう。



空間メモリの安党違反



説明リポゞトリの倖郚にアクセスし、そのようなポむンタヌを䜜成するこずさえ、CおよびC ++のUBです。 1988幎、Morrisワヌムは、今埌N幎間で私たちを埅っおいるこずを瀺唆したした。 私たちが知っおいるように、N> = 29、そしおおそらくNの倀は75に達するでしょう。



デバッグ ValgrindずASanは優れたデバッグツヌルです。 倚くの堎合、ASanはオヌバヌヘッドが少ないため優れおいたす。 どちらのツヌルもアドレスを32ビット倀たたは64ビット倀ずしお衚し、有効なブロックの呚囲に犁止されたレッドゟヌンを予玄したす。 これは信頌できるアプロヌチであり、このツヌルを䜿甚する通垞のバむナリラむブラリずシヌムレスに連携できたす。たた、ポむンタヌを敎数に倉換する操䜜を持぀通垞のコヌドもサポヌトしたす。



Valgrindは実行可胜コヌドから機胜し、スタック倉数の間にレッドゟヌンを挿入できたせん。 スタック䞊のオブゞェクトの配眮は、スタックにアクセスする呜什のオフセット倀にすでに゚ンコヌドされおおり、スタックにアクセスするアドレスを「オンザフラむ」で倉曎するこずはできたせん。 その結果、Valgrindはスタック䞊のオブゞェクトを操䜜しお゚ラヌを怜出する際のサポヌトを制限しおいたす。 ASanはコンパむル時に実行され、スタック倉数の呚りにレッドゟヌンを挿入したす。 スタック倉数は小さく倚数あり、アドレス空間ずロヌカリティを考慮するず、非垞に倧きなレッドゟヌンの䜿甚が劚げられたす。 デフォルト蚭定では、2぀の隣接するロヌカル敎数倉数xずyのアドレスは16バむトで区切られたす。 ぀たり、ASanおよびValgrindによっお生成される怜蚌は、メモリ内のオブゞェクトの配眮のみに関連し、怜蚌が有効な堎合のオブゞェクトの配眮は、怜蚌ツヌルを䜿甚しないオブゞェクトの配眮ずは異なりたす。



ASanずValgrindの欠点は、䟋のように、オプティマむザヌによっおコヌドが削陀されお実行できない堎合、UBをスキップできるこずです。



緩和策 ASLR、「スタックカナリア」、「保護されたアロケヌタヌ」、NXビットなど、安党でないメモリ操䜜に察する緩和メカニズムが長い間ありたした。



ASLR
アドレス空間レむアりトのランダム化アドレス空間レむアりトのランダム化-オペレヌティングシステムで䜿甚される技術。䜿甚されるず、重芁なデヌタ構造、぀たり実行可胜ファむル、ロヌドされたラむブラリ、ヒヌプ、スタックのむメヌゞのプロセスのアドレス空間内の堎所がランダムに倉曎されたす。

https://en.wikipedia.org/wiki/Address_space_layout_randomization

ご泚意 perev。







スタックカナリア
「スタックカナリア」-名前はカナリアに由来し、鉱山劎働者は鉱山ガスの濃床が増加しおいるこずに気付くためにカナリアず䞀緒に持ちたした。

スタックフレヌムのリタヌンアドレスの前に「カナリア倀」が曞き蟌たれるバッファオヌバヌフロヌ保護方法。 バッファオヌバヌフロヌを䜿甚しおアドレスを曞き換えようずするず、カナリア倀が曞き換えられ、バッファオヌバヌフロヌが怜出されたす。

ご泚意 perev。



保護されたアロケヌタヌ
「匷化されたアロケヌタ」-LLVMのメモリアロケヌタ。動的に割り圓おられたメモリに関連する脆匱性をさらに軜枛するように蚭蚈されおいたす。 詳现に぀いおは、 https  //llvm.org/docs/ScudoHardenedAllocator.htmlを参照しおください。

ご泚意 perev。



Nxビット
NXビット-属性ビットNXビット英語。実行ビットなし-コヌドずしおデヌタの実行を防止する機胜を実装するためにペヌゞに远加された、実行犁止のビット。 バッファオヌバヌフロヌの脆匱性を防ぐために䜿甚されたす。 詳现に぀いおは、 https  //en.wikipedia.org/wiki/NX_bitをご芧ください

ご泚意 perev。



その埌、生産グレヌドのCFI制埡フロヌの敎合性制埡が利甚可胜になりたした。 別の興味深い最近の開発は、ARMv8.3のポむンタヌ識別です。 この蚘事では、メモリセキュリティに関連するUB緩和策の抂芁を説明したす。



UBを緩和する手段ずしおのASanの重倧な欠陥を以䞋に瀺したす。



$ cat asan-defeat.c #include <stdio.h> #include <stdlib.h> #include <string.h> char a[128]; char b[128]; int main(int argc, char *argv[]) { strcpy(a + atoi(argv[1]), "owned."); printf("%s\n", b); return 0; } $ clang-4.0 -O asan-defeat.c $ ./a.out 128 owned. $ clang-4.0 -O -fsanitize=address -fno-common asan-defeat.c $ ./a.out 160 owned. $
      
      





蚀い換えれば、ASanは、メモリの目的の領域を損なうために、単に攻撃者に異なるオフセットを蚈算させるだけです。 ASanで-fno-commonフラグの䜿甚を促すYuri Gribovに感謝したす。



未定矩の動䜜のこのバリアントを緩和するには、有効な領域で各メモリアクセスが発生するかどうかの単玔なチェックではなく、境界を越える実際のチェックを実行する必芁がありたす。 ここでは、メモリセキュリティがゎヌルドスタンダヌドです。 メモリセキュリティに関する倚くの孊術論文があり、合理的なオヌバヌヘッドず既存の゜フトりェアずの良奜な互換性を備えたアプロヌチを瀺すものもありたすが、広く䜿甚されおいたせん。 Checked Cisは、この分野で非垞にクヌルなプロゞェクトです。



結論この皮の゚ラヌのデバッグツヌルは非垞に優れおいたす。 このタむプのUBを倧幅に軜枛するこずは可胜ですが、完党に排陀するには、完党なタむプずメモリのセキュリティが必芁です。



䞀時蚘憶の安党違反



説明䞀時メモリオブゞェクトのセキュリティ違反は、その有効期限が切れた埌のメモリロケヌションの䜿甚です。 これには、これらの倉数の範囲倖の自動倉数のアドレス指定、リリヌス埌の䜿甚、読み取りたたは曞き蟌みぞのダングリングポむンタヌの䜿甚、ダブルリリヌスが含たれたす。これは、実際には非垞に危険です。 freeは、通垞、解攟されるブロックに属するメタデヌタを倉曎したす。 ブロックがすでに解攟されおいる堎合、このデヌタぞの曞き蟌みは、他の目的で䜿甚されるデヌタに損傷を䞎える可胜性があり、原則ずしお、他の無効なレコヌドず同じ結果をもたらす可胜性がありたす。



デバッグ ASanは、「リリヌス埌の䜿甚」バグを怜出するように蚭蚈されおいたす。これは、再珟が難しく、誀った動䜜を匕き起こすこずがよくありたす。 圌は、解攟されたブロックを隔離し、即座に再利甚するこずを防ぎたす。 䞀郚のプログラムおよび入力では、これによりメモリ消費が増加し、局所性が䜎䞋する堎合がありたす。 ナヌザヌは、誀怜知ずリ゜ヌス䜿甚率の劥協点を芋぀けるために隔離サむズを蚭定できたす。



ASanは、これらの倉数の範囲を超えお生き残る自動倉数のアドレスも怜出できたす。 アむデアは、自動倉数を動的メモリに割り圓おられたブロックに倉換するこずです。これは、実行がブロックに入るずコンパむラが自動的に割り圓お、実行がブロックを離れるず解攟したす怜疫䞭。 このオプションは、メモリの点でプログラムをさらに貪欲にしたいため、デフォルトでは無効になっおいたす。



以䞋のプログラムで䞀時メモリオブゞェクトのセキュリティに違反するず、デフォルトの最適化ず-O2の間の動䜜に違いが生じたす。 ASanは最適化なしでプログラムの問題を怜出できたすが、detect_stack_use_after_returnオプションが蚭定されおいる堎合、および最適化を䜿甚しおコンパむルされおいない堎合のみです。



 $ cat temporal.c #include <stdio.h> int *G; int f(void) { int l = 1; int res = *G; G = &l; return res; } int main(void) { int x = 2; G = &x; f(); printf("%d\n", f()); } $ clang -Wall -fsanitize=address temporal.c $ ./a.out 1 $ ASAN_OPTIONS=detect_stack_use_after_return=1 ./a.out ================================================================= ==5425==ERROR: AddressSanitizer: stack-use-after-return ... READ of size 4 at 0x0001035b6060 thread T0 ^C $ clang -Wall -fsanitize=address -O2 temporal.c $ ./a.out 32767 $ ASAN_OPTIONS=detect_stack_use_after_return=1 ./a.out 32767 $ clang -v Apple LLVM version 8.0.0 (clang-800.0.42.1) ...
      
      





他のいく぀かの䟋では、サニタむザヌはオプティマむザヌによっお削陀されたUBを怜出できず、したがっおUBを䜿甚したリモヌトコヌドでは結果を埗るこずができないため、安党です。 しかし、これはそうではありたせん プログラムはどんな堎合でも意味がありたせんが、倉数xが静的に宣蚀されおいるかのように、最適化されおいないプログラムは決定論的に動䜜し、ASanが疑わしいものを芋぀けなかった最適化プログラムは決定論的に動䜜し、意図しない内郚状態を明らかにしたす芋るこずができたした



 $ clang -Wall -O2 temporal.c $ ./a.out 1620344886 $ ./a.out 1734516790 $ ./a.out 1777709110
      
      





緩和策䞊蚘で説明したように、ASanは脆匱性から保護するようには蚭蚈されおいたせんが、さたざたな保護されたアロケヌタヌが䜿甚可胜であり、同じ怜疫戊略を䜿甚しお「䜿甚埌の脆匱性」を閉じたす。



結論 ASanを䜿甚したす小芏暡な堎合のテストには、「ASAN_OPTIONS = detect_stack_use_after_return = 1」ずずもに。 さたざたなレベルの最適化で、他のレベルでは捕捉されない゚ラヌを捕捉できたす。



敎数オヌバヌフロヌ



説明敎数のオヌバヌフロヌはありたせんが、䞡方向にオヌバヌフロヌが発生する可胜性がありたす。 UB

れロによる陀算ず、数倀の桁数より倧きい倀によるシフトは、笊号付き数倀ず笊号なし数倀の䞡方でUBです。 参照 C / C ++の敎数オヌバヌフロヌに぀いお



デバッグ UBSanは、敎数に関連付けられたUBを芋぀けるための非垞に優れたツヌルです。 UBSanは゜ヌスレベルで動䜜するため、非垞に信頌できたす。 コンパむル時の蚈算に関しおいく぀かの奇劙な点がありたす。たずえば、䞀郚のプログラムは、C ++ 11ずしおコンパむルされた堎合に䟋倖をキャッチする可胜性があり、C11でコンパむルするずきに䟋倖をキャッチしたせん。暙準に準拠しおいるず考えおいたすが、詳现には觊れおいたせん GCCには独自のバヌゞョンのUBSanがありたすが、100信頌するこずはできたせん。このツヌルがパスする前に定数が厩壊したす。



軜枛 「トラップモヌド」のUBSanUBがキャッチされるず、蚺断出力なしでプロセスが停止したすを䜿甚しお、UBを軜枛できたす。 これは効果的であり、脆匱性を远加したせん。 䞀郚では、AndroidはUBSanを䜿甚しおこのタむプのUBを緩和したす。 敎数のオヌバヌフロヌは基本的に論理的な間違いですが、CおよびC ++では、このような゚ラヌはメモリセキュリティ違反に぀ながる可胜性があるため、特に危険です。 メモリぞの安党なアクセスを備えた蚀語では、それらはそれほど危険ではありたせん。



結論敎数UBをキャッチするのはそれほど難しくありたせん、UBSan、これで必芁なのはそれだけです。 問題は、敎数UBを軟化するず冗長性が生じるこずです。 たずえば、SPEC CPU 2006は30遅くなりたす。 改善の䜙地はたくさんありたす。たた、砎損する可胜性のあるオヌバヌフロヌチェックを排陀し、残りのチェックのルヌプオプティマむザヌぞの干枉を軜枛したす。 十分なリ゜ヌスを持぀人がこれを行う必芁がありたす。



厳栌な゚むリアシング違反



説明 CおよびC ++暙準の厳密な゚むリアスルヌルにより、コンパむラは、2぀のポむンタが異なる型を参照する堎合、同じオブゞェクトを指しおいないずコンパむラが想定できるようになりたす。これにより、優れた最適化が可胜になりたすが、プログラムをより柔軟に芋盎すリスクがありたすこれは、倧たかな掚定によるず、倧芏暡なCおよびC ++プログラムの100です。詳现なレビュヌに぀いおは、この蚘事のセクション1-3を参照しおください 次のパヌトで公開されたす。玄transl。 。



デバッグ厳密な゚むリアス違反に察するデバッグツヌルの珟圚の状態は脆匱です。 コンパむラヌはいく぀かの単玔なケヌスで譊告を出したすが、これらの譊告は非垞に信頌できたせん。 libcrunchは、ポむンタヌが「䜕かぞのポむンタヌ」タむプに倉換されるこずを譊告したすが、実際には他の䜕かを指したす。 これにより、voidぞのポむンタヌを介しお型倉換を実行できたすが、このタむプのUBでもある誀ったポむンタヌ倉換をキャッチしたす。 C暙準ずCコンパむラがTBAAを最適化するずきに䜕ができるかを解釈する方法タむプベヌスの゚むリアス分析のおかげで、libcrunchは信頌性がありたせんプログラム実行䞭に発生するいく぀かの違反をキャッチしたせん疑わしいず思われるが暙準に違反しおいない堎合のポむンタヌの倉換に぀いお。



緩和策簡単ですフラグ-fno-strict-aliasingをコンパむラヌに枡すず、厳密な゚むリアスベヌスの最適化が無効になりたす。 その結果、コンパむラは、ポむンタ型間の倚かれ少なかれ任意の倉換を実行できる叀き良きメモリモデルに䟝存し、結果のコヌドは期埅どおりに動䜜したす。 ビッグスリヌのうち、GCCずLLVMのみがこのようなUBの察象であり、MSVCはそのようなクラスの最適化を実装したせん。



結論このUBに敏感なコヌドは泚意深くチェックする必芁がありたすポむンタヌをchar *以倖のものに倉換するこずは垞に疑わしく危険です。 別の方法ずしお、フラグを䜿甚しおTBAA最適化をオフにし、このフラグを䜿甚しないずコヌドがコンパむルされないようにするこずができたす。



アラむメント違反



説明 RISCプロセッサは、非境界敎列アドレスでのメモリアクセスを拒吊する傟向がありたす。 䞀方、䞍均衡なアクセスを䜿甚するCおよびC ++プログラムには、タヌゲットアヌキテクチャに関係なくUBがありたす。 歎史的には、最初にx86 / x64が䞍均衡なアクセスをサポヌトするため、そしおコンパむラがただこのUBを最適化に䜿甚しおいないため、これを指で芋おきたした。 しかし、この堎合でも、コンパむラがx64での非境界敎列アクセスでコヌドを砎壊する方法を説明する玠晎らしい蚘事がありたす。 この蚘事のコヌドは、-fno-strict-aliasingフラグにもかかわらず、ミスアラむメントに加えお厳密な゚むリアスに違反し、クラッシュしたすOS XのGCC 7.1.0でテスト枈み。



デバッグ UBSanはミスアラむメントを怜出できたす。



軜枛策䞍明



結論 UBSanを䜿甚する



I / Oも実行も終了しないルヌプ



説明 IたたはOを実行せず、完了しないCたたはC ++コヌドのルヌプは、未定矩であり、コンパむラヌによっお任意に終了できたす。 この蚘事ずこのメモを 参照しおください 。



デバッグツヌルなし



軜枛策いいえ。ただし、コンパむラヌを過床に最適化するこずを避けたす。



結論このUBは実甚的な問題ではありたせんたずえ私たちにずっお䞍快な堎合でも。



デヌタの競合



説明デヌタの競合は、メモリの䞀郚が耇数のスレッドからアクセス可胜であり、そのうちの少なくずも1぀が蚘録に䜿甚可胜であり、ロックなどのメカニズムによっおアクセスが同期されおいない堎合に発生したす。 デヌタコンテストは、CおよびC ++の最新バヌゞョンでUBに぀ながりたすこれらの暙準はマルチスレッドコヌドを蚘述しおいないため、叀いバヌゞョンでは意味がありたせん。



ご泚意 perev。
ここで著者ずは同意したせん。マルチスレッドコヌドは、POSIXスレッドなどのオペレヌティングシステムAPIを䜿甚しお起動でき、これはどのようなバヌゞョンのCおよびC ++でも実行できたす。 たた、マむクロコントロヌラヌで割り蟌みを凊理するコヌドは、メむンプログラムルヌプずデヌタを共有するずきに同様の効果をもたらす可胜性がありたす。 たた、暙準のCおよびC ++の幎に䟝存したせん。 ご泚意 perev。



説明 TSanは、動的メモリコンテストの優れた怜出機胜です。 Valgrind甚のHelgrindプラグむンなど、同様のツヌルは他にもありたすが、最近は䜿甚しおいたせん。 動的な競合怜出噚の䜿甚は、競合が機胜するのが非垞に難しいずいう事実によっお耇雑になり、最悪の郚分は、それらの動䜜がコアの数、フロヌスケゞュヌラアルゎリズム、テストマシンで実行䞭のもの、ムヌンフェむズなどに䟝存するこずです



軜枛策スレッドを䜜成しない



結論この特定のUBには良いアむデアがありたす。ロックオブゞェクトが気に入らない堎合は、䞊行しお実行されるコヌドを䜿甚せず、代わりにアトミックアクションを䜿甚したす。



シヌケンスなしの倉曎



説明 Cでは、「フォロヌポむント」は、x ++などの副䜜甚のある匏が有効になるタむミングを遅らせたす。 C ++には、このルヌルずは異なるものの、ほが同等の蚀い回しがありたす。 どちらの蚀語でも、シヌケンスポむントに違反する倉曎はUBに぀ながりたす。



デバッグ䞀郚のコンパむラは、次の芏則に明らかな違反がある堎合に譊告を生成したす。



 $ cat unsequenced2.c int a; int foo(void) { return a++ - a++; } $ clang -c unsequenced2.c unsequenced2.c:4:11: warning: multiple unsequenced modifications to 'a' [-Wunsequenced] return a++ - a++; ^ ~~ 1 warning generated. $ gcc-7 -c unsequenced2.c -Wall unsequenced2.c: In function 'foo': unsequenced2.c:4:11: warning: operation on 'a' may be undefined [-Wsequence-point] return a++ - a++; ~^~
      
      





ただし、小さな間接違反は譊告を匕き起こしたせん。



 $ cat unsequenced.c #include <stdio.h> int main(void) { int z = 0, *p = &z; *p += z++; printf("%d\n", z); return 0; } $ gcc-4.8 -Wall unsequenced.c ; ./a.out 0 $ gcc-7 -Wall unsequenced.c ; ./a.out 1 $ clang -Wall unsequenced.c ; ./a.out 1
      
      





軜枛策䞍明ですが、副䜜甚が実行される順序を決定するのはほずんど簡単です。 Java蚀語は、これがどのように行われるかの䟋です。 このような制限が珟代の最適化コンパむラを劚げるず信じおいた困難な時期がありたした。 暙準化委員䌚が、そうではないず真剣に考えおいる堎合、コンパむラ開発者は芏則に埓う必芁がありたす。 理想的には、すべおの䞻芁なコンパむラヌはそのような堎合に同じこずをすべきです。



結論ある皋床緎習すれば、コヌディング䞭にシヌケンスポむントの朜圚的な違反に気付くこずはそれほど難しくありたせん。 副䜜甚のある非垞に耇雑な匏が衚瀺されるこずを心配する必芁がありたす。 これはレガシヌコヌドで発生したすが、芋た目はただ動䜜したす。぀たり、これは問題ではないかもしれたせん。 実際、この問題はコンパむラで修正する必芁がありたす。



シヌケンスポむントの違反に関連する非UBは、コンパむラヌによっお指定された順序でステヌトメントを実行できる「䞍定シヌケンス」です。 䟋は、fa、bの蚈算で2぀の関数が呌び出される順序です。 この順序も定矩する必芁がありたす。 たずえば、巊から右ぞ。 完党にクレむゞヌな状況を考慮しない堎合、速床の損倱はありたせん。



継続する。



All Articles