web-dev-qa-db-ja.com

localtime vs localtime_sおよび適切な入力引数

time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );

警告C4996: 'localtime':この関数または変数は安全でない可能性があります。代わりにlocaltime_sの使用を検討してください。

time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime_s ( &rawtime );

Localtimeをlocaltime_sに変更すると、次のエラーが表示されます:エラーC2660: 'localtime_s':関数は1つの引数を取りません

コードの最初のブロックで起こっていることは次のとおりです。

  • 空のtime_t変数を作成します。
  • ctimeで定義されているtimeinfoへのポインターを作成します
  • rawtimeをrawtime参照に書き込みます
  • rawtimeを歩行者にとって意味のあるものに変換します

    1. 私は正しいですか?
    2. Localtime_sに必要な2番目の入力パラメーターは何ですか?
    3. 現地時間の安全性の問題をすべて無視した場合に起こる可能性がある最悪の事態は何ですか。
48
ProGirlXOXO

localtimeは、静的に割り当てられたstruct tmへのポインターを返します。

Localtime_sでは、構造体tmへのポインターを渡すと、localtime_sが結果データをそこに書き込むため、コードは次のように変更されます。

struct tm *timeinfo;
timeinfo = localtime(&rawtime);

次のようなものに:

struct tm timeinfo;
localtime_s(&timeinfo, &rawtime);

この方法では、独自のバッファーを持つのではなく、your bufferに書き込みます。

57
Jerry Coffin

localtime_sは、localtime関数のMicrosoftによる実装にすぎません。C++ ISOに準拠しており、Microsoftが「非推奨」とマークしたため、locatimeを安全に使用できます。 localtime関数自体は、C++の世界では非推奨ではありません。

localtime_s参照 は、これらのパラメーターを渡す必要があることを示します。

_tm 
Pointer to the time structure to be filled in.
 time 
Pointer to the stored time.
7
user1182183

軌道上の明るさのレース 指摘したように、localtimeはスレッドセーフではなく、他のいくつかの時間関数でもありません。私はこの主題についてもっと知りたいと思ったのですが、 関連するブログ記事 を見つけました。

以下の引用は、localtimeがスレッドセーフではない理由を説明しています。

[...] localtimeは、静的バッファ(std :: tm *)へのポインタを返します。別のスレッドが関数を呼び出すことができ、静的バッファーは、最初のスレッドがstruct std :: tm *のコンテンツの読み取りを完了する前に上書きされる可能性があります。

6
ForceMagic