標準に準拠する必要がありますか?


17

Stack Overflowには、C標準について常に語る経験豊富な人々がいます。たとえ私のために働いていても、人々は非ポータブルなソリューションを好まないようです。わかりました、標準に従う必要があることを理解していますが、プログラマーの創造性に束縛をかけませんか?

標準に従うことから得られる具体的な利点は何ですか?特に、コンパイラは標準をわずかに異なる方法で実装する場合があるためです。


7
「標準」とはどういう意味ですか?標準で定義されていない動作に気付いていないということですか?または、拡張機能/コンパイラ機能を使用していませんか?またはスタイルの規則?
ikh

1
@ikh彼はISO C標準(C90、C99、C11)を取り上げています。
アシームバンサル

9
それは、英語の文法と語彙を使用して、英語で書いたり話したりすると、創造性に束縛がかかると言うのと同じです。確かに、人々は一貫性を犠牲にしてルールを破ることで素晴らしいことをすることができますが、英語の「標準」を守りながら何百万もの創造的な本を書くことができます。
アヴナーシャハルカシュタン

「人々は私のために働いても、非ポータブルソリューションは好きではないようだ」という例を追加できますか
BЈовић

1
@PHIfounderその最後のケースに対処するために、メインからのリターンを省略できます。暗黙的に0を返します:)
ダニエル・グラッツァー

回答:


45

標準に準拠することが良いことである理由はいくつかあります。

  1. コンパイラーにロックされているのは大変なことです。あなたは完全に彼ら自身のアジェンダを持つ開発者のグループに翻弄されています。彼らは明らかにあなたや何かを手に入れようとはしていませんが、コンパイラが最適化、新機能、セキュリティ修正などに遅れを取り始めた場合、あまりにも悪いです。あなたが立ち往生しています。極端な場合、一部の企業は、依存しているツールにパッチを適用する必要があります。他の作業ツールが存在する場合、これは莫大なお金と時間の無駄です。

  2. プラットフォームにロックされていると、さらに難しくなります。Linuxでソフトウェアをプッシュしていて、市場が本当にあることに気付いてWindowsに切り替えたい場合は、コード内にあるすべての非ポータブルハックを変更して、うまくプレイできるようになります。 GCCとMSVCの両方で。そのようなものに基づいたコアデザインのいくつかの部分がある場合は、幸運を祈ります!

  3. 後方互換性のない変更が最も困難です。標準はコードを壊しません(Pythonを無視します)。ただし、一部のランダムなコンパイラ作成者は、実際にこの実装固有のアドオンはトラブルに見合う価値がないと判断し、削除する可能性があります。たまたまそれを頼りにしているのなら、あなたはそれが最後に残っていた古い古いバージョンに固執しています。

したがって、ここで最も重要なメッセージは、標準に準拠することで、より柔軟になります。あなたはより限られた言語を確かに持っていますが、あなたはもっと持っています

  • 図書館
  • サポート(すべての複雑なコンパイラ固有のハックではなく、人々は標準を知っています)
  • 利用可能なプラットフォーム
  • 成熟したツール
  • セキュリティ(将来の証明)

それは微妙なバランスですが、標準を完全に無視することは間違いです。移植性のない方法で実装される可能性のある抽象化に依存するようにCコードを整理する傾向がありますが、抽象化に依存するすべてを変更せずに透過的に移植できます。


+1公平:)、ありがとう...コンパイラが標準からわずかに逸脱した方法を真剣に混乱させ、厳密にそれに従うことに懐疑的であり、賛否両論を知る必要があり、それらを明確に特定しました。
-0decimal0

6
未定義の動作もおそらくかなりひどいものです。cを使用すると、標準に厳密に従っていない場合、UBに簡単にアクセスできます。
CodesInChaos

@CodesInChaos合意、未定義の動作が、それはいくつかのクレイジーな最適化が可能になりますので、一方では素晴らしいですが、他にそれをデバッグ...
ダニエルGratzer

6

