Home> 備忘録: 2006年12月アーカイブ

備忘録: 2006年12月アーカイブ

ログ出力 (2)

  • 2006年12月18日 17:02
  • 備忘録

1 年以上前に書いたこの記事の通りに実装したところ, どうやら main() 終了直前に必ずセグフォが発生する模様 (g++ (GCC) 4.1.1 (Gentoo 4.1.1-r1)). 以下のように書き直すと発生しないことが分かった.


#include <iostream>
#include <fstream>
#include <cstdlib>

// std::ofstream  ofsLog;           // 大域変数として宣言するか ...
// static std::ofstream  ofsLog;    // ここで静的変数として宣言するか ...

int main(void)
{
    static std::ofstream  ofsLog;   // ここで静的変数として宣言するか.

    ofsLog.open("verbose.log");
    if (ofsLog.fail())
    {
        std::cerr << "ERROR: can't open the log file.\n";
        return EXIT_FAILURE;
    }
    std::clog.rdbuf(ofsLog.rdbuf());

    std::clog << "This line is outputted to std::clog." << std::endl;

    ofsLog.close();     // わざわざ書く必要はないか

    return EXIT_SUCCESS;
}

察するに, ofsLogmain() 内部の自動変数とした場合は, std::clog なる (静的) オブジェクトが消滅するよりも先に ofsLog が消滅するため, std::clog のストリームバッファ オブジェクトに対する処理が破綻してセグフォ発生, ということなんだろう. そうだとすれば ofsLogstd::clog よりも長生きする必要があるんだろう, ということで上のようにした次第. (参考 URL)

ここで気になるのは, ofsLog を静的変数とした場合に, これと std::clog とではどちらが先に消滅するのか, またその順番は常に一定と保証されているのか否か, ということ.

  • Comments (Close): 0
  • TrackBack (Close): 0

std::cerr &lt;&lt; std::endl;

  • 2006年12月 7日 16:27
  • 備忘録

std::cerr は標準エラー出力に関連付けられたバッファなしの出力ストリームオブジェクトで, std::endl は改行文字を出力してバッファをフラッシュするマニピュレータ. そんなら, 標記のように std::cerr に対して std::endl を使うのはほとんど意味がなくて, std::cerr << "\n" で十分なはずだよなぁ, むしろタイプ量が少ないんだから後者を使う方が良いよなぁ, と思うんだけど.

C++ 規格書が欲しい.


追記. 以下のコードをコンパイルして実行してみた. (g++ (GCC) 4.1.1 (Gentoo 4.1.1-r1))


#include <iostream>
#include <cstdlib>
#include <unistd.h>

void output_test(std::ostream& os)
{
    os << "before ::sleep(2) -- ";
    ::sleep(2);
    os << " -- after ::sleep(2), w/o std::endl\n";

    os << "before ::sleep(2) -- ";
    ::sleep(2);
    os << " -- after ::sleep(2), w/ std::endl" << std::endl;

    return;
}

int main(void)
{
    std::cout << "::output_test(std::cerr)" << std::endl;
    ::output_test(std::cerr);
    std::cout << std::endl;

    std::cout << "::output_test(std::clog)" << std::endl;
    ::output_test(std::clog);
    std::cout << std::endl;

    std::cout << "::output_test(std::cout)" << std::endl;
    ::output_test(std::cout);
    std::cout << std::endl;

    return EXIT_SUCCESS;
}

std::cout とは違う, という事は分かったが, バッファの有無の違いしかないはずの std::cerrstd::clog とでは挙動の違いはなかった. 上のコードが適切でない事も考えられるけど…うぅむ.

  • Comments (Close): 0
  • TrackBack (Close): 0

Home> 備忘録: 2006年12月アーカイブ

カテゴリ
アーカイブ
購読
Powerd By

Return to page top