Help us understand the problem. What is going on with this article?

開発時やデバッグの時だけログを出力するさえないやり方

はじめに

これは Delphi Advent Calendar 2019 の 17 日目の記事です。

2019/12/17訂正

コメントで指摘されているとおり、インライン関数として定義することで、デバッグビルドのときだけログ出力が実現できるとのことです。

現存するオンラインドキュメントを眺めたところ、少なくともDelphi 2010以降は、確実にサポートしている模様です(see: プロシージャと関数の呼び出し)

残念ですがDelphi7はインライン関数をサポートしていないので、それ以前のバージョンで頑張っている方は諦めましょう。

ほんへ

デバッグ時だけにログ出力して、リリースでは出したくない場合、たいていは

{$IFDEF DEBUG}
OutputDebugString('Hoge');
{$ENDIF}

な事をすると思う。

けどIFDEFENDIFが仰々しくてなんか嫌。

なら、「関数化すればいいじゃない」ということで、コードとしてはこんな感じか。

procedure OutputDebugOnlyString(M: string);
begin
{$IFDEF DEBUG}
OutputDebugString('Hoge');
{$ENDIF}
end;

// .....

begin
  OutputDebugOnlyString('Uge');
end;

けどこの関数、ログ出力の有無にかかわらず、引数は評価されて渡されてしまう。
引数に渡す関数の実行が重い場合、リリース版なのに無駄に処理を食うのなんか嫌(2回目)

そんなわけで、いい方法はないかなと思案した結果がこちら

program DevTimeOnlyLog;

{$APPTYPE CONSOLE}

{$R *.res}

{$IFDEF DEBUG}
  {$C+}
{$ELSE}
  {$C-}
{$ENDIF}

uses
  System.SysUtils,
  Windows;

function TryOutputDebugString(Msg: string): boolean;
begin
  OutputDebugString(PWideChar(Msg));

  Exit(true);
end;

function HeavyFunc(M: string): string;
begin
  OutputDebugString('Begin sleep 2000 ms');

  Sleep(2000);

  OutputDebugString('Complete sleep 2000 ms');

  Result := M;
end;

begin
  try
    Assert(TryOutputDebugString(HeavyFunc('Some Message')));

    Writeln('Press ANY Key');
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

ポイントは、ログ出力をAssert手続きでくくり、コンパイラ指令($C)でログ出力の有無を切り替えるという残念な方法。
ここでは、説明のためコードで直接コンパイラ指令を指定してますが、通常はプロジェクトオプションで。

リリース版では、ログ出力のコードすら生成されなくなって心の平穏を取り戻しましたとさ。ちゃんちゃん。

おまけ

実装・動作確認、Delphi XE5にて行ったのですが、なーぜーかリリースビルドであるにもかかわらず、Assertの生成がONになってた。
リリースビルドではAssertのコードを生成しないのが一般的だと思ってたので、ちょっと驚いた。

まぁ古いバージョンだし、今は昔で変わってるのかな?

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした