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

2015年7月16日 1 投稿者: khws4v1

☆お知らせ☆
この記事が人気すぎるので真面目に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では非標準の関数をわざわざ使わせたのはセキュリティではなくコンパイルエラーを回避するためだったわけですね。

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