Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to define a define?

Status
Not open for further replies.

theotyflos

Programmer
Oct 15, 2000
132
GR
Hi all,

I have the following:

/*--- SNIP ---*/
Code:
typedef struct Argument_s
{
  char *address;
  int   type;
  int   length;
} ARGUMENT;

#define Function(F) int F( int ArgCount, ARGUMENT ArgVector[] )

#define First       ArgVector[0]
#define First_A     First.address
#define First_T     First.type
#define First_L     First.length
#define Second      ArgVector[1]
#define Second_A    Second.address
#define Second_T    Second.type
#define Second_L    Second.length
#define Third       ArgVector[2]
#define Third_A     Third.address
#define Third_T     Third.type
#define Third_L     Third.length

Function(One)
{
/* do something with First_A */
/* do something with First_T */
/* do something with First_L */
/* do something with Second_A */
/* do something with Second_T */
/* do something with Second_L */
/* do something with Third_A */
/* do something with Third_T */
/* do something with Third_L */
/* etc etc */
}

#define Apple       ArgVector[0]
#define Apple_A     Apple.address
#define Apple_T     Apple.type
#define Apple_L     Apple.length
#define Orange      ArgVector[1]
#define Orange_A    Orange.address
#define Orange_T    Orange.type
#define Orange_L    Orange.length

Function(Two)
{
/* do something with Apple_A */
/* do something with Apple_T */
/* do something with Apple_L */
/* do something with Orange_A */
/* do something with Orange_T */
/* do something with Orange_L */
/* etc etc */
}
/*--- SNIP ---*/

The question is: Is there a way instead of writing all those #defines
for the arguments (First, Second, etc), to write something like:
Code:
#define Arg(n) #define Arg     ArgVector[n]                 #define Arg##_A Arg.address                #define Arg##_T Arg.type                   #define Arg##_L Arg.length
and define the arguments like this:
Code:
Arg First(0)
Arg Second(1)
Arg Third(2)
Function(One)
....
Arg Apple(0)
Arg Orange(1)
Function(Two)
....

Thanks in advance everyone.


Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
avoid using of define

Ion Filipski
1c.bmp
 
nice joke :)

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
No, you can't have a preprocessor directive inside a #define.
But, as IonFilipski pointed out, there is most probably a better way to do what you want (and I have no clue what that might be, as of yet) without having to rely on defines.

Greetings,
Tobi
 
Hi Tobi,
Thanks for the answer. What i'm trying to do is avoid writing all those defines one by one. They can be up to 10 arguments or more for every function * 4 (for ArgVector[] ..._A ..._T ..._L) = 40something defines.

If you know of a way to do that without the defines, i'm all ears.

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
I know I can write
Code:
ArgVector[0].address
instead of
Code:
First_A
for example in the function's body, I just want to avoid this. BTW I'm NOT a C expert.


Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
So what does
Code:
#define First       ArgVector[0]
#define First_A     First.address
#define First_T     First.type
#define First_L     First.length
...
Function(One)
{
/* do something with First_A */
/* do something with First_T */
/* do something with First_L */
buy you, apart from what appears to be a bit less typing in the function?

Like what is so horrible with this?
Code:
Function(One)
{
/* do something with ArgVector[0].address */
/* do something with ArgVector[0].type */
/* do something with ArgVector[0].length */

You're certainly not buying anything useful if you have a #define for X and only use X in one or two places in the next few lines in the code.


Ok, so you want to 'document' the anonymous interface which is ArgVector in some way. Well that's pretty easy to do by adding a new scope, and declaring a variable with the better name within that scope.
Code:
Function(One)
{
  { ARGUMENT First = ArgVector[0];
    /* do something with First.address */
    /* do something with First.type */
    /* do something with First.length */
  }
}

On the face of it, it seems to me that you have so many #defines that the whole thing is being generated either automatically, or semi-automatically (or could be).

> 10 arguments or more for every function
So your code is fairly repetetive over this range - doing the same (or similar) things to all instances?
Code:
/* do something with First_A */
/* blah blah */
/* do something with Tenth_A */
Like if you do first.length = 0, then you also do tenth.length = 0

And how many of these functions do you have?


--
 
Hi Salem,
First of all, thanks for the answers.

So what does
...
buy you, apart from what appears to be a bit less typing in the function?

Less typing of course and documentation of the arguments.


Like what is so horrible with this?

well, not horrible, but I think if I need to make changes at some other time in the future, it will be easier for me to remember what First_A is, than ArgVector[0].address

You're certainly not buying anything useful if you have a #define for X and only use X in one or two places in the next few lines in the code.
Unfortunatelly the arguments are used extensively.

Ok, so you want to 'document' the anonymous interface which is ArgVector in some way.
Exactly.
Well that's pretty easy to do by adding a new scope, and declaring a variable with the better name within that scope.
Function(One)
{
{ ARGUMENT First = ArgVector[0];
/* do something with First.address */
/* do something with First.type */
/* do something with First.length */
}
}

So, If I understand correctly, you're saying instead of #define'ing an argument, to create another variable? Never thought of that. Is this good practice in C? What's the reason for the inner scope? What's wrong with declaring the variables at the begining of the function?

On the face of it, it seems to me that you have so many #defines that the whole thing is being generated either automatically, or semi-automatically (or could be).
No, it's written by hand.

So your code is fairly repetetive over this range - doing the same (or similar) things to all instances?
/* do something with First_A */
/* blah blah */
/* do something with Tenth_A */
Like if you do first.length = 0, then you also do tenth.length = 0

Again, unfortunatelly not. What I wrote was just an example. Every argument is pressessed differently.

And how many of these functions do you have?
46 till now and growing. It's a library I write, which will be called from RM/Cobol -pre CodeBridge, if Liant reads this- (so I can NOT change the function's prototypes, if that's what you're thinking).

Again thank you for your time and yor answers.

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
>theotyflos
As I can see you are a novice. There is no way to demonstrate you what you should avoid using of define. That will come only with personal programming experience.

You can use define:
1. to avoid including twice or more the same header
2. conditional compilation, for example compilling for different versions or platforms
3. Using some global constants(not constant variables!!!),
for example instead of writing 3.1415.... is better to write PI. But in this case much better is to declare a global constant variable with that value.

No programminc logic can be based on defines. If you want to use templates for functions, there exist another language - C++.

Ion Filipski
1c.bmp
 
Is this some kind of Cobol-to-C wrapper to allow inter-language calls?

Does that mean that the processing is based on the value stored in say first.type ?

> 46 till now and growing.
Ouch!

If this really is a inter-language translation wrapper, you should step back from the problem to try and see what the underlying patterns to the problem are.
Like for example, creating a library based on the .type member of the structure, then using some script to generate the 'function(one)' stuff automatically.

> What's the reason for the inner scope?
Your example suggested that the processing was linear
Code:
First
First
Second
Second
Not mixed, like this
Code:
First
Second
First
Second
Basically, once you're done with first, there is no longer a need to keep the variable, and the inner scope idea makes sure it doesn't hang around longer than necessary.

In addition, declaration and use are close to one another, which makes for easier reading. If you have say 10 of these, then the code dealing with the last one could be hundreds of lines away from the declaration.

It is also possible that
Code:
void foo ( void ) {
  int a, b;  // both must be stored
}
would use more stack space than
Code:
void foo ( void ) {
  { int a;
  }
  { int b; // a smart compiler will reuse the space just vacated by a
  }
}


--
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top