2016-04-05 9 views
1

単純なsocketクライアントプログラムをLinuxからWindows(VS2012)に移行しています。このプログラムでは、通常のclose,read、およびwriteの機能が使用されます。クローズvsクローズ、読み取りvs _読み取り、書き込みvs _write - 違いは何ですか?

次の警告を取得VS2012、 - 私にコンパイル:

warning C4996: 'close': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _close 

warning C4996: 'write': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _write 

warning C4996: 'read': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _read 

ソリューションは簡単です - ちょうどunderscodeを追加する - しかし...

What's間の実質的な違いをcloseおよび_close,readおよび_read,writeおよび_write

アンダースコアのバージョンに変更するだけで、同じ動作が維持されますか?

+0

WindowsとPOSIXは実際にはサポートされていないので、POSIX名とアンダースコアのあるPOSIX名とPOSIX名は廃止されています。 – immibis

答えて

2

機能のPOSIX名は、真のPOSIXシステムでのみ動作することが保証されています。 VisualC++では、コードの移植を支援するためにPOSIX名が実装されていますが、ISO標準ではアンダースコアの接頭辞を使用しています。

POSIXは "UnixプラットフォームAPI"と考えることができます - 厳密に言えば、それはCとC++の標準ライブラリ(表面的にはプラットフォーム中立[1])とは別に、POSIXのような名前closewrite、およびreadは完全に有効ですが、プラットフォーム上のみです。

ISO版はアンダープレフィックスを使用していますので、C++標準状態(What are the rules about using an underscore in a C++ identifier?):

アンダースコアがグローバル名前空間内の名前として使用するための実装に予約されてから始まるそれぞれの名前

ユーザーアプリケーションコードはおそらくclosewrite(それほど具体的ではないため)を使用したいと考えられますが、同じ名前を使用してライブラリをインポートする場合は、自分で使用することはできません。あなたは名前を取得するでしょうcollアイシオンエラー。

残念ながら、アンダースコアのプレフィックスに関する規則は、POSIXやWin32などのさまざまなAPIやライブラリが既によく定着しているかぎり、初めて導入されました。今はVarious() forms_of_writing = _andNaming(IDENTIFIERS)の醜い組み合わせが残っています。

[1]ケースインポイント:最近まで(つまり過去数年間)、CやC++でファイルやディレクトリを列挙する標準的な方法がなかったため、プラットフォーム固有のAPIを常に使用する必要がありました。 Cは元のMacintoshのような階層ファイルシステムをサポートしていないコンピュータよりも前にあります。

2

次の警告に

うわーを取得VS2012、 - 私にコンパイルする場合、それらは陽気に誤解を招くようなメッセージです。いい仕事、マイクロソフト

彼らは、どういうわけかISO C++の機能であることを示唆していると思われます。_close_readおよび_write
彼らはそうではありません!

close_closeread_readwrite_write間の本当の違いは何ですか?

は、Microsoftが明らかにPOSIXはclosereadwrite機能再実装しました。違いは、再実装時に、ISO C++標準ではインプリメンテーション(つまり、Visual Studio)が内部/組み込み関数に使用する必要があることを示すため、これらの関数の先頭にアンダースコアを付けて名前を変更したということです。

ちょうどアンダースコアのバージョンに変更すると、同じ動作が維持されますか?

ここではさまざまな潜在的な違いを列挙しません。もちろん、それらの機能がどのように機能し、どのように機能するかについての完全な情報については、そのドキュメントを読んでください。しかし、直接的な答えは、ではなく、同様の名前のPOSIX関数の動作と同じであると仮定するとではありません。

2

エラーメッセージは、実際の真実ではなく、政治的なステートメントです。 _close以来

が "ISO C++準拠" であると主張され、ほのめかしはPOSIX close命名はない ISO C++準拠であるということです。

これは完全なごみです。

下線付きの名前は、何十年もの間、MicrosoftがPOSIXサブセットの模倣をライブラリに実装した方法です。 (forkの欠如を補う、_spawn*ファミリーの機能のような拡張機能を持つ)。

名前は、予約された名前空間に限定されているという意味で、ISO CおよびC++に準拠しています。 の場合、プログラマは_closeのような識別子を外部名として使用し、その動作は未定義です。しかし、それは、言語実装者が公開APIにそのような識別子を使用することをお勧めします。内部の(おそらく文書化されていない)識別子には便利です。マイクロソフトは残念なことにいくつかのAPIを一度に醜い名前で作成し、後でそれを遡及的に正当化するためのコンパイラエラーメッセージを作成しました。

しかし、Windows APIは、CreateWindowWaitForSingleObjectのように、_[a-zA-Z0-9_]*名前空間に限定されない識別子でいっぱいです。

closeが "ISO C++に準拠していない"場合、これらはどちらもありません!

実際、ISO CおよびC++では、実装者がcloseまたはWaitForSingleObjectなどの名前空間を持つ追加のライブラリ関数を持つことができます。 _closeのような名前は、将来のISO CまたはC++標準では使用されないという意味でのみ適合しています。しかし、これはPOSIXやWindowsのような主要なAPIの識別子にも当てはまります。

あなたがシステムAPIの世界でマイナープレーヤーで、ISO Cと今でも衝突しなくても、短い名前(つまり英語辞書の単語)を指定すると、将来の標準では、そのブルドーザーをその上で実行することができます。これがPOSIX関数に起こる危険はありません。

関連する問題