I was recently going through some code and considering whether I need to be careful with the expressions placed inside Debug.Assert
statements, such as expensive operations or those with side effects. However, it appears the compiler is pretty smart about completely removing the Assert
statement and inner expressions.
For example, the following will only print on debug builds:
static void Main(string[] args) { Debug.Assert(SideEffect()); } private static bool SideEffect() { Console.WriteLine("Side effect!"); return true; }
And this will complain that o
is being used before initialization on release builds:
static void Main(string[] args) { object o; Debug.Assert(Initialize(out o)); o.ToString(); } private static bool Initialize(out object o) { o = new object(); return true; }
It even seems to stand up to expressions such as this (printing "After" in both cases):
static void Main(string[] args) { if (false) Debug.Assert(true); Console.WriteLine("After"); }
I was a little suprised with how smart the compiler is here and its ability to correctly detect cases when the Debug.Assert
is removed. So, it got me curious..
if
statement correctly.System.Diagnostics.Debug
class special here, or is it possible to build your own methods with similar handling?In C programming language, %d and %i are format specifiers as where %d specifies the type of variable as decimal and %i specifies the type as integer. In usage terms, there is no difference in printf() function output while printing a number using %d or %i but using scanf the difference occurs.
c is called the source file which keeps the code of the program. Now, when we compile the file, the C compiler looks for errors. If the C compiler reports no error, then it stores the file as a . obj file of the same name, called the object file.
The result of a logical OR ( || operator in C) is true if EITHER of its inputs is true. Similarly logical AND ( && operator in C) is true if BOTH of its inputs are true. (Note that 0 is FALSE and anything else is TRUE, 1 is conventionally used in truth tables like the above).
-= Subtract AND assignment operator. It subtracts the right operand from the left operand and assigns the result to the left operand. C -= A is equivalent to C = C - A.
Debug.Assert
is declared with ConditionalAttribute
; as the documentation states, this "[i]ndicates to compilers that a method call or attribute should be ignored unless a specified conditional compilation symbol is defined."
The C# compiler has specific support for that attribute and removes the Debug.Assert during release builds, so it is never part of the built expression tree.
If you right-click on one of your Debug.Assert
statements, you should be able to go to the definition. Visual Studio will show you "code" generated from the metadata, and there you can see the [Conditional("DEBUG")]
attribute applied. So this code is only respected when DEBUG
is #define
'd as part of your build.
The methods on the debugger use the pseudo-custom attribute, ConditionalAttribute
, which the compiler detects and removes any calls to any methods with that attribute unless the specified compilation symbol (in this case, DEBUG
) is defined. Anyone may use the attribute on void
methods without any out
parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With