C# Frequently Asked Questions

The C# team posts answers to common questions

Why doesn't C# support #define macros?

In C++, I can define a macro such as:

#define PRODUCT(x, y, z) x * y * z

and then use it in code:

int a = PRODUCT(3, 2, 1);

C# doesn't allow you to do this. Why?

There are a few reasons why. The first is one of readability.

One of our main design goals for C# is to keep the code very readable. Having the ability to write macros gives the programmer the ability to create their own language - one that doesn't necessarily bear any relation to what the code underneath. To understand what the code does, the user must not only understand how the language works, but he must also understand all of the #define macros that are in effect at that point in time. That makes code much harder to read.

In C#, you can use methods instead of macros, and in most cases, the JIT will inline them, giving you the same performance aspect.

There's also a somewhat more subtle issue. Macros are done textually, which means if I write:

int y = PRODUCT (1 + 2, 3 + 4, 5 + 6)

I would expect to get something that gives me 3 * 7 *11 = 231, but in fact, the expansion as I've defined it gives:

int y = 1 + 2 * 3 + 4 * 5 + 6;

which gives me 33. I can get around that by a judicious application of parenthesis, but its very easy to write a macro that works in some situations and not in others.

Although C# doesn't strictly speaking have a pre-processor, it does have conditional compilation symbols which can be used to affect compilation. These can be defined within code or with parameters to the compiler. The "pre-processing" directives in C# (named solely for consistency with C/C++, despite there being no separate pre-processing step) are (text taken from the ECMA specification):

#define and #undef
Used to define and undefine conditional compilation symbols
#if, #elif, #else and #endif
Used to conditionally skip sections of source code
#line
Used to control line numbers emitted for errors and warnings.
#error and #warning
Used to issue errors and warnings.
#region and #endregion
Used to explicitly mark sections of source code.

See section 9.5 of the ECMA specification for more information on the above. Conditional compilation can also be achieved using the Conditional attribute on a method, so that calls to the method will only be compiled when the appropriate symbol is defined. See section 24.4.2 of the ECMA specifcation for more information on this.

Author: Eric Gunnerson]

Published Tuesday, March 09, 2004 6:30 PM by CSharpFAQ

Comments

 

Zinoblog said:

March 9, 2004 10:07 PM
 

Vadym Stetsyak said:

I doubt that users will read source code of the application. IMO developers should be able to use macro and readability issue has nothing to do with this.
March 9, 2004 10:39 PM
 

Josh Williams [MS] said:

Here's a reason that macro's suck! Debugging!! Have you ever had to debug a macro mess? Compiling the code as a debug build doesn't really help you at all, even then you end up effectively with inlined calls and non-type safe code. Maybe there is a way to get the meat of what macros accomplish in a type safe manner that is debuggable and the C# team just hasn't wrapped their heads around it. But I for one believe that with great power comes great responsibliity and as long as C# is aimed at a mainstream audience they should avoid the pre-processor as much as possible.

Given generics as part of the C# language now I think there is probably little that can't be done with a well designed type safe generic method where a macro would be a preferable implementation.
March 9, 2004 11:10 PM
 

CC said:

" But I for one believe that with great power comes great responsibliity and as long as C# is aimed at a mainstream audience they should avoid the pre-processor as much as possible."

I think the point is that we don't have the choice, the decision is made for us. One of the main reasons I gave up on Java was that Sun kept emasculating the language and productivity by telling us what we needed... er hello? :)
March 10, 2004 12:32 AM
 

Paul Bartlett said:

If you really need macros, just create your code as, say, HelloWorld.csx, then run that through the C preprocessor (CL /C /EP, if memory serves) to produce HelloWorld.cs. NOte that you'll probably loose lots of nice syntax checking, Intellisence and other stuff, so you'd better be sure that you do really, really need them...

(See also: http://blogs.geekdojo.net/pdbartlett/archive/2004/02/23/1191.aspx where I first "owned up" to having had this idea...)
March 10, 2004 12:37 AM
 

nfactorial said:

I used to think the lack of macros was a pain, but a little thinking about what you're trying to do usually produces much more intuitive code.

In C# there are no 'global' or classless methods, macro's would tend to lead to code that doesn't 'fit' into the C# model.

Also, for algorithmic macros (such as the PRODUCT macro mentioned) a method makes more sense in both the C++ world and the C# world.

The only real use of macros in the C++ world (IMHO of course) are 'helpers' such as the MFC "BEGIN_MESSAGE_MAP" and friends. These macros reduce code complexity by allowing the author to write code in a more simple way and not worry about the underlying (relatively) complex generated code.

C# (and the .NET framework in general) has events, reflection and attributes (which can do all sorts of things) that make similar 'magic' management possible, in a much neater way. I no longer miss macros and am glad they're gone.

Now, templates are another matter... Roll on Whidbey! :)

n!
March 10, 2004 2:25 AM
 

anon said:

The biggest reason to disallow macros is imho that it makes stuff like automatic refactoring in the IDE possible. If the intellisense had to understand every atrocity that can be commited with macros, it becomes very hard to offer autocompletion. That's why C++ intellisense booster tools like Visual Assist STILL aren't perfect.
March 10, 2004 5:03 AM
 

Josh Williams [MS] said:

CC: Personally I don't think that C# should try to be a language for everyone, I applaud their moves up market with the addition of generics and such in Whidbey. But if you're dyning for macros you should check out C++/CLI (Stan has a great blog: http://blogs.msdn.com/slippman). With Microsoft moving to make C++ a fully fledged member of the managed world it becomes worth looking at in my mind as a viable alternative to C# for managed code when C# just won't do exactly what you want.
March 10, 2004 7:53 AM
 

DarthPedro said:

As was mentioned earlier, besides making things harder to read, macros make debugging very painful. I would rather have the C# compiler do a good job of inlining short methods for me rather than creating macros to do that.

The complexity of the language will continue to increase with new versions, but keeping some of it hidden will help the adoption of C#.
March 10, 2004 9:16 AM
 

Zinoblog said:

March 10, 2004 12:25 PM
 

Edmundo Posada said:

>In C++, I can define a macro such as:
>#define PRODUCT(x, y, z) x * y * z
>and then use it in code:
>int a = SUM(3, 2, 1);
>C# doesn't allow you to do this. Why?

Neither does C++. You did not define any SUM() function or macro.

:>
March 10, 2004 10:30 AM
 

Shane King said:

Macros are only a problem when they act as a textual substitution mechanism. Just be brave, bite the bullet, and put in lisp style macros. ;)
March 11, 2004 11:53 PM
 

Kamil Skalski said:

People might find Nemerle language (http://nemerle.org) very interesting. I'm developer of its type-safe macro system: it is not a textual transformer, but operates on syntax trees. It can execute any code at compile-time, analyze (decompose) and generate fragments of code. We think it has resolved all drawbacks of preprocessor macros, while giving much more power to them (see http://nemerle.org/macros.html).

We will also focus on adding debug information to all generated code, so one would have no problems with debugging.
March 20, 2004 1:32 AM
 

Eldar's thoughts said:

In short, macros are often times misappropriated when there are better and more consistent means to accomplish...

January 14, 2008 7:31 PM
 

macro for __FUNCTION__ style information | keyongtech said:

January 21, 2009 8:19 PM
Anonymous comments are disabled

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker