rvalue

Discussion in 'C Programming' started by Tobias Oed, Apr 9, 2004.

  1. Tobias Oed

    Tobias Oed Guest

    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.
     
    Tobias Oed, Apr 9, 2004
    #1
    1. Advertising

  2. Tobias Oed

    Tobias Oed Guest

    Stefan Ram wrote:

    > Tobias Oed <> writes:
    >>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.)


    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.
     
    Tobias Oed, Apr 9, 2004
    #2
    1. Advertising

  3. Tobias Oed

    Tobias Oed Guest

    Tobias Oed wrote:

    > Stefan Ram wrote:
    >
    >> Tobias Oed <> writes:
    >>>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.)

    >
    > 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.
     
    Tobias Oed, Apr 9, 2004
    #3
  4. Tobias Oed

    Stefan Ram Guest

    Tobias Oed <> writes:
    >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.)
     
    Stefan Ram, Apr 9, 2004
    #4
  5. Tobias Oed wrote:

    > #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.

    --
    Hallvard
     
    Hallvard B Furuseth, Apr 9, 2004
    #5
  6. Tobias Oed

    Jack Klein Guest

    On Thu, 08 Apr 2004 22:18:00 -0400, Tobias Oed
    <> wrote in comp.lang.c:

    > Stefan Ram wrote:
    >
    > > Tobias Oed <> writes:
    > >>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.)

    >
    > 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)

    ?

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Apr 9, 2004
    #6
  7. Tobias Oed

    Rob Thorpe Guest

    Tobias Oed <> wrote in message news:<c551gb$2mvd8q$-berlin.de>...
    > 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.
     
    Rob Thorpe, Apr 9, 2004
    #7
  8. Tobias Oed <> writes:
    > 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).

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    Schroedinger does Shakespeare: "To be *and* not to be"
     
    Keith Thompson, Apr 9, 2004
    #8
  9. Keith Thompson <> spoke thus:

    > #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).

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Apr 9, 2004
    #9
  10. Tobias Oed

    Eric Sosman Guest

    Tobias Oed wrote:
    >
    > 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.

    --
     
    Eric Sosman, Apr 9, 2004
    #10
  11. Christopher Benson-Manica <> writes:
    > Keith Thompson <> spoke thus:
    > > #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;
    }

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    Schroedinger does Shakespeare: "To be *and* not to be"
     
    Keith Thompson, Apr 9, 2004
    #11
  12. Tobias Oed

    Chris Torek Guest

    In article <news:>
    Keith Thompson <> writs:
    >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.)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Apr 10, 2004
    #12
  13. "Keith Thompson" <> wrote in message
    > 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
     
    Peter Pichler, Apr 10, 2004
    #13
  14. Tobias Oed

    Tobias Oed Guest

    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.
     
    Tobias Oed, Apr 12, 2004
    #14
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Mantoulidis

    ++x returns lvalue but x++ return rvalue

    Chris Mantoulidis, Dec 28, 2003, in forum: C++
    Replies:
    4
    Views:
    511
    Chris Mantoulidis
    Dec 29, 2003
  2. Gonzalo Aguirre

    rvalue / lvalue operator[]

    Gonzalo Aguirre, Jan 2, 2004, in forum: C++
    Replies:
    4
    Views:
    464
    Ron Natalie
    Jan 2, 2004
  3. Denis Remezov

    lvalue rvalue

    Denis Remezov, Jul 16, 2004, in forum: C++
    Replies:
    12
    Views:
    895
  4. Kavya
    Replies:
    9
    Views:
    541
    Dik T. Winter
    Oct 28, 2006
  5. Juha Nieminen
    Replies:
    13
    Views:
    652
    Edek Pienkowski
    Aug 29, 2012
Loading...

Share This Page