Does Debug.Assert generate IL in release mode? - c#

When Debug.Assert() method calls exist in source code and I compile in release mode, does the compiler generate the IL for the Debug.Assert() even though it's not called?
One of our developers added an Assert recently that displays information about our internal security. Could someone look at the release mode IL and figure out the text for the assert?

No, the members of the Debug class (with the ConditionalAttribute attribute) do not emit IL. There is no explicit mention on MSDN, however the following two quotes imply the behaviour quite well, so to augment Roy's answer:
If you use methods in the Debug class to print debugging information
and check your logic with assertions, you can make your code more
robust without affecting the performance and code size of your
shipping product.
So, no size difference implies no output from these whatsoever, and
The ConditionalAttribute attribute is applied to the methods of Debug.
Compilers that support ConditionalAttribute ignore calls to these
methods unless "DEBUG" is defined as a conditional compilation symbol.
Refer to a compiler's documentation to determine whether
ConditionalAttribute is supported and the syntax for defining a
conditional compilation symbol.
Which means that, at the compiler level, these calls won't even be considered (when DEBUG is not defined.)

It does not by default, unless you define the DEBUG symbol (and by default, for Release that is turned off).
To verify, open your Project Properties and select the Build pane in Visual Studio. It will show the checkbox "Define DEBUG constant". If it is turned on for Release, then asserts will fire; otherwise, they won't.

Related

Assertions C# + When to use them

I have seen couple of posts regarding usage of Debug.Assert in C#.
But I still have one doubt, may be its repeated, but I need to ask.
Is there a strict rule that Debug.Assert should be used only for checking members of a class or used to check parameters to a public method?
Or Can i Use Debug.Assert where ever I want, and to check whichever condition?
Thanks
sandeep
Is there a strict rule that Debug.Assert should be used only for checking members of a class or used to check parameters to a public method?
Do not use Debug.Assert() to check parameters to a public method. Parameters should be checked in both debug and release builds.
You should use an explicit if followed by thowing ArgumentNullException, ArgumentOutOfRangeException or ArgumentException for invalid parameters.
Alternatively, use Code Contracts to express the parameter preconditions using Contract.Requires().
For further reference, see this thread: When should I use Debug.Assert()?
Other than that, then you can use Debug.Assert() wherever you want, but be aware that it might take a little more setting up for Asp.Net: Is it worth using Debug.Assert in ASP.NET?
Also see here: http://gregbeech.com/blog/how-to-integrate-debug-assert-with-your-asp-net-web-application
You can use it wherever you want. Just be aware that it's a debug check. So it's checked only at development time while you test it. If you need your program to actually change behaviour based on a condition, you still need additional ifs.
Read the coding guidelines over at Microsoft and try to use tools like the static code analysis or Visual Studio (formerly FxCop) and StyleCop to have an automated way of checking your code quality and common mistakes.

How to get an attribute to act as [Conditional("DEBUG")]?

I have a C# program where some parts of code are generated using D-style mixins (i.e., the body of the method is compiled, executed, and results inserted into a class). The method is marked with [MixinAttribute] and, naturally, I don't want it to be compiled into the program. Is there some cheap way of preventing the method decorated with this attribute from being included in a build?
The only way is with compiler conditionals:
#if DEBUG
[MixinAttribute]
// method you don't want included
#endif
The problem with this approach is that you then create a member which will be unavailable in builds where DEBUG is not defined. You then have to mark all usages with the conditional, and I don't think this is what you want. It's not quite clear but I think what you are really asking is how you create dynamic call sites at build time, or, rather, at JIT time (which is what the ConditionalAttribute controls). If this is the case, you can't really do this easily in C# without using some kind of dynamic dispatch overriding (using some proxying library) or by using some post-processing tool like PostSharp to manipulate the compiler output.

Debug vs Trace in C#