標準は、プログラムの意味を定義する、ユーザーとコンパイラ間の一種の「契約」です。プログラマーとして、私たちはしばしば言語がどのように機能するかの特定のメンタルモデルを持ち、このメンタルモデルはしばしば標準と対立しています。(たとえば、Cプログラマーは、ポインターを大まかに「メモリアドレスを示す整数」と考えるため、メモリーを示す整数で実行する可能性のあるポインターで算術/変換/操作を実行しても安全であると想定します。アドレス。この仮定は標準と一致していません。実際には、ポインタでできることに対して非常に厳しい制限を課しています。

それで、あなた自身のメンタルモデルではなく、標準に従うことの利点は何ですか?

簡単に言えば、それは標準が正しいことであり、あなた自身のメンタルモデルが間違っているということです。通常、メンタルモデルは、すべてのコンパイラの最適化が無効になっている、一般的なケースで、システムでの動作の単純化されたビューです。コンパイラベンダーは通常、特に最適化に関しては、準拠する努力をしません。(契約の終了を延期しない場合、ガベージイン、ガベージアウトなど、コンパイラに特定の動作を期待することはできません。)

たとえ私のために働いていても、人々は非ポータブルなソリューションを好まないようです。

「たとえ彼ら私のため働いているように見えても」と言う方が良いかもしれません。コンパイラーが特定の動作が機能することを明確に文書化しない限り(つまり、適切な標準とコンパイラー文書で構成される充実した標準を使用している場合を除き)、それが本当に機能するか、本当に信頼できるかはわかりません。たとえば、符号付き整数のオーバーフローは通常、多くのシステムでラッピングされます(したがって、INT_MAX+1通常はINT_MIN)。ただし、コンパイラは符号付き整数演算が(正しい)Cプログラムでオーバーフローしないことを「知って」おり、知識"。


1
-fwrapvを使用してコンパイルでき、その後、符号付き整数演算が常にラップする、わずかに異なる非標準言語を使用しています。
user253751 14

@immibis:C89が書かれたとき、その理論的文書によると、現代のコンパイラの大半は整数オーバーフローのサイレントラッピングセマンティクスを定義していました。多くの場合、整数オーバーフローの場合に何が起こるかについて何らかの保証を設けることで、特に保証が正確なラッピング動作を強制しない限り、そのような保証なしで可能な場合よりもコードを効率的にすることができます。ラップ動作は符号なしの数学を使用してエミュレートできますが、より緩やかですが要件を満たすのに十分なセマンティクスにより、より効率的なコードが可能になる場合があります。
-supercat

@immibis:修正主義者が、特定のプラットフォーム(または場合によっては100%全員)のコンパイラ間でほぼ満場一致で実装された動作が、そのようなプラットフォームでは決して「標準」ではないことを人々に納得させることができませんでした。そのような動作を回避しなければならないことから生じる効率の損失は、コンパイラがそれらを取り消すことによって達成できた「最適化」によって回復されません。
-supercat

4

標準に従う必要があることは理解していますが、プログラマーの創造性に束縛をかけませんか?異なるコンパイラが標準に従う方法にはまだいくつかの違いがあります。たとえば、非常に優れたパフォーマンスと速度で機能するコードを書くことができます。それは重要なことですが、それでも必ずしも標準に厳密に従うとは限りません。

いいえ。標準は何が許可されているかを示しています。指定されていない場合、未定義の行動領域にあり、すべての賭けはオフです-プログラムは何でも自由に行えます。


void main()vsの特定の例を挙げたのでint main()、答えを改善できます。

void main()メイン関数の標準宣言ではありません。拡張機能を介して一部のコンパイラで動作する場合がありますが、実装に依存しています。それが機能する場合でも、あなたが望むことをするかどうかを確認する必要があります。問題は、コンパイラ開発者がvoid main()次のコンパイラリリースで削除することを決定し、アプリケーションが破損する可能性があることです。

一方、標準ではmainの署名が明確に定義されてint main()おり、何をすべきかが示されています。


一方、標準では定義されていないものがあります。次に、別の標準が適用される場合があります(POSIXなど)。c ++ 03標準プログラムは1スレッドであるため、最良の例はc ++ 03でのスレッド実装です。その場合、プラットフォーム依存ライブラリ、またはboostのようなものを使用する必要があります。


4
コンパイラが標準ではないことはすべて、未定義の動作ではありません。コンパイラの拡張機能は、確定的で意図的であるという意味で明確に定義されています。UBは違います。
ダニエル・グラッツァー

@jozefg質問された方法-OPがUBの実装方法を考えたことは明らかです。たとえば、スレッドはc ++ 03で定義されていません。
BЈовић

1
@deworde:コメントは回答から削除されました。
ケビン-モニカ

@jozefg特定のコンパイラが常に符号付き整数をラップする場合、ドキュメント化されていない言語拡張機能と見なされる可能性があります。(もちろん、文書化されていないということは、拡張機能を削除しないという保証がないことを意味します)
user253751

-6

プロジェクトが政府プロジェクトや軍隊プロジェクトなどの特別なプロジェクトに関するものである場合はルールを守らないでください。ただし、オープンソースや分散チームとの大規模なプロジェクトについて話す場合はルールに従う必要があります。


2
説明がないと、他の誰かが反対意見を投稿した場合に、この答えが役に立たなくなる可能性があります。たとえば、誰かが「プロジェクトが政府プロジェクトや軍隊プロジェクトなどの特別なプロジェクトに関するものであればルールに従うが、オープンソースについて話している場合はルールに従う必要はない...」などの主張を投稿した場合、この答えは読者が2つの反対意見を選ぶのにどのように役立ちますか?それをより良い形に編集することを検討してください
-gnat

2
Unknownは:あなたはGOVプロジェクトでありますどのように多くの規格を学ぶために驚かれると思います...
ディア・ハンター
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.