rvalue

T

Tobias Oed

Hi all, It's been a while!
I'm working on a very buggy piece of code that uses a lot of macros.
A bunch of them look like
#define POSITION(mw,row) (mw.positions[row])
In order to debug the thing I'd like to modify these macors so they can only be
used as rvalues and not as lvalues. If they are used as lvalues I want my
compililation to fail. Unfortunately I can't remember a nice way to do that.
As always thanks for the help!
Tobias.
 
T

Tobias Oed

Stefan said:
You might cast them to their type. (A cast does not yield an
lvalue.)

True. But my compiler (gcc) requires special options (-pedantic) before
the following fails

int main(void){

int a;
(int) a = 3;

return 0;
}

If possible, I'd like to avoid that. Also, I'd have to be carefull
modifying all these macros not to screw up somewhere between an int
and short, and I'm no good at that kind of manual labour.
A while back there was a discussion here (or was it fclc?) about
web pages exposing exteme measures for defensive programming. One
part of it was the above. At the time I thought the author was insane.
Now that's just about what I need but google doesn't turn up anything...
I'll try the cast for select macros until something better comes up.
Thanks, Tobias.
 
T

Tobias Oed

Tobias said:
True. But my compiler (gcc) requires special options (-pedantic) before
the following fails

int main(void){

int a;
(int) a = 3;

return 0;
}

If possible, I'd like to avoid that. Also, I'd have to be carefull
modifying all these macros not to screw up somewhere between an int
and short, and I'm no good at that kind of manual labour.
A while back there was a discussion here (or was it fclc?) about
web pages exposing exteme measures for defensive programming. One
part of it was the above. At the time I thought the author was insane.
Now that's just about what I need but google doesn't turn up anything...
I'll try the cast for select macros until something better comes up.

All right, so my googles are dirty!
http://users.bestweb.net/~ctips/
He recomends something like
((void) 0, a) = 3;
For which gcc also needs -pedantic before giving a warning instead of
an error with your cast to type trick.
Any other idea?
Tobias.
 
S

Stefan Ram

Tobias Oed said:
In order to debug the thing I'd like to modify these macors so
they can only be used as rvalues and not as lvalues.

You might cast them to their type. (A cast does not yield an
lvalue.)
 
H

Hallvard B Furuseth

Tobias said:
#define POSITION(mw,row) (mw.positions[row])
In order to debug the thing I'd like to modify these macors so they
can only be used as rvalues and not as lvalues.

#define RVALUE(x) ((x)+0)
#define POSITION(mw,row) RVALUE(mw.positions[row])

Or you could just sprinkle '+0' around your macros instead of using an
RVALUE macro, but then someone who reads the code later might wonder why
you have been doing so.
 
J

Jack Klein

True. But my compiler (gcc) requires special options (-pedantic) before
the following fails

int main(void){

int a;
(int) a = 3;

return 0;
}

If possible, I'd like to avoid that. Also, I'd have to be carefull
modifying all these macros not to screw up somewhere between an int
and short, and I'm no good at that kind of manual labour.
A while back there was a discussion here (or was it fclc?) about
web pages exposing exteme measures for defensive programming. One
part of it was the above. At the time I thought the author was insane.
Now that's just about what I need but google doesn't turn up anything...
I'll try the cast for select macros until something better comes up.
Thanks, Tobias.

Perhaps something like:

#define POSITION(mw,row) (mw.positions[row] + 0)

?
 
R

Rob Thorpe

Tobias Oed said:
Hi all, It's been a while!
I'm working on a very buggy piece of code that uses a lot of macros.
A bunch of them look like
#define POSITION(mw,row) (mw.positions[row])
In order to debug the thing I'd like to modify these macors so they can only be
used as rvalues and not as lvalues. If they are used as lvalues I want my
compililation to fail. Unfortunately I can't remember a nice way to do that.
As always thanks for the help!
Tobias.

Maybe remove the macros if you can. It should be fairly quick to do
so by searching for "POSITION" etc. If the code looks clearer with
the macros removed, then leave them out.
 
K

Keith Thompson

Tobias Oed said:
Hi all, It's been a while!
I'm working on a very buggy piece of code that uses a lot of macros.
A bunch of them look like
#define POSITION(mw,row) (mw.positions[row])
In order to debug the thing I'd like to modify these macors so they
can only be used as rvalues and not as lvalues. If they are used as
lvalues I want my compililation to fail. Unfortunately I can't
remember a nice way to do that.

Assuming the result is numeric, I think this will work.

#define POSITION(mw,row) (+mw.positions[row])

I usually prefer to enclose all reference to macro arguments in
parentheses to avoid operator precedence problems, but I don't *think*
it's necessary in this case (though it won't hurt to do it anyway).
 
C

Christopher Benson-Manica

