#define directive purpose
Asked Answered
S

2

7

What is the purpose and good usage of #define directive in C#?

There are already few questions on this topic but no answer I need. They only give examples how it works. But I need deeper explanation: why does it exist and what are good ways of using it (if any).

Basically I know how to use it, but for me the usage looks odd. Let's look at example:

#define DEV

#if DEV
Console.WriteLine("Development trace log message");
#endif

For me this is completely different from using #if conditional build with project-defined conditional compilation symbols. If we use project-defined symbol, it is attached to project build configuration and we can manage code needed to build (and excluded from build) with build configuration used. So code

#if DEBUG
Console.WriteLine("Debug log message");
#endif

is fine for me. But as I said it is completely different from using #define directive because it is managable. Am I correct that 1st example can be managed only manually commenting/uncommenting #define line on every build? If yes, it is not managable, hard-to-maintain and I think this usage of #define is extreemely bad practice and sholdn't exists in the language at all.

I can imagine usage of #define/#undef inside #if statement. Something like

#if DEBUG
#if CLIENT1
#define TEST_CLIENT1
#endif
#endif

#if TEST_CLIENT1
connectionString = "Some specific test connection" //I know this is bad practice even in conditional. Only for example purpose.
#elif
//Read connection from config
#endif

#if UNITTESTS
#undef TEST_CLIENT1
#endif

#if TEST_CLIENT1
Console.WriteLine("Some message");
#endif

Sorry for so complicated example, but that is at least something I can find useful. Though I wouldn't write such code in any way =). Is there any good usage of #define?

PS: I never used #define myself for 5 years and had no will to do it, but I got a support project which has many strange defines which even named in an odd way. Those defines usually placed at the top of the file, like in my 1st example here. And I have no idea how to maintain this code.

Swansdown answered 27/7, 2012 at 9:52 Comment(0)
P
3

I can't see any valid reason for it other than without it, the #IF statement wouldn't exist.

When you define project level precondition variables using the /define directive on the compiler all it really does is add a #DEFINE to the code.

I would argue that this makes it manageable but not in setting it manually in the code, using the /define statement.

The other usefulness is readability and scope. Project defined statements apply to the project, #DEFINE level statements only apply to one file. This helps keep things organised, readable and stops variable issues.

Phyllisphylloclade answered 27/7, 2012 at 9:58 Comment(3)
Sorry, I don't understand what you mean under redability and scope here. Defining symbol in a file is the same as removing all code that not match conditions and remove #if conditions with this symbol. The only way to use it is less commenting/uncommending during debug. But why should this be present in release code? Under managable I mean ability to change it, running different build scripts or different build configurations in VS.Swansdown
@OleksandrPshenychnyy apologies if answer wasn't very clear, I would agree that it is highly unmanageable in the current form. The only benefit of having it listed in a file is you know its there, you can read it at the top of the file and know it supports these variables. I think most of the things you can do with define statements you can do with well managed code. You may take an extra OP or two, but if you REALLY REALLY want micro-optimization then it will be handy, but again if you need it optimized this much maybe C# isn't the choice :DPhyllisphylloclade
Thanks. Optimization is probably the last thing considered in that project =). But if you agree that #define isn't a good practice, I don't understand why it even exists in the C# language. You said compiler places it in the code (in every file??) when we use VS prject conditional symbol. That might be the reason actually, but I think it was possible to prohibit developers to write it in code.Swansdown
F
1

'#define' is there because people expect it to be there. :) For your purposes (e.g. a large project) it may make more sense to keep preprocessor symbols in your project. For quick debugging or other purposes #define may be the best choice. Additionally, #define allows fine-grained (file level) control of symbols.

Imagine you have a large codebase and a single module that is giving you trouble. You might wish to '#define TRACE' or '#define DEBUG' only in the single file where you want to enable tracing/debugging for performance reasons.

Faydra answered 27/7, 2012 at 9:57 Comment(2)
I afraid defining DEBUG symbol will not give you ability to debug code. From your words #define should be used only on project stabilization phase, for quick-fixes and logs. But I don't want to believe this construction exists only for this reason =)Swansdown
It's really a completeness thing. People who have grown accustomed to the C/C++ preprocessor are going to expect (as much as C# allows) a similar experience. That means being able to add preprocessor directives either via command line or in-code text. Being able to do both means the developer has more tools to work with. For example, imagine you have some service using CodeDom's compiler and you can only give it text to compile. You might like to use #if in that code for whatever reason, which means you need #define.Faydra

© 2022 - 2024 — McMap. All rights reserved.