fopen_sってなんだよ(C言語)

☆お知らせ☆
この記事が人気すぎるので真面目にfopen_sについて新しい記事を書いたのでご覧ください。
https://khws4v1.myhome.cx/article/2017/04/13/%e3%81%aa%e3%82%93%e3%81%8b%e4%ba%ba%e6%b0%97%e3%81%aefopen_s%e9%96%a2%e6%95%b0%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/

ファイル操作?簡単っていうwwwwwwww
こんなのできて当たり前っていうwwwwwwww

って何?fopenじゃなくてfopen_sを使え?
fopen_sって何?初めて聞くんだけど・・・。

違い

fopenfopen_sとの違い、なんかセキュリティが強化されているとか説明を受けましたがなんのこっちゃさっぱりなので自力で調べることに。

fopenはほとんどの環境で使えますが、fopen_sはC11以降で標準ライブラリに導入された関数です。

これらの関数は戻り値と引数が異なります。

http://en.cppreference.com/w/c/io/fopen

戻り値がfopenFILE *fopen_serrno_tになっています。
fopen_sは戻り値がerrno_tなので、いちいちerrnoからエラーの原因を調べなくても良くなっています。

また、fopen_sでファイルを開くと他のアプリケーションから開けなくなります。

なぜfopen_sなのか

大学の授業ではC89基準のコードしか教えていなかったのに突然教科書に無いC11で導入されたfopen_sをセキュリティを理由に出してきました。
でもセキュリティをそんなに気にするならscanfとかのバッファオーバランという遥かに深刻な問題をほったらかしにするはずないです。
それに同類のfprintf_sfscanf_sなどは出ていません。

MSVC 2012はC99には対応しておらず、それなのにC11で導入された関数を使わせるなぜなのか?
その前にC89・C99の時点では非標準の関数を標準の関数として使わせるのはなぜなのか?
ちなみにgccとclangでは最新バージョンでもfopen_sは使えません。

そしてその謎を解明するべくおもむろにMSVC 2013で適当なコードをコンパイルしてみることに。

結果は・・・

 

fopen_s使えと言われてコンパイルできませんでした。
C89・C99では非標準の関数をわざわざ使わせたのはセキュリティではなくコンパイルエラーを回避するためだったわけですね。

個人的にはこの仕様とこの対処法は嫌いですけど・・・。

fopen_sってなんだよ(C言語)” への1件のフィードバック

  1. Visual Studio 2005で、_s 関数は導入されました。当時は_sでない関数を使った場合は警告でした。これはセキュリティのためで、当時はマイクロソフト社の独自拡張の関数でした。ところが時代も進み、世間的にもセキュリティ問題が関心ごとになり、C/C++の標準として取り入れるべく、TR 24731-1 として標準化委員会で審議され、C11で標準化(規格書のAnnex K. Bounds-checking interfaces)に至りました。おそらく、それを受けてマイクロソフト社もVisual Studioの設定を変えて、_sでない関数を使用するとデフォルトではエラーになるようになったのです。

コメントを残す