In C/C++ we've had
#ifdef _DEBUG
...
#endif
In C# we've got
#if DEBUG
...
#endif
and
[Conditional("DEBUG")]
I don't expect anything as fancy as an attribute based way of dealing with debug only code but would like to know if there's a manifest constant kind of thing or any other way of making code only present in a debug build. For instance I'm doing the following in Lua at the moment:
if not type(parameters.callback) == 'function' then
error('The "callback" parameter is not a function, or missing (nil).');
end
if not type(parameters.times) == 'number' then
error('The "times" parameter is not a number or missing (nil).');
end
if not type(parameters.interval) == 'number' or not parameters.interval == nil then
error('The "interval" parameter is not a number.');
end
I don't even know if that will run. Totally new to the language.
Given the nature of the function I'm writing, a simple retry function taking the number of attempts to make, an optional interval and a callback as parameters - which I anticipate being used many times throughout the application being written - and that its to be run on a micro controller I feel these checks should not be made in a production release as I'm guessing they could be relatively costly?!?! I'm even doing a type check within a for loop.
Is there already something built into the language to allow for conditional compilation? Or has anyone come up with a neat and clean way of handling this sort of thing? I know I could declare a global variable marking it a debug build and simply put and if block around the above but I thought I'd ask.
Googling has got me nowhere. In fact when I read the sites that talk about Lua I feel like I've stepped back to the mid to late 90's web.
Thanks,
Lee.
EDIT
Or perhaps I just write the method as a C module?!?!
way of making code only present in a debug build
There is no "build" for Lua. It's an interpreted language. Internally it is compiled to byte code, but that's an implementation detail.
However, if you're OK with having a build step, then you can just use a precompiler, exactly as C does. In fact, you can use the same one your your C compiler does, then you're getting the exactly syntax you're already familiar with.
For instance, my old copy of MSVC uses cl /EP <filename> to run filename through the preprocessor and dump the output to stdout. Then you can write:
#ifdef _DEBUG
-- debug Lua code goes here
#endif
The cleanest way would probably be something like
_DEBUG = true
if _DEBUG then
--code
end
The flavour of Lua being used is eLua or Embedded Lua and it does allow pre-compiling scripts to bytecode.
The code is on GitHub so if time permits I'll see about submitting a patch that will allow for true conditional compilation as it's all C under the hood.
In that way everyone benefits. Whether the checks in the original question are costly or not there are often times when you want code in or out depending upon whether you're actively working on it or its being used in a production environment but not the other way around.
And since they support pre-compilation and only target embedded devices with differing levels of performance and memory constraints I wouldn't be surprised if they haven't already implemented support. I'll hop along there and find out next.
Thanks all.
I have an application and I will have two versions - Trial and Commercial. The trial will have some limited features compared to the Commercial version.However I need to make it so that when one has the trial version, it will be impossible for him to uncover the features in the full version. The simplest idea is to have two absolutely separate builds, however this will be hard to maintain(I think). The second idea I have is to build the solutions with a Conditional Compilation Symbols - Trial and Full. I will adapt the source to work this way and I will use #If statements. My question is if this is safe. As it seems the code which is not in the Full compilation symbol's #If statement will be excluded from the assembly but I need your help on this as I need to be sure. Thanks a lot
You are correct code excluded via conditional compilation will not be included in the resulting executable. In that way it is 'safe', i.e. it can't be hacked to execute code that isn't there. All managed code by it's nature is decompilable.
You cannot use conditional compilation to produce a single executable file that contains both states (defined/undefined) of your code and select behavior at runtime.
I have an application where I used compiler switches to control whether large chunks of code were included or not. Think car with automatic transmission or manual transmission.
Works fine in Debug mode but in Release mode it looks like both Auto Transmission and Manual Transmission are compiled so the car doesn't drive too well...
So am I wrong in trying to get option control functionality out of compiler switches?
More Detail:
My understanding of compiler switches was flawed.
Simple project in comments below.(Not too good at driving StackOverFlow)
To continue the analogy, The (Winform) project was built with manual transmission. It was deployed in debug mode using a setup project. (Mistake).
After some years Auto-transmission was required. (No commonality to give rise to a base class).
The thought was that one day manual transmission may be required again)
Seemed like a compiler switch was a good idea to decide which block of code to use.
Again the Auto-transmission version was deployed in debug mode.
After some more years of running I decided that it should be released. That was when I noticed the problem.
The simple example asked for (thanks) showed me that it wasn't both blocks that were being compiled, just the block in the #else. i.e. Release build regards the switch as off.
So unless I am missing something the answer is self-evident. Don't use compiler switches for deployment options.
I suggest you use composition instead and make use of object-orientation. Have two classes, one for AutoTransmission, and another for ManualTransmission. Each one will derive from a base class Transmission Then you can use either one as you see fit when you create the object that makes use of one of these transmissions.
Then, when you create the object that uses a Transmission, simply instantiate whatever transmission you need. That could be defined in config, or it could be compiler constants. But, I'd recommend against compiler constants because when you perform automatic refactorings blocks of could disabled by #ifdef will not be processed and may not build when you change your compiler options.
I develop and maintain a large (500k+ LOC) WinForms app written in C# 2.0. It's multi-user and is currently deployed on about 15 machines. The development of the system is ongoing (can be thought of as a perpetual beta), and there's very little done to shield users from potential new bugs that might be introduced in a weekly build.
For this reason, among others, i've found myself becoming very reliant on edit-and-continue in the debugger. It helps not only with bug-hunting and bug-fixing, but in some cases with ongoing development as well. I find it extremely valuable to be able to execute newly-written code from within the context of a running application - there's no need to recompile and add a specific entry point to the new code (having to add dummy menu options, buttons, etc to the app and remembering to remove them before the next production build) - everything can be tried and tested in real-time without stopping the process.
I hold edit-and-continue in such high regard that I actively write code to be fully-compatible with it. For example, I avoid:
Anonymous methods and inline delegates (unless completely impossible to rewrite)
Generic methods (except in stable, unchanging utility code)
Targeting projects at 'Any CPU' (i.e. never executing in 64-bit)
Initializing fields at the point of declaration (initialisation is moved to the constructor)
Writing enumerator blocks that use yield (except in utility code)
Now, i'm fully aware that the new language features in C# 3 and 4 are largely incompatible with edit-and-continue (lambda expressions, LINQ, etc). This is one of the reasons why i've resisted moving the project up to a newer version of the Framework.
My question is whether it is good practice to avoid using these more advanced constructs in favor of code that is very, very easy to debug? Is there legitimacy in this sort of development, or is it wasteful? Also, importantly, do any of these constructs (lambda expressions, anonymous methods, etc) incur performance/memory overheads that well-written, edit-and-continue-compatible code could avoid? ...or do the inner workings of the C# compiler make such advanced constructs run faster than manually-written, 'expanded' code?
Without wanting to sound trite - it is good practice to write unit/integration tests rather than rely on Edit-Continue.
That way, you expend the effort once, and every other time is 'free'...
Now I'm not suggesting you retrospectively write units for all your code; rather, each time you have to fix a bug, start by writing a test (or more commonly multiple tests) that proves the fix.
As #Dave Swersky mentions in the comments, Mchael Feathers' book, Working Effectively with Legacy Code is a good resource (It's legacy 5 minutes after you wrote it, right?)
So Yes, I think it's a mistake to avoid new C# contructs in favor of allowing for edit and continue; BUT I also think it's a mistake to embrace new constructs just for the sake of it, and especially if they lead to harder to understand code.
I love 'Edit and Continue'. I find it is a huge enabler for interactive development/debugging and I too find it quite annoying when it doesn't work.
If 'Edit and Continue' aids your development methodology then by all means make choices to facilitate it, keeping in mind the value of what you are giving up.
One of my pet peeves is that editing anything in a function with lambda expressions breaks 'Edit and Continue'. If I trip over it enough I may write out the lambda expression. I'm on the fence with lambda expressions. I can do some things quicker with them but they don't save me time if I end up writing them out later.
In my case, I avoid using lambda expressions when I don't really need to. If they get in the way I may wrap them in a function so that I can 'Edit and Continue' the code that uses them. If they are gratuitous I may write them out.
Your approach doesn't need to be black and white.
Wanted to clarify these things a bit
it is good practice to avoid using these more advanced constructs in favor of code that is very, very easy to debug?
Edit and Continue is not really debugging, it is developing. I make this distinction because the new C# features are very debuggable. Each version of the language adds debugging support for new language features to make them as easy as possible debug.
everything can be tried and tested in real-time without stopping the process.
This statement is misleading. It's possible with Edit and Continue to verify a change fixes a very specific issue. It's much harder to verify that the change is correct and doesn't break a host of other issues. Namely because edit and continue doesn't modify the binaries on disk and hence doesn't allow for items such as unit testing.
Overall though yes I think it's a mistake to avoid new C# contructs in favor of allowing for edit and continue. Edit and Continue is a great feature (really loved it when I first encountered it in my C++ days). But it's value as a production server helper doesn't make up for the producitivy gains from the new C# features IMHO.
My question is whether it is good practice to avoid using these more advanced constructs in favor of code that is very, very easy to debug
I would argue that any time you are forcing yourself to write code that is:
Less expressive
Longer
Repeated (from avoiding generic methods)
Non-portable (never debug and test 64bit??!?!?)
You are adding to your overall maintenance cost far more than the loss of the "Edit and Continue" functionality in the debugger.
I would write the best code possible, not code that makes a feature of your IDE work.
While there is nothing inherently wrong with your approach, it does limit you to the amount of expressiveness understood by the IDE. Your code becomes a reflection of its capabilities, not the language's, and thus your overall value in the development world decreases because you are holding yourself back from learning other productivity-enhancing techniques. Avoiding LINQ in favor of Edit-and-Continue feels like an enormous opportunity cost to me personally, but the paradox is that you have to gain some experience with it before you can feel that way.
Also, as has been mentioned in other answers, unit-testing your code removes the need to run the entire application all the time, and thus solves your dilemma in a different way. If you can't right-click in your IDE and test just the 3 lines of code you care about, you're doing too much work during development already.
You should really introduce continues integration, which can help you to find and eliminate bugs before deploying software. Especially big projects (I consider 500k quite big) need some sort of validation.
http://www.codinghorror.com/blog/2006/02/revisiting-edit-and-continue.html
Regarding the specific question: Don't avoid these constructs and don't rely on your mad debugging skills - try to avoid bugs at all (in deployed software). Write unit tests instead.
I've also worked on very large permanent-beta projects.
I've used anonymous methods and inline delegates to keep some relatively simple bits of use-one logic close to their sole place of use.
I've used generic methods and classes for reuse and reliability.
I've initialised classes in constructors to as full an extent as possible, to maintain class invariants and eliminate the possibility of bugs caused by objects in invalid states.
I've used enumerator blocks to reduce the amount of code needed to create an enumerator class to a few lines.
All of these are useful in maintaining a large rapidly changing project in a reliable state.
If I can't edit-and-continue, I edit and start again. This costs me a few seconds most of the time, a couple of minutes in nasty cases. Its worth it for the hours that greater ability to reason about code and greater reliability through reuse saves me.
There's a lot I'll do to make it easier to find bugs, but not if it'll make it easier to have bugs too.
You could try Test Driven Development. I found it very useful to avoid using the debugger at all. You start from a new test (e.g. unit test), and then you only run this unit test to check your development - you don't need the whole application running all the time. And this means you don't need edit-and-continue!
I know that TDD is the current buzz-word, but it really works for me. If I need to use the debugger I take it as a personal failure :)
Relying on Edit and Cont. sounds as if there is very little time spent on designing new features, let alone unit tests. This I find to be bad because you probably end up doing a lot of debugging and bug fixing, and sometimes your bug fixes cause more bugs, right?
However, it's very hard to judge whether you should or should not use language features or not, because this also depends on many, many other factors : project reqs, release deadlines, team skills, cost of code manageability after refactoring, to name a few.
Hope this helps!
The issue you seem to be having is:
It takes too long to rebuild you app,
start it up again and get to the bit
of UI you are working on.
As everyone has said, Unit Tests will help reduce the number of times you have to run your app to find/fix bugs on none UI code; however they don’t help with issues like the layout of the UI.
In the past I have written a test app that will quickly load the UI I am working on and fill it with dummy data, so as to reduce the cycle time.
Separating out none UI code into other classes that can be tested with unit tests, will allow you do use all C# constructs in those classes. Then you can just limit the constructs in use in the UI code its self.
When I started writing lots of unit tests, my usage of “edit-and-continue” went down, I how hardly use it apart from UI code.
So Jeff Atwood rightly complained about Visual Studio not performing background compilation see: http://www.codinghorror.com/blog/2007/05/c-and-the-compilation-tax.html
The solution from most sources seems to be Reshaper which will incrementally perform background compilation as you write. This leads to their great realtime re-factoring tips and error detection.
But what I don't understand is with R# continually compiling my code, why does it take so long when executing a compilation via VS (i.e. Ctrl + Shift + B or similar). What I mean by this is, if R# has already compiled my code then why would I need a recompilation?
My assumption is of course that R# is not overriding the assemblies in my bin directories but instead holding the compilation results in memory. In which case, is it possible to tell R# to simply override my assemblies when compilation is successful?
I don't know about "rightly complained" - that's an opinion I happen to disagree with:)
However, the VB.NET (and probably Resharper c#) background compilers do not actually compile full assemblies - they cannot! If you think about it, the natural state of your code while you are working is not compilable! Almost every keystroke puts your code in an invalid state. Think of this line:
var x = new Something();
As you type this, from the key "v" to the key ")", your code is "wrong". Or what if you are referencing a method you haven't defined yet? And if this code is in an assembly that another assembly requires, how would you compile that second assembly at all, background or not?
The background compilers get around this by compiling small chunks of your code into multiple transient "assemblies" that are actually just metadata holders - really, they don't care about the actual effects of the code as much as the symbols defined, used, etc. When you finally hit build, the actual full assemblies still need to be built.
So no, I don't believe it's possible because they're not built to do actual full compilation - they are built to check your code and interpret symbols on the fly.
Reshaper which will incrementally perform background compilation as you write
It doesn't, it just parses the source code. The exact same thing Visual Studio already does if you don't have Resharper, that's how it implements IntelliSense, its own refactoring features and commands like GoTo Definition and Find All References. Visual Studio also parses in the background, updating its data while you type. Resharper just implements more bells and whistles with that parsing data.
Going from parsing the code to actually generating the assembly is a pretty major step. The internal format of an assembly is too convoluted to allow this to happen in the background without affecting the responsiveness of the machine.
And the C# compiler is still a large chunk of unmanaged C++ code that is independent from the IDE. An inevitable consequence of having to have the compiler first. It is however a stated goal for the next version of C# to provide compile-on-demand services. Getting true background compilation is a possibility.
I don't really have an answer but I just wanted to say that I have been using Eclipse and Java for 4 months now and I love the automatic compilation. I have a very large java code base and compilation happens constantly as I save code changes. When I hit Run everything is ready to go! It's just awesome. It also deploys to the local web server instance (Tomcat in my case) automatically as I make code changes. All this is setup by default in Eclipse.
I hope Microsoft does something similar with .net in the near future.