conditional operator again

J

junky_fellow

Hi guys,

I posted a query yesterday and got some good responses. However,
before posting
I did some simplications in my code. Now, I am posting what I exactly
want and what
I have done. I want your views if I have done it correctly or not ?
Are there any loopholes ?
Or can it be done in a better way ?

My objective is to convert a function func() to macro for efficiency.

The function func() is:

char ** func( int var, char **ptr)
{
if(var == 1)
return(ptr);
if(var == 2) {
if(*ptr == NULL)
return NULL;
else
return ptr;
}
func2(var, ptr);
}

I am using this function as follows:

int main(void)
{
char **ptr, **res;
int flag;
/* some code */
res = func(flag,ptr);
}

I have written the following macro.

#define func(flag, ptr) \
((flag == 1 || flag == 2) \
? (flag == 1) \
? (char **)ptr \
: ( flag == 2 && (*ptr == NULL) )
? NULL \
: (char **)ptr \
: (char**)func2(flag, ptr))


I want to know, if this would work fine or not ? Is there a better way
of doing this ?


thanks a lot in advance for any help .....
 
M

Markus Moll

Hi

My objective is to convert a function func() to macro for efficiency.

Is it necessary?
Have you tried to make the function static and to put it in your header
file?
The function func() is:

char ** func( int var, char **ptr)
{
if(var == 1)
return(ptr);
if(var == 2) {
if(*ptr == NULL)

undefined as soon as ptr == NULL.
return NULL;
else
return ptr;
}
func2(var, ptr);
}

did you mean "return func2(var, ptr)"?
I have written the following macro.

#define func(flag, ptr) \
((flag == 1 || flag == 2) \
? (flag == 1) \
? (char **)ptr \
: ( flag == 2 && (*ptr == NULL) )
? NULL \
: (char **)ptr \
: (char**)func2(flag, ptr))


I want to know, if this would work fine or not ? Is there a better way
of doing this ?

a) You lose some type-safety.
b) With macros, you should _always_ enclose the parameters in parenthesis:
#define func(flag, ptr) (( (flag) == 1 || (flag) == 2) ...
c) Your parameters may be evaluated more than once, which might lead to
problems (especially as you call your macro "func"):
ptr2 = func(++flag, ptr); // undefined
d) It's terrible to read.

All in all, don't do it.

Markus
 
J

junky_fellow

Markus said:
a) You lose some type-safety.
b) With macros, you should _always_ enclose the parameters in parenthesis:
#define func(flag, ptr) (( (flag) == 1 || (flag) == 2) ...
c) Your parameters may be evaluated more than once, which might lead to
problems (especially as you call your macro "func"):
ptr2 = func(++flag, ptr); // undefined
d) It's terrible to read.

All in all, don't do it.

Thanks for your suggestions. Just to clarify, nowhere in my code func()
will be
called as
ptr = func(++flag, ptr). In fact, flag is not a integer variable. It is
always called as
ptr = func(HASH_DEF_VALUE, ptr). where HASH_DEF_VALUE may be 1, 2 or
3.
And, also *ptr will never be NULL.
 
C

Chris Dollin

My objective is to convert a function func() to macro for efficiency.

Well, the first question I have is what makes you think that this
will be worth it? You have done the measurements, yes? You have
done refactoring? You don't have a working `inline`?
The function func() is:

char ** func( int var, char **ptr)
{
if(var == 1)
return(ptr);
if(var == 2) {
if(*ptr == NULL)
return NULL;
else
return ptr;
}
func2(var, ptr);
}

Really? Are you /sure/ this is the code you have? You didn't
miss out a `return` before that last call? [And I truly hope
that your actual functions aren't called `func` and `func2`.
I know this sounds picky, but knowing what this is /about/
can help a lot.]

So the /first/ line of attack, if you're hell-bent on this
transformation, is the obvious:

return
var == 1 ? ptr
: var == 2 ? (*ptr == NULL ? NULL : ptr)
: func2( var, ptr )
;

All your tests should still pass. Then the middle three
lines can become your macro body, with suitable guards:

#define FUNC( var, ptr ) \
((var) == 1 ? (ptr) \
: (var) == 2 ? (*(ptr) == NULL ? NULL : (ptr)) \
: func2( (var), (ptr) ) \
)
I have written the following macro.

#define func(flag, ptr) \
((flag == 1 || flag == 2) \
? (flag == 1) \
? (char **)ptr \
: ( flag == 2 && (*ptr == NULL) )
? NULL \
: (char **)ptr \
: (char**)func2(flag, ptr))

Hell's teeth, that looks complicated. What are all those casts for?
Why fiddle around with the tests?
I want to know, if this would work fine or not ? Is there a better way
of doing this ?

Dunno. I don't know what it's /for/. But I'd lay odds it'll make the
program go at pretty much the same speed as it already does.
 

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

Similar Threads


Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top