Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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]
Anonymous
March 09, 2004
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.Anonymous
March 09, 2004
The comment has been removedAnonymous
March 09, 2004
" 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? :)Anonymous
March 09, 2004
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...)Anonymous
March 09, 2004
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!Anonymous
March 09, 2004
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.Anonymous
March 09, 2004
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.Anonymous
March 10, 2004
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#.Anonymous
March 10, 2004
>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.
:>Anonymous
March 11, 2004
The comment has been removedAnonymous
March 19, 2004
The comment has been removedAnonymous
January 14, 2008
In short, macros are often times misappropriated when there are better and more consistent means to accomplish...Anonymous
January 21, 2009
PingBack from http://www.keyongtech.com/670880-macro-for-function-style-informationAnonymous
January 27, 2010
My question is why c# defines have the small scope of a file, as someone who comes from a c++ background one of the things I really appreciated is being able to define a debug directive so I can optionally include additional debug information throughout my program and simply remove the directive when I want to do a release buildAnonymous
May 28, 2010
The comment has been removedAnonymous
June 18, 2010
ya ya ya. macros are ugly and bad. we all know it. but now I have to implement an algorithm for int16, int32, int64 and decimal if i want to change it i have to change it in four places much uglier in my opinion. I WANT MACROS. YOU DONT LIKE IT? DONT USE IT. GIVE ME THE OPTION. DO NOT FORCE ME to write the same code 4 times. IT IS THERE FOR A ... REASON!Anonymous
September 01, 2010
Why doesn't C# have macros like C++? Because its not C++. Want to use macros? Go back to C++. The world is full of programming languages, each one developed with its own philosophy and goals in mind. You should pick the language that is most appropriate for your task and learn that language and its philosophies, not take a language and try to fit it to your philosophies. It would be like driving on the left side of the road and telling the police that they are wrong to not allow you do what you want. And remember, never stop learning. Just because you used to do it one way doesn't mean thats the only way to do it.Anonymous
October 31, 2010
There is definitely a need for a macro language in C#. Declarations of dependency properties is just one example. It would be much nicer if I could create a macro that let me write DEPENDENCY_PROP(int,propProperty,"prop",MyClass) instead of the usual garbage: public static DependencyProperty propProperty = DependencyPropety.Register("prop",typeof etc... public int prop { get ... etc... (Anonymous
November 14, 2010
Macros are difficult to debug? Yes, but: The debugger environment should show the expanded code (which no environment that I know of does), not the actual source (or at least there should be this option). (Also searching in code should use that view). Some of the comments above suppose certain simple uses of macros. But macros can do much more, for instance contain code blocks that begin and end at very different brace levels. (Usually such use comes in compensating pairs). I agree with the fact that refactoring becomes rather difficult on a combination of macros and tokenizing. (This might lead to a need to refactor other names as well). But, the environment could warn if refactoring interferes with Macros&Tokenizing (which seldom is the case) and maybe even refuse to refactor such cases. Another suggestion is to show both source+expanded (on first example) views (split screen) while editing a macro, which would make it much more easy to design them. Much of the ugliness perception comes from the need to mentally expand the macro. For printed source, however, the ugliness is there to stay. The fact that C# doesn't have a true macro possibility yet, is an opportunity to rethink the concept and design a new&elegant format, for instance not needing the annoying backslash for multiline macros. This said, I agree of course that macros (if&when available) should be avoided in C# if more elegant ways to achieve the same can be used.Anonymous
November 30, 2010
Leave C# clean and use managed C++ if you need for macros.Anonymous
December 15, 2010
I have a table of User Names which also contain a security level for that user. I need the text (associated in an enum) with that security level. userTable = dataTable for Users, passwords, security level, etc. Properties.Settings.Default.UserIndex = index of Current User SecurityLevelName[] = array of Text for describing Security Level (actual case was more complex but I streamlined it a bit for here...) I can write (every time!) string s =SecurityLevelName[userTable.Rows[Properties.Settings.Default.UserIndex][2]; or I can write a couple of macros such as'CURRENTUSER(i)' and 'GETSECURITYLEVEL(j)' (which I only have to debug once; macro definition left to reader) and then write: string s = SECURITYLEVELTEXT(CURRENTUSER); So which is easier to understand? Which is easier to write? The restrictions imposed tie our hands, stifle our creativity, and force us down paths that are envisioned by a narrow focus and unyielding minds. PS And Sergei, sometimes we don't always get to choose whether we use C++ or C#.Anonymous
December 19, 2010
One thing I usually use macros for is debug call wrapping like this (AFAIK works for GCC only): #ifdef DEBUG #define CALL_WRAP(call) { int result=call; if (result) printf(#call" return an error %i", i); else printf(#call" ok "); result; } #else #define CALL_WRAP(call) call #endif Or, less complex and more portable: #ifdef DEBUG #define CALL_WRAP(call) printf(#call " return %i", call); #else #define CALL_WRAP(call) call #endif Is there a way to do such things in C# without performance loss (e.g being sure call is inline)?Anonymous
January 03, 2011
You've got to be kidding me. I'm sure you're familiar with the DECLARE_DYNCREATE() macro used in MFC. Using macros just eliminates hours of needless repetitive typing. Whoever thought this was a good idea obviously has never programmed in his life.Anonymous
February 02, 2011
shut up! Microsoft knows better than you do, You shouldn't be using Macros, Bill never had toAnonymous
February 14, 2011
I can think of a couple of situations where I REALLY NEED macros and C# gives me no reasonable alternative. :( I could care less of the IntelliSense implications.Anonymous
May 23, 2011
"and in most cases, the JIT will inline them" One case where this is false is when using the XNA framework or the JIT on the Xbox360, which NEVER inlines code. This limitation will could cause someone to have to write a pre-processor for C#, which would be avoided by macros.Anonymous
June 13, 2011
C# has its roots with Borland Delphi. Delphi never had macros and so be c#. I would love to have macros to implement the mechanism for the Debug Statements to disappear from release builds automatically.Anonymous
February 12, 2012
But MAcros is a grat tool for programmer to write thier code i think C#should have that functions because only programmers can understand what thier code is doing no common peoplesAnonymous
March 31, 2012
Yeah, it's pretty frustrating when someone tries to tell you how to write your code and what to use and not to... Welcome to China :) C# favors readability of the code over the speed of compiled executables, and that is why the resulting modules are so much slower and bloated than the ones written in C/C++. I am missing Macros BIG TIME!Anonymous
March 31, 2012
Compile-time macros, man, compile-time. I have to explicitly specify a set of constructors for every class I derive from my base class. I want to just say "CONSTRUCTORS_DEF()" or something instead of writing it out every time. I love C#, but something designed to be convenient should allow for something as basic as macros. Your job isn't to force me to code a certain way. I don't need to learn structure -- that's what PASCAL was for. If you want a greater number of serious developers to move over to C# then you will trust them to code properly. If you need to have a "C# in dummy mode", then fine, have a compile-time option that disables macros. Or even, let the class specify if it can be used in macros or not -- then it's up to the DEVELOPER. I've been coding since I was 8 on a Commodore 64. I know how to structure my code, so who the heck are you to tell me what's "clean" code and what isn't? This is the kind of thing right-wingnuts think we're doing with regulations. Like regulations, sometimes you need to force developers to code a certain way. However, not including something as basic as macros because we're "not responsible enough to write clean code" is pretty much the definition of the "Broccoli argument" (look it up). Really insulting reason, to be honest.Anonymous
February 03, 2013
A long explanation instead of just - "we just cannot do this in C# " ))))Anonymous
February 07, 2013
Any tool, when abused, can produce bad results (e.g. chainsaws, etc.) That is no reason to outlaw chainsaws, however. The answer is to train the operator property, since chainsaws have many beneficial uses. The lack of macros means that I can no longer do the equivalent of the following #if defined(__DEBUG) #define DEBUGPRINT(x) printf(x) #else #define DEBUGPRINT(x) #endif Sure, I could replace DEBUGPRINT with a function whose body was empty if __DEBUG was not defined, but the compiler would still have to generate code to evaluate the arguments every time, whether in debug mode or not, and evaluating the arguments could be arbitrarily long and complex. With the macro, the entrie DEBUGPRINT invocation, and its argument evaluation, simply go away.Anonymous
March 22, 2013
Using macros wisely can significantly improve READABILITY. I have bunch of fields with the same attributes: private DateTime? _someAtt; [DbType( "smalldatetime" )] [NullValue( typeof( DateTime ), "1/1/0001 12:00:00 AM" )] [DevExpress.Persistent.Base.VisibleInDetailViewAttribute( true )] [DevExpress.Persistent.Base.VisibleInListViewAttribute( false )] [DevExpress.Persistent.Base.VisibleInLookupListViewAttribute( false )] public System.DateTime? SomeAtt { get { return _someAtt; } set { SetPropertyValue( "SomeAtt", ref _someAtt, value ); } } which I have to repeat over and over and again... With help of macro I would easily define and use one line: DEF_MYPROP( DateTime, SomeAtt ) now don't tell me MACROS are evilAnonymous
August 08, 2013
If #define macro expansion was omitted from C# because of potential misuse, then I would guess that MOST of the features of C# should be omitted for the same reason. Potential for misuse is not a very good criteria for language features.Anonymous
August 07, 2014
"The first is one of readability." - I'm very sorry, but this is very subjective - and not at all to not support c++ like macros in c#. We use c++ macros in a very big application (build time is more than 12h…) - and macros are readable and easy to use. You just need to know how to use it. As almost everything related to programming so that it is readable. Kind regards, TomAnonymous
November 16, 2015
Your example of how bad are macros (PRODUCT) is bad. Always enclose parameters: (x)