2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ConditionalAttributeのメソッドの引数に副作用のある式を書くとどうなるか

Posted at

概要

最近C#に入門していて、ConditionalAttributeなるものの存在を知りました。
例えば、[Conditional("AAA")]という属性をメソッドに与えている場合において、シンボルのAAAが定義されていなければ、そのメソッドを呼び出している箇所がコンパイルされなくなるというものです(メソッド自体はコンパイルされます)。

Program.cs
using System;
using System.Diagnostics;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            // シンボルAAAが定義されていないため、下のHello()の呼び出しはコンパイルされない
            Hello();
            Console.WriteLine("Main()");
        }

        [Conditional("AAA")]
        static void Hello()
        {
            Console.WriteLine("Hello()");
        }
    }
}

実行結果

Main()

シンボルのAAAが定義されていないため、Hello()メソッドが呼び出されてないことが確認できます。

そこで、1つ疑問が浮かびました。
ConditionalAttributeのメソッドの引数に副作用のある式を書いたらどうなるのでしょうか。これは、C/C++のassert()において、意図せず副作用のある式を書いてしまい、挙動がDebugとReleaseのときで異なりバグが発生することがよくある?ことであり気になったからです。

例えば、C++でassert()に副作用のある式を書いてしまったソースコードは下記です。

main.cpp
#include <iostream>
#include <cassert>

using namespace std;

int main()
{
    int a = 10;

    assert(++a);

    cout << a << endl;

    return 0;
}

NDEBUGを定義するかしないかで、aの値が変化してしまいます。

$ clang++ main.cpp && ./a.out
11
$ clang++ -DNDEBUG main.cpp && ./a.out
10

検証

検証用のソースコードは下記です。

Program.cs
using System;
using System.Diagnostics;

namespace ConsoleApplication
{
    class Program
    {
        static int a = 10;

        static void Main(string[] args)
        {
            Hello(++a);

            Console.WriteLine("Main():{0}", a);
        }

        [Conditional("AAA")]
        static void Hello(int x)
        {
            Console.WriteLine("Hello():{0}", x);
        }
    }
}

実行結果

Main():10

というわけで、Hello(++a);がコンパイルされなくなっているので、++aは実行されず、aが11になることはありませんでした。
結論としては、ConditionalAttributeのメソッドの引数に副作用のある式を書くのは、あまり良いことでは無いかもしれません。

参考文献

ConditionalAttribute Class (System.Diagnostics) | Microsoft Docs

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?