Question from "The Standard C Library" - create a program with this

Discussion in 'C Programming' started by John Reye, Apr 29, 2012.

  1. John Reye

    John Reye Guest

    Hello,

    Exercise 0.2 (page 16) from "The Standard C Library" is:
    Create a program which contains this line
    x : ((struct x *)x)->x = x(5);

    An "easy" solution is given right at the bottom; but that is not the
    main focus here...



    I am interested in a solution where the ":"
    is part of an inline if... () ? :

    Thus the line will occur like this:
    ?
    x : ((struct x *)x)->x = x(5);


    Here is my attempt:

    #include <stdio.h>
    #include <stdlib.h>

    struct y
    {
    struct y *num;
    int a;
    };

    struct x
    {
    struct y *x;
    };

    #define x(num) (&(struct y){NULL, (num)})

    int main(void)
    {
    int i;
    struct y *tmp;
    struct y *x = &(struct y) {&(struct y) {NULL, 2}, 1};
    x = x(5);
    ((struct x *)x)->x = x(5);
    for (i = 0; i < 2; ++i) {
    tmp = i ?
    x : ((struct x *)x)->x = x(5);
    printf("%d\n", tmp->num->a);
    }
    return EXIT_SUCCESS;
    }


    The compiler (gcc) complains:
    almost.c:30:31: error: lvalue required as left operand of assignment

    I find this rather strange, since the following lines from above,
    compile without error:
    x = x(5);
    ((struct x *)x)->x = x(5);

    How can one fix the compiler error????


    Not even this works:
    tmp = ((struct y*)(i ?
    x : ((struct x *)x)->x) = x(5));

    As an aside... Ironically if I dereference the inline if, then the
    following compiles without problem:
    *tmp = *(i ?
    x : ((struct x *)x)->x) = *x(5);



    My question:
    1) Can one fix my above attempt, that results in the compiler error?
    2) Can one have this line in a valid C program, as part of an inline-
    if
    /*... */ ? /*... */
    x : ((struct x *)x)->x = x(5);

    Thanks.





    "Easy" solution:

    #include <stdio.h>
    #include <stdlib.h>

    struct y
    {
    struct y *num;
    int a;
    };

    struct x
    {
    struct y *x;
    };

    #define x(num) (&(struct y){NULL, (num)})

    int main(void)
    {
    int i;
    struct y *tmp;
    struct y *x = &(struct y) {&(struct y) {NULL, 2}, 1};
    // x is a goto-label
    x : ((struct x *)x)->x = x(5);
    printf("%d\n", x->num->a);
    return EXIT_SUCCESS;
    }
     
    John Reye, Apr 29, 2012
    #1
    1. Advertising

  2. John Reye

    Nobody Guest

    Re: Question from "The Standard C Library" - create a program with this line: x : ((struct x *)x)->x = x(5);

    On Sun, 29 Apr 2012 13:18:22 -0700, John Reye wrote:

    > Exercise 0.2 (page 16) from "The Standard C Library" is:
    > Create a program which contains this line
    > x : ((struct x *)x)->x = x(5);
    >
    > An "easy" solution is given right at the bottom; but that is not the
    > main focus here...
    >
    >
    >
    > I am interested in a solution where the ":"
    > is part of an inline if... () ? :
    >
    > Thus the line will occur like this:
    > ?
    > x : ((struct x *)x)->x = x(5);


    1. The LHS of an assignment must be an lvalue.
    2. a?b:c is not an lvalue, even if b and c are lvalues.
    3. ?: has higher precedence than =, so a?b:c=d is parsed as (a?b:c)=d
    rather than as a?b:(c=d).

    > 2) Can one have this line in a valid C program, as part of an inline-
    > if
    > /*... */ ? /*... */
    > x : ((struct x *)x)->x = x(5);


    No.
     
    Nobody, Apr 29, 2012
    #2
    1. Advertising

  3. John Reye

    Old Wolf Guest

    Re: Question from "The Standard C Library" - create a program with

    On Apr 30, 8:50 am, Nobody <> wrote:
    > > 2) Can one have this line in a valid C program, as part of an inline-
    > > if
    > > /*... */  ? /*... */
    > >    x : ((struct x *)x)->x = x(5);

    >
    > No.


    What is this then:

    struct x { int x; };
    #define x(N) N

    int main()
    {
    struct x y, *x = &y;
    x : ((struct x *)x)->x = x(5);
    return 0;
    }

    I am also suspicious of OP's x(5), is a
    struct literal addressable?
     
    Old Wolf, Apr 30, 2012
    #3
  4. John Reye

    James Kuyper Guest

    Re: Question from "The Standard C Library" - create a program with

    On 04/29/2012 09:11 PM, Old Wolf wrote:
    > On Apr 30, 8:50�am, Nobody <> wrote:
    >>> 2) Can one have this line in a valid C program, as part of an inline-
    >>> if
    >>> /*... */ �? /*... */
    >>> � �x : ((struct x *)x)->x = x(5);

    >>
    >> No.

    >
    > What is this then:


    It is something that is not "part of an inline-if", by which the OP
    apparently means an expression containing a conditional operator.

    > struct x { int x; };
    > #define x(N) N
    >
    > int main()
    > {
    > struct x y, *x = &y;
    > x : ((struct x *)x)->x = x(5);
    > return 0;
    > }
    >
    > I am also suspicious of OP's x(5), is a
    > struct literal addressable?


    6.5.2.5p10 contains Example 3 of compound literals:
    > drawline(&(struct point){.x=1, .y=1},
    > &(struct point){.x=3, .y=4});


    so I would say that the answer is "yes".
    --
    James Kuyper
     
    James Kuyper, Apr 30, 2012
    #4
  5. John Reye

    John Reye Guest

    Re: Question from "The Standard C Library" - create a program with

    Thanks for the helpful replies

    I wrote
    > As an aside... Ironically if I dereference the inline if, then the
    > following compiles without problem:
    >     *tmp = *(i ?
    >              x : ((struct x *)x)->x) = *x(5);


    This code is not nice, since tmp does not point to any allocated
    memory.

    But why does the above code work... but I not able to do this:
    tmp = &(*(i ?
    x : ((struct x *)x)->x) = *x(5));

    Error-message from gcc:
    almost.c:23:11: error: lvalue required as unary ‘&’ operand

    (All I did was add the & operator.)

    Does this mean that dereferencing an address, does non necessarily
    yield an lvalue??
    Surely I must have an lvalue above, because I can see that I have
    storage that is either located at address x, or address x->x

    Thanks.
     
    John Reye, Apr 30, 2012
    #5
  6. John Reye

    John Reye Guest

    Re: Question from "The Standard C Library" - create a program with

    On Apr 30, 9:31 am, John Reye wrote:
    > But why does the above code work... but I not able to do this:
    >     tmp = &(*(i ?
    >              x : ((struct x *)x)->x) = *x(5));
    >
    > Error-message from gcc:
    > almost.c:23:11: error: lvalue required as unary ‘&’ operand
    >
    > (All I did was add the & operator.)


    The problem is that the unary address operator &, never yields an
    lvalue.


    > Does this mean that dereferencing an address, does non necessarily
    > yield an lvalue??

    Dereferencing an address (e.g. *x) does yield an lvalue, but taking
    the unary address operator &, never yields an lvalue.
    &(*x) is not a lvalue.
     
    John Reye, May 1, 2012
    #6
  7. John Reye

    James Kuyper Guest

    Re: Question from "The Standard C Library" - create a program with

    On 05/01/2012 08:25 AM, John Reye wrote:
    > On Apr 30, 9:31�am, John Reye wrote:
    >> But why does the above code work... but I not able to do this:
    >> � � tmp = &(*(i ?
    >> � � � � � � �x : ((struct x *)x)->x) = *x(5));
    >>
    >> Error-message from gcc:
    >> almost.c:23:11: error: lvalue required as unary �&� operand
    >>
    >> (All I did was add the & operator.)

    >
    > The problem is that the unary address operator &, never yields an
    > lvalue.


    While you're correct about the what unary & yields, that doesn't explain
    the problem. The error message is complaining about the operand of unary
    &, not what it yields.

    I've avoided commenting on this question because, while it looks to me
    like your code should be valid, I wasn't willing to swear to that. But
    if it does contain a problem, the one you've identified isn't it.
    --
    James Kuyper
     
    James Kuyper, May 1, 2012
    #7
  8. John Reye

    James Kuyper Guest

    Re: Question from "The Standard C Library" - create a program with

    On 05/01/2012 08:25 AM, John Reye wrote:
    > On Apr 30, 9:31�am, John Reye wrote:
    >> But why does the above code work... but I not able to do this:
    >> � � tmp = &(*(i ?
    >> � � � � � � �x : ((struct x *)x)->x) = *x(5));
    >>
    >> Error-message from gcc:
    >> almost.c:23:11: error: lvalue required as unary �&� operand
    >>
    >> (All I did was add the & operator.)

    >
    > The problem is that the unary address operator &, never yields an
    > lvalue.


    While you're correct about the what unary & yields, that doesn't explain
    the problem. The error message is complaining about the operand of unary
    &, not what it yields.

    I've avoided commenting on this question because, while it looks to me
    like your code should be valid, I wasn't willing to swear to that. But
    if it does contain a problem, the one you've identified isn't it.
    --
    James Kuyper
     
    James Kuyper, May 1, 2012
    #8
  9. John Reye

    John Reye Guest

    Re: Question from "The Standard C Library" - create a program with

    On May 1, 4:12 pm, James Kuyper wrote:
    > On 05/01/2012 08:25 AM, John Reye wrote:
    >
    > > On Apr 30, 9:31 am, John Reye wrote:
    > >> But why does the above code work... but I not able to do this:
    > >> tmp = &(*(i ?
    > >> x : ((struct x *)x)->x) = *x(5));

    >
    > >> Error-message from gcc:
    > >> almost.c:23:11: error: lvalue required as unary & operand

    >
    > >> (All I did was add the & operator.)

    >
    > > The problem is that the unary address operator &, never yields an
    > > lvalue.

    >
    > While you're correct about the what unary & yields, that doesn't explain
    > the problem. The error message is complaining about the operand of unary
    > &, not what it yields.


    Ah yes of course! You're right! Thanks.


    The real problem above is that an assignment does not yield an lvalue.
    Assignment is right associative, and yields the result rvalue at the
    right-hand side of the =.


    Example:

    int main(void)
    {
    int* a, *b, *c;
    a = &(*b); // ok
    a = &(*b = *c); // gcc compilation error: lvalue required as
    unary ‘&’ operand
    return 0;
    }
     
    John Reye, May 1, 2012
    #9
    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. PHP2
    Replies:
    2
    Views:
    419
    ¾ç¼¼ÈÆ
    Apr 29, 2004
  2. Jason Heyes
    Replies:
    1
    Views:
    6,850
    Jaspreet
    Jun 15, 2005
  3. Standard C library functions

    , Aug 3, 2005, in forum: C Programming
    Replies:
    6
    Views:
    389
  4. ruoqingmm
    Replies:
    9
    Views:
    5,335
    Rod Pemberton
    Apr 28, 2006
  5. The Grue - James T. Sprinkle

    Source Code to Plauger's "Standard C Library"

    The Grue - James T. Sprinkle, May 10, 2006, in forum: C Programming
    Replies:
    4
    Views:
    825
    The Grue - James T. Sprinkle
    May 10, 2006
Loading...

Share This Page