MACROS are not all bad, can anyone help?

C

Chronologic

All,

I have an issue I would like some expert help on.

I understand, or so I believe, that C# does not support the concept of
a "compile time macro". At least not in the sense I'm looking for.

While many users contend that macros are inherently evil, I would
argue that no - they are not, they have a function. That function is
sometimes -- perhaps much too often -- abused, but they do have a
unique function in life that gives them a unique power than no other
construct has. In other words, the Platonic Form of a Macro does
exists and has inherent qualities that make them What They Are. So
therefore, follows my question:

Compile time macros, aka Preprocessor Directives allow the compiler to
in essence make a decision for you. Generally speaking this is a
"compile time decision" that makes no sense but to make it --> at
compile time :).

The most valid use of this I can think of (actually the use I am
clamoring for) is to eliminate unecessary calls given some case that
can be determined at compile time. I am sure there are other uses
that have merit.

In C++ you can define a macro that resolves to something at compile
time, or nothing at compile time, if you so desire.

The best example of this is TRACE or other debug macros that resolve
to absolutely nothing at compile time if DEBUG is not defined.

What I want is a way to resolve something to nothing given a compile
flag, but in a more readable way.

Certainly I believe that within the bounds of C# I can put this
construct in my code in numerous places:

#If Defined XXXX
//some code here I want only to be compiled in SOMETIMES
#End IF

My research into the capabilities of C# .Net suggests that some
construct (spelling and exact phrasing not critical) akin to that is
very possible in C#.

But I would much rather do this:

#define CONDITIONAL_SOME_OPERATION //some code here I want to be
compiled in only sometimes

I find it perfectly acceptable to encapsulate the code in any way that
is acceptable under the .NET and C# idiom. For example, I might
create a class called BuildEnvironment. Under BuildEnvironment I
might have a number of configureation classes, with methods that would
resolve to appropriate implementations. Again consider this a
pseudo-code example -- I'm not going for correct syntax, or even
totally correct engineering principles. I'm just trying to get the
idea across:

class BuildEnvironment
{
class EnvA
{
public void MyMethod();
}
class EnvB
{
public void MyMethod();
}
}

and then define a macro as such in a header location:

#If Defined BUILD_A
#define MYMETHOD BuildEnvironment.EnvA.MyMethod();
#End If
#If Defined BUILD_B
#define MYMETHOD BuildEnvironment.EnvB.MyMethod();
#End If

Therefore, from within any code module I can place calls to MYMETHOD
and if build envrinment A is in effect, I get the call I want, if
Build environment B is in effect, I still get the call I want, if
Neither one is the case, I get basically no call at all. Note that
the BuildEnvironment class (or namespace) and its subclasses are
always defined. I'm not trying to hide or mangle their definition,
only the calls to them and the resulting stack allocations.

That's really what I am looking for, a way to COMPILE OUT certain
calls if I want and therefore NOT have any proccessor time or stack
space wasted on a call to a function that I don't want to call in that
environment, but yet have the code very readable, and managed in a
similar way despite the build environment.

BTW, FYI, The build environments I have in mind are DEBUG, RELEASE,
RELEASE_LOGGING, and perhaps gradations (though probably not).

Now, certainly there is a way to do this in C#, but I don't find the
alternatives very eloquent. I can think of two ways.

Option one is sprinkling my code with a bunch of calls like this:
#If Defined A
MakeMyCall_A
#End If
#If Defined B
MakeMyCall_B
#End If

This would show up throughout my code making it unreadable, a pain to
type, and a bit ugly. I guess I could put it in regions. The
advantage to this method is I would not have any stack space wasted on
a call to a function I don't want to call.

The other option would be to define the function, always call it and
have it decide what to do:

virtual class Builds
{
static void MyMethod()
{
#If Defined A
//do the A stuff
#End If

#If defined B
//Do the B Stuff
#End If
}
}

here, the advantage would be much more readable code from the calling
point, much easier to type and maintain, still giving me multiple
implementations available depending on the build environment. While
the negative side is that I will have unnecessary stack space
allocations in my code execution paths because if Neither A or B was
defined (IE full release build) I would still call what would resolve
to basically an empty function call. (Though perhaps some expert will
inform me that the C# compiler itself will optimize this call and NOT
allocate the stack space for the IP, and actually make the JMP and RET
calls that would result from calling a function that does nothing...
that would be something I guess)

Now, I'm sure there are a number of seasoned developers out there with
some ideas on how to best get what I want, or at least give me an
opinion on what is the best option under the circumstances to help me
decide.

Basically the goals are:
Multiple configurations
Maximize readability
Minimize coding keystrokes
Maximize execution speed in the release build

Does C# .Net afford meeting all of these goals?

Thank you in advance for your kind consideration of my query.
--Chronologic
 
N

Nick Malik

now, that's cool.

Thanks, Daniel. It's for nuggets like this that I spend time reading these
newsgroups.

--- Nick

Daniel O'Connell said:
Have you looked at the conditional attribute[1]? It may do what you want...
http://msdn.microsoft.com/library/d.../en-us/csspec/html/vclrfcsharpspec_17_4_2.asp
Chronologic said:
All,

I have an issue I would like some expert help on.

I understand, or so I believe, that C# does not support the concept of
a "compile time macro". At least not in the sense I'm looking for.

