-4

I would like to make the C# compiler check more at compile time. For example:

public class Foo
{
    public bool condition;
    public void CheckCondition()
    {
       if(condition) {
         #warning SomeCompilerWarning
       }
    }
}

static void Main()
{
    var foo = new Foo();
    foo.condition = true;
    foo.CheckCondition();
}

This trivial sequence should be able to be detected compile time. I realize #warning is a pre-processor directive. I would like the above to somehow generate a warning. Are there any ways to slightly extend the compile time checks for trivial sequences or are custom extensions the only way?


Clarifications:

  1. I'm asking for an alternative to the above that does not use the pre-processor. The above is an example in concept what I would like to achieve.
  2. I want the compiler to emit a warning similar to the example. The example doesn't work. It is just used as an illustration.
  3. Rephrase: Are there any alternative to writing a custom analyzer to achieve the behavior in the example, without using any preprocessor directive? The #warning is just an illustration as to what I would like to happen.
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
gwow12345
  • 311
  • 3
  • 12
  • 1
    That is not a trivial sequence, this is an instance field, and it is not constant. In order for this to be evaluated, it would need to be compiled, and executed. Try using the `#if` directive and wrap your warning inside – Ehssan Aug 15 '21 at 10:30
  • Are you saying the above can not be checked ahead of runtime? That's just not true. – gwow12345 Aug 15 '21 at 10:34
  • No. As I stated above: I'm asking for an analogue to the above. – gwow12345 Aug 15 '21 at 10:37
  • If `condition` is not a `constant`, is your expected outcome for the compiler to make an *assumption* about the state of `condition`? – DekuDesu Aug 15 '21 at 10:42
  • Again, I'm asking for an alternative to the above that does not use the pre-processor. The above is an example in concept what I would like to achieve. Obviously if I already knew the answer I would not ask a question. – gwow12345 Aug 15 '21 at 10:43
  • I am not saying it's impossible to evaluate that before compilation, but it just doesn't make sense to have such a functionality for public, mutable fields that are not guaranteed to not be accessed from outside of the local scope (as you can't predict the real value it will hold at runtime); also it does not make sense for values that require code execution. So assuming you have a local value that is assigned with constant values only, what would be the benefits of what you are asking for? You can do all that with the existing preprocessor directives – Ehssan Aug 15 '21 at 10:43
  • @DekuDesu The example above can be statically analyzed. The state is well-defined at compile time. I want the compiler to emit a warning similar to the example. The example doesn't work. It is just used as an illustration. – gwow12345 Aug 15 '21 at 10:44
  • Are you asking for a facility to write compiled code to generate compiler warnings before compiling? – Mat J Aug 15 '21 at 10:50
  • @gwow12345 What kinds of values do you want to evaluate? Are they constant, or dynamic (if so, depending on what external factors)? – Ehssan Aug 15 '21 at 10:51
  • @MatJ Ahead of runtime is the main criteria. Before or during compilation are both fine. – gwow12345 Aug 15 '21 at 10:51
  • @OlivierRogier Never mind, I think I misread your answer. Thought there was another comment of you – Ehssan Aug 15 '21 at 10:54
  • @Ehssan All values will be known before compilation. Each conditional path will be known ahead of compilation, as in the example above. It may be more complex, but there are no external factors in runtime that can affect path. – gwow12345 Aug 15 '21 at 10:55
  • @MatJ Ok. Let's change it to ahead of runtime. – gwow12345 Aug 15 '21 at 10:57
  • 1
    Does this answer your question? [What static analysis tools are available for C#?](https://stackoverflow.com/questions/38635/) and [Writing solution analyzers for Visual Studio](https://stackoverflow.com/questions/43442866/) and [Tutorial: Write your first analyzer and code fix](https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/tutorials/how-to-write-csharp-analyzer-code-fix) and [How to write a Roslyn Analyzer](https://devblogs.microsoft.com/dotnet/how-to-write-a-roslyn-analyzer/) and https://stackoverflow.com/questions/tagged/roslyn-code-analysis –  Aug 15 '21 at 10:58
  • In that case, use preprocessor directives. What is turning you away from using them? Do you need to access constant values defined in code? As mentioned by @OlivierRogier, you could use Roslyn analyzers, to output your warnings. There you can execute your custom code and do a static code analysis – Ehssan Aug 15 '21 at 10:58
  • @OlivierRogier No. My question, again, is asking for alternatives or if writing a custom extension is the only way, not for a tutorial. – gwow12345 Aug 15 '21 at 11:01
  • @Ehssan > Do you need to access constant values defined in code? Yes. I'm asking if any alternatives to writing custom analyzers are available. – gwow12345 Aug 15 '21 at 11:01
  • 1
    @gwow12345 Therefore if you disagree that you misunderstood what preprocessor is, and if you say that writing rules for a code analyzer is not what you are asking, then your question is not clear and you run out of chars for nothing responding that we don't get it until you clarify your intention ... and I think anyway there is no solution at all even though I didn't understand what you are asking ... because you can't generate a compiler warning from code at runtime and only from a code analyzer because you can't modify the compiler unless you're working at Microsoft or any implementer ... –  Aug 15 '21 at 11:03
  • To be clear, are you asking if there is a way for c#'s compiler to run the code it is compiling? – Mat J Aug 15 '21 at 11:14
  • @MatJ No, I'm asking for alternatives to achieving the above ahead of runtime. I'm not fishing for any specific solution, at any stage, so long as it ahead of runtime. What you are asking is clearly not possible. – gwow12345 Aug 15 '21 at 11:19
  • 1
    [How do I ask a good question](https://stackoverflow.com/help/how-to-ask) • [What topics can I ask about here?](https://stackoverflow.com/help/on-topic) • [What types of questions should I avoid asking?](https://stackoverflow.com/help/dont-ask) • [Writing the perfect question](https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question) –  Aug 15 '21 at 11:28
  • I copied your code in the Visual Studio 2019, and **it does generate a warning**. So it is unclear to me why you say that *the example doesn't work*. A warning is generated also if I paste your code in the .NET Fiddle online compiler: [link](https://dotnetfiddle.net/FJFiEs). – Theodor Zoulias Aug 15 '21 at 13:22
  • For this sort of thing, NDepend is very flexible. – GaTechThomas Aug 17 '21 at 13:30

2 Answers2

3

No, and I doubt it would be desirable even if it was technically possible. The number of cases when it would be feasible and correct is miniscule; the number of cases when it would give false warnings, or fail to give a warning when it should, would dwarf any such utility, and as such: it would be more harmful than useful. In the general case: object state is not very predictable even between successive lines of the same method, since in general there are unrelated side-effects, concurrency, reflection, unsafe access, and a wide range of other things to contend with - including the "halting problem".

This situation can only be usefully and reliably detected at runtime, so: do that.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
-4

There is no alternative to writing a custom analyzer.

gwow12345
  • 311
  • 3
  • 12
  • 2
    [How do I write a good answer](https://stackoverflow.com/help/how-to-answer) • [How do I write a good answer to a question](https://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question) • [Answering technical questions helpfully](https://codeblog.jonskeet.uk/2009/02/17/answering-technical-questions-helpfully) –  Aug 15 '21 at 11:28