Keith Thompson said:
#define POSITION(mw,row) (+mw.positions[row])
I usually prefer to enclose all reference to macro arguments in
parentheses to avoid operator precedence problems, but I don't *think*
it's necessary in this case (though it won't hurt to do it anyway).

It is necessary, I believe:

mynum=my_num+POSITION(a,b);

The parentheses are necessary for the above line to compile (assuming
all variables are correctly declared, of course).
 
E

Eric Sosman

Tobias said:
Hi all, It's been a while!
I'm working on a very buggy piece of code that uses a lot of macros.
A bunch of them look like
#define POSITION(mw,row) (mw.positions[row])
In order to debug the thing I'd like to modify these macors so they can only be
used as rvalues and not as lvalues. If they are used as lvalues I want my
compililation to fail. Unfortunately I can't remember a nice way to do that.
As always thanks for the help!
Tobias.

#define POSITION(mw,row) (0 , mw.positions[row])

Works for numeric and for non-numeric types.
 
K

Keith Thompson

Christopher Benson-Manica said:
Keith Thompson said:
#define POSITION(mw,row) (+mw.positions[row])
I usually prefer to enclose all reference to macro arguments in
parentheses to avoid operator precedence problems, but I don't *think*
it's necessary in this case (though it won't hurt to do it anyway).

It is necessary, I believe:

mynum=my_num+POSITION(a,b);

The parentheses are necessary for the above line to compile (assuming
all variables are correctly declared, of course).

(I hope you didn't really intend to use the identifiers "mynum" and
"my_num" in the same expression. :cool:})

The outer parentheses surrounding the entire macro definition are
necessary (and the original version of the macro had them). I was
referring to parentheses around each parameter reference within the
macro definition:

#define POSITION(mw,row) (+(mw).positions[(row)])

I'm fairly sure that the parentheses around row are unnecessary, since
it's already immediately surrounded by square brackets. I'm less
certain about the parentheses surrounding mw; I can't think of any
possible problems, but I could be missing something.

I would probably add the parentheses if I were writing this myself,
but this is a borderline case.

Here's a case where the lack of parentheses causes real problems;
it prints "6 * 9 = 42":

#include <stdio.h>

#define SIX 1+5
#define NINE 8+1

int main(void)
{
printf("%d * %d = %d\n", SIX, NINE, SIX * NINE);
return 0;
}
 
C

Chris Torek

The outer parentheses surrounding the entire macro definition are
necessary (and the original version of the macro had them). I was
referring to parentheses around each parameter reference within the
macro definition:

#define POSITION(mw,row) (+(mw).positions[(row)])

I'm fairly sure that the parentheses around row are unnecessary, since
it's already immediately surrounded by square brackets. I'm less
certain about the parentheses surrounding mw; I can't think of any
possible problems, but I could be missing something.

There is one case where they are required.

For any such macro to work, the macro parameter "mw" must name a
structure object that has a "positions" field. This field is either
an array of size N, or a pointer that points to the first of N
sequential elements.

Suppose we redefine the macro as just:

#define POSITION(mw, row) (+mw.positions[row])

Typically this might be used as:

struct S var;

... POSITION(var, k) ...

which works as desired. The macro expands to:

(+var.positions[k])

which parses as "access the k'th element of the array or pointer
named via the positions member of the variable `var', then apply
the unary + operator". But suppose instead we have a pointer,
e.g.:

struct S *ptr = ...;

... POSITION(*ptr, k) ...

In this case, the version without parentheses expands to:

(+*ptr.positions[k])

which parses the same as:

(+(*(ptr.positions[k])))

This attempts to apply the unary "*" and binary "." operators
to the wrong operands.

Parenthesizing "mw" in the expansion gives, instead:

(+(*ptr).positions[k])

which now applies unary "*" to "ptr" as desired, and binary "."
to the structure found via *ptr.

The parentheses around "row" are in fact unnecessary. (A good
proof requires exhaustive enumeration, but a hand-wavey version
simply notes that the square brackets function identically to
parentheses, provided the expression in "row" is syntactically
legal to begin with. Writing POSITION(*ptr,]) causes problems,
but these problems are not fixable via parentheses.)
 
P

Peter Pichler

Keith Thompson said:
The outer parentheses surrounding the entire macro definition are
necessary (and the original version of the macro had them). I was
referring to parentheses around each parameter reference within the
macro definition:

#define POSITION(mw,row) (+(mw).positions[(row)])

I'm fairly sure that the parentheses around row are unnecessary, since
it's already immediately surrounded by square brackets. I'm less
certain about the parentheses surrounding mw; I can't think of any
possible problems, but I could be missing something.

x = POSITION(*pmv, row);

Peter
 
T

Tobias Oed

Thanks for all the replies! I'll go with Jack's/Hallvard's idea:

#define RVALUE(x) ((x)+0)
#define POSITION(mw,row) RVALUE(mw.positions[row])

as it fit my purpose best.
Tobias.
 

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

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top