While many users contend that macros are inherently evil, I would
argue that no - they are not, they have a function. That function is
sometimes -- perhaps much too often -- abused, but they do have a
unique function in life that gives them a unique power than no other
construct has. In other words, the Platonic Form of a Macro does
exists and has inherent qualities that make them What They Are. So
therefore, follows my question:

Compile time macros, aka Preprocessor Directives allow the compiler to
in essence make a decision for you. Generally speaking this is a
"compile time decision" that makes no sense but to make it --> at
compile time :).

The most valid use of this I can think of (actually the use I am
clamoring for) is to eliminate unecessary calls given some case that
can be determined at compile time. I am sure there are other uses
that have merit.

In C++ you can define a macro that resolves to something at compile
time, or nothing at compile time, if you so desire.

The best example of this is TRACE or other debug macros that resolve
to absolutely nothing at compile time if DEBUG is not defined.

What I want is a way to resolve something to nothing given a compile
flag, but in a more readable way.

Certainly I believe that within the bounds of C# I can put this
construct in my code in numerous places:

#If Defined XXXX
//some code here I want only to be compiled in SOMETIMES
#End IF

My research into the capabilities of C# .Net suggests that some
construct (spelling and exact phrasing not critical) akin to that is
very possible in C#.

But I would much rather do this:

#define CONDITIONAL_SOME_OPERATION //some code here I want to be
compiled in only sometimes

I find it perfectly acceptable to encapsulate the code in any way that
is acceptable under the .NET and C# idiom. For example, I might
create a class called BuildEnvironment. Under BuildEnvironment I
might have a number of configureation classes, with methods that would
resolve to appropriate implementations. Again consider this a
pseudo-code example -- I'm not going for correct syntax, or even
totally correct engineering principles. I'm just trying to get the
idea across:

class BuildEnvironment
{
class EnvA
{
public void MyMethod();
}
class EnvB
{
public void MyMethod();
}
}

and then define a macro as such in a header location:

#If Defined BUILD_A
#define MYMETHOD BuildEnvironment.EnvA.MyMethod();
#End If
#If Defined BUILD_B
#define MYMETHOD BuildEnvironment.EnvB.MyMethod();
#End If

Therefore, from within any code module I can place calls to MYMETHOD
and if build envrinment A is in effect, I get the call I want, if
Build environment B is in effect, I still get the call I want, if
Neither one is the case, I get basically no call at all. Note that
the BuildEnvironment class (or namespace) and its subclasses are
always defined. I'm not trying to hide or mangle their definition,
only the calls to them and the resulting stack allocations.

That's really what I am looking for, a way to COMPILE OUT certain
calls if I want and therefore NOT have any proccessor time or stack
space wasted on a call to a function that I don't want to call in that
environment, but yet have the code very readable, and managed in a
similar way despite the build environment.

BTW, FYI, The build environments I have in mind are DEBUG, RELEASE,
RELEASE_LOGGING, and perhaps gradations (though probably not).

Now, certainly there is a way to do this in C#, but I don't find the
alternatives very eloquent. I can think of two ways.

Option one is sprinkling my code with a bunch of calls like this:
#If Defined A
MakeMyCall_A
#End If
#If Defined B
MakeMyCall_B
#End If

This would show up throughout my code making it unreadable, a pain to
type, and a bit ugly. I guess I could put it in regions. The
advantage to this method is I would not have any stack space wasted on
a call to a function I don't want to call.

The other option would be to define the function, always call it and
have it decide what to do:

virtual class Builds
{
static void MyMethod()
{
#If Defined A
//do the A stuff
#End If

#If defined B
//Do the B Stuff
#End If
}
}

here, the advantage would be much more readable code from the calling
point, much easier to type and maintain, still giving me multiple
implementations available depending on the build environment. While
the negative side is that I will have unnecessary stack space
allocations in my code execution paths because if Neither A or B was
defined (IE full release build) I would still call what would resolve
to basically an empty function call. (Though perhaps some expert will
inform me that the C# compiler itself will optimize this call and NOT
allocate the stack space for the IP, and actually make the JMP and RET
calls that would result from calling a function that does nothing...
that would be something I guess)

Now, I'm sure there are a number of seasoned developers out there with
some ideas on how to best get what I want, or at least give me an
opinion on what is the best option under the circumstances to help me
decide.

Basically the goals are:
Multiple configurations
Maximize readability
Minimize coding keystrokes
Maximize execution speed in the release build

Does C# .Net afford meeting all of these goals?

Thank you in advance for your kind consideration of my query.
--Chronologic
 
D

Daniel O'Connell

There are alot of interesting little nuggets hiding in the system...its
always nice to run across one you didn't know about.
Nick Malik said:
now, that's cool.

Thanks, Daniel. It's for nuggets like this that I spend time reading these
newsgroups.

--- Nick

Daniel O'Connell said:
Have you looked at the conditional attribute[1]? It may do what you want...
http://msdn.microsoft.com/library/d.../en-us/csspec/html/vclrfcsharpspec_17_4_2.asp
 
C

Chronologic

Daniel,

No, I hadn't run across this, thanks a bunch! On first glance it
looks like it is exactly what I was looking for. It was my hope that
the new environment brought a new solution to an old problem.
Excellent.

Chronologic
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top