As I understand statements like Debug.WriteLine() will not stay in the code in the Release build. On the other hand Trace.WriteLine() will stay in the code in the Release build.
What is controling this behaviour? Does the C# compiler ignores everything from the System.Diagnostics.Debug class when the DEBUG is defined?
I am just trying to understand the internals of C# and just curious.
These methods use the ConditionalAttribute to designate when they should be included.
When DEBUG is specified as a #define, via the command line or the system environment (set DEBUG = 1 in the shell), a method marked with [Conditional("DEBUG")] will be included by the compiler. When DEBUG is not included, those methods and any calls to them will be omitted. You can use this mechanism yourself to include methods under certain circumstances and it is also used to control the Trace calls like Trace.WriteLine (this uses the TRACE define).
This is due to ConditionalAttribute; the compiler ignores calls to methods marked as conditional unless that symbol is defined.
You can have your own:
[Conditional("BLUE")]
void Bar() {...}
which will only be called when BLUE is defined.
Note that there are some restrictions, to make "definite assignment" work:
no return value
no out parameters
(the same restrictions apply to partial methods for similar reasons)

Do debugging attributes such as [DebuggerDisplay] still get compiled into Release binaries?

Having recently learned of the DebuggerDisplay attribute, I've found it quite useful. However, one thing that surprises me is that it doesn't have a [ConditionalAttribute("DEBUG")] attribute attached to it. Is there some way to force this or is it a bad idea to try? Or does it not matter for some other reason?
The [ConditionalAttribute("DEBUG")] is only used for optimising out method calls.
If you really want to remove these from your builds you can use #ifdef so that the code is only compiled in release mode.
One thing to bear in mind is that you can still debug binaries in release mode, as long as you have the pdb files it shouldn't matter. Release mode just clears up variables sooner and applies some compiler optimisations
As I often have to debug things in Release configuration builds that don't have the DEBUG directive, I would not want these hints to the debugger to be removed.
However, if you have some proprietary or confidential information in the way you display things when debugging that you don't want to make it into your release build, you may want to consider using the ConditionalAttribute or #if/#elif/#endif preprocessor directives to control what is emitted into your release builds.
For example, you could do:
#if DEBUG
[DebuggerDisplay...]
#endif
public class MyAwesomeClass
{
}
This would ensure the attribute is only emitted when the DEBUG directive is given.
I'll share a pattern that I've come to appreciate using partial.
public partial class MyClass{
//class details here
}
And then elsewhere:
#if DEBUG
[DebuggerDisplay("DebuggerValue")]
public partial class MyClass{
//anything needed for debugging purporses
}
#endif
This gives the ability to use DebuggerDisplay or other attributes without cluttering-up the base class.
I've been using a handful of files, all wrapped in #if DEBUG to hold these Debug-Partials. It helps keep the core classes cleaner and I don't have to remember to start/end compiler directives for each attribute.
I would think it would be a bad idea, because a lot of times the thing you're attaching the attribute to has some other use besides just showing it in the debugger, IMO.

Does C# inline properties?

Does C# inline access to properties? I'm aware of the 32 byte (instruction?) limit on the JIT for inlining, but will it inline properties or just pure method calls?
It's up to the JIT (the C# compiler doesn't do any inlining as far as I'm aware), but I believe the JIT will inline trivial properties in most cases.
Note that it won't inline members of types deriving from MarshalByRefObject which includes System.Windows.Forms.Control (via System.ComponentModel.Component).
I've also seen double fields end up being less efficient when accessed via properties - it could be that there are some subtleties around that (due to register use etc).
Also note that the 64-bit and 32-bit JITs are different, including their treatment of what gets inlined.
EDIT: I've just found a 2004 blog entry by David Notario with some more information. However, that was before 2.0 shipped - I wouldn't be surprised to see that at least some of it had changed now. Might be of interest anyway.
EDIT: Another question referred to a 2008 Vance Morrison blog entry which gives more information. Interesting stuff.
A property access is just a pure method call. There is no difference in the IL the compiler emits for a property access and for a method call with a similar signature, which sort of answers your question.
It took me a while to figure out that in Visual Studio you can view the disassembly of managed code, after the JIT compiles it.
So why not create a class with a very simple accessor property, run it in release mode, set a breakpoint, and see what the disassembly says?
I posted a similar question recently:
Why are public fields faster than properties?
The issue with mine was that a public field was faster than a property because I'm running 64-bit Vista and the JIT compiled my code to 64-bit as well, and my properties were not in-lined. Forcing the project to compile for x86 did in-line the property and there was no speed difference between the property and the public field.
So, the C# 32-bit JIT does in-line properties, the 64-bit doesn't, nor any other non-static methods.

Categories

Resources