using a method as an lvalue and "invalid lvalue in assignment"compilation error

Discussion in 'C Programming' started by markryde@gmail.com, Sep 8, 2008.

  1. Guest

    Hello,
    Followed here is a simplified code example of something which I
    try to implement; in essence , I want to assign a value to a return
    value of a method is C. I know, of course, that in this example I
    can
    get this by newskb->iph = iphdr (this also appears in a commented
    line in the example below) ; but I want to achieve the same where
    the left side is : ip_hdr(newskb). Alas, if I try this , I get
    a compilation error about line 25.
    line 25 is:
    ip_hdr(newskb)=iphdr;
    the error I get is:
    lval.c:25: error: invalid lvalue in assignment
    I use gcc-4.1.2-33c, and I compile without any flag.

    I tried casting,
    like : (struct iphdr*)ip_hdr(newskb)=iphdr;
    or like:
    ip_hdr(newskb)=(struct iphdr*)iphdr;
    and got the same error.
    Any ideas?
    Regards,
    Mark
     
    , Sep 8, 2008
    #1
    1. Advertising

  2. Guest

    On 8 Sep, 19:25, "" <> wrote:
    > Hello,
    >   Followed here is a simplified code example of something which I
    >         try to implement; in essence , I want to assign a value to a return
    >         value of a method is C. I know, of course, that in this example I
    > can
    >         get this by newskb->iph = iphdr (this also appears in a commented
    >         line in the example below) ; but I want to achieve the same where
    >         the left side is : ip_hdr(newskb). Alas, if I try this , I get
    >         a compilation error about line 25.
    >         line 25 is:
    >           ip_hdr(newskb)=iphdr;
    >         the error I get is:
    >         lval.c:25: error: invalid lvalue in assignment
    >         I use gcc-4.1.2-33c, and I compile without any flag.
    >
    >         I tried casting,
    >         like : (struct iphdr*)ip_hdr(newskb)=iphdr;
    >         or like:
    >         ip_hdr(newskb)=(struct iphdr*)iphdr;
    >         and got the same error.
    >         Any ideas?
    >         Regards,
    >         Mark


    Could you explain what you're actually trying to do here?

    If ip_hdr is a function that takes one value in and returns one value
    out, then ip_hdr(newskb) will run the function and give a result. For
    some reason, you seem to want a different result. Do you want the
    ip_hdr function to run, or not? What are you going to do with (a) the
    result it actually gives, and (b) the result that you appear to want
    it to give?

    If you want a different result to come out of the function, you
    probably need to alter the function and get it to return the desired
    result. Eg by putting "return iphdr;" into it. Alternatively, do
    something like:

    if (someflag)
    { result = iphdr; }
    else
    { result = ip_hdr(newskb); }

    Hope that helps.
    Paul.
     
    , Sep 8, 2008
    #2
    1. Advertising

  3. Re: using a method as an lvalue and "invalid lvalue in assignment" compilation error

    "" <> writes:
    > Followed here is a simplified code example of something which I
    > try to implement; in essence , I want to assign a value to a return
    > value of a method is C. I know, of course, that in this example I
    > can
    > get this by newskb->iph = iphdr (this also appears in a commented
    > line in the example below) ; but I want to achieve the same where
    > the left side is : ip_hdr(newskb). Alas, if I try this , I get
    > a compilation error about line 25.
    > line 25 is:
    > ip_hdr(newskb)=iphdr;
    > the error I get is:
    > lval.c:25: error: invalid lvalue in assignment
    > I use gcc-4.1.2-33c, and I compile without any flag.
    >
    > I tried casting,
    > like : (struct iphdr*)ip_hdr(newskb)=iphdr;
    > or like:
    > ip_hdr(newskb)=(struct iphdr*)iphdr;
    > and got the same error.
    > Any ideas?


    C doesn't have "methods". If you really want to ask about methods,
    you probably want comp.lang.c++ (<OT>the C++ standard refers to them
    as member functions, but it's common to refer to them as methods
    anyway</OT>).

    The result of a function call is not an lvalue. For example, an
    attempt to set the square root of 2.0 to 1.5:

    sqrt(2.0) = 1.5; /* illegal */

    cannot succeed.

    If a function returns a pointer value, dereferencing that value does
    yield an lvalue. For example:

    #include <stdio.h>

    int obj = 0;

    int *func(void)
    {
    return &obj;
    }

    int main(void)
    {
    *(func()) = 42;
    printf("obj = %d\n", obj);
    return 0;
    }

    (The extra parentheses are for clarity; they're not strictly
    necessary.)

    You'll have to exercise the usual care about the lifetime of the
    object to which the result points; for example, returning a pointer to
    a local object is bad.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 8, 2008
    #3
  4. Guest

    wrote:
    > Hello,
    > Followed here is a simplified code example of something which I
    > try to implement; in essence , I want to assign a value to a return
    > value of a method is C.


    It is possible in C++ to use the value returned by a function call as
    the left operand of an assignment operator; this is not possible in
    C.

    So, are you programming in C or in C++? Your use of the term "method"
    makes me think you're using C++ - neither language actually uses the
    term "method", but it is in common use to describe what C++ call
    member functions; something that doesn't exist in C.

    C and and C++ are two significantly different languages. If your
    question is actually about C++, then this is the wrong newsgroup. You
    should go to comp.lang.c++. There will be a much larger number of
    people there who are competent to answer your question.

    > ... I know, of course, that in this example I
    > can
    > get this by newskb->iph = iphdr (this also appears in a commented
    > line in the example below) ; but I want to achieve the same where
    > the left side is : ip_hdr(newskb). Alas, if I try this , I get
    > a compilation error about line 25.
    > line 25 is:
    > ip_hdr(newskb)=iphdr;
    > the error I get is:
    > lval.c:25: error: invalid lvalue in assignment
    > I use gcc-4.1.2-33c, and I compile without any flag.
    >
    > I tried casting,
    > like : (struct iphdr*)ip_hdr(newskb)=iphdr;
    > or like:
    > ip_hdr(newskb)=(struct iphdr*)iphdr;
    > and got the same error.
    > Any ideas?


    Yes - I've got the idea that you have no concept of the kind of
    information that is needed to answer your question. You should provide
    the following information:

    What is the definition of ip_hdr()? How is it related to iphdr? What
    is newskb? And what in the world are you actually trying to do?

    If you are writing in C++, the existence of a "struct iphdr"
    declaration somewhere in your code makes "iphdr" a type name. In all
    three statements you've provided, the final use of 'iphdr' is in a
    context where a type name is not allowed. This makes it very unclear
    what it is that you're actually trying to do. If you're writing in C,
    iphdr is not necessarily a type name - you're allowed to define a
    variable with the same name, but it's not a good idea to actually do
    so.

    I would strongly recommend creating a complete program, as small as
    possible, that actually demonstrates what it is that you're trying to
    do. Compile it, and then post the COMPLETE TEXT of the program, and
    the COMPLETE TEXT of the compiler's error messages. Please make sure
    that you post it to the appropriate newsgroup.
     
    , Sep 8, 2008
    #4
  5. viza Guest

    On Mon, 08 Sep 2008 11:25:37 -0700, wrote:
    > ip_hdr(newskb)=iphdr;


    short answer: I guess you mean:

    *(ip_hdr(newskb))= iphdr;

    but it could be anything because you didn't include the code.


    Also, please don't use tabs. This is really ugly:

    > try to implement; in essence , I want to assign a value to a

    return
    > value of a method is C. I know, of course, that in this example I
    > can
    > get this by newskb->iph = iphdr (this also appears in a commented

    line
    > in the example below) ; but I want to achieve the same where the

    left
    > side is : ip_hdr(newskb). Alas, if I try this , I get a
     
    viza, Sep 8, 2008
    #5
  6. Guest

    Hello,
    First, thanks a lot for you (and the others who replied to
    my question).
    Second, I simply forgot to insert the little program I already wrote
    into my post. Sorry about it. Here it is:
    // lval.c
    #include <stdlib.h>

    struct iphdr
    {
    int i;
    };


    struct sk_buff
    {
    struct iphdr *iph;
    };



    struct iphdr* ip_hdr(struct sk_buff *skb)
    {
    return skb->iph;
    };

    int main()
    {
    struct iphdr* iphdr = malloc(sizeof (struct iphdr));
    struct sk_buff *newskb = malloc(sizeof (struct sk_buff));
    ip_hdr(newskb)=iphdr;
    }


    compiling this program gives:
    lval.c: In function ‘main’:
    lval.c:26: error: lvalue required as left operand of assignment

    where line 26 is:
    ip_hdr(newskb)=iphdr;

    And I am talking (solely) about "C", not C++.

    Regards,
    Mark

    On Sep 8, 10:24 pm, wrote:
    > wrote:
    > > Hello,
    > >   Followed here is a simplified code example of something which I
    > >    try to implement; in essence , I want to assign a value to a return
    > >    value of a method is C.

    >
    > It is possible in C++ to use the value returned by a function call as
    > the left operand of an assignment operator; this is not possible in
    > C.
    >
    > So, are you programming in C or in C++? Your use of the term "method"
    > makes me think you're using C++ - neither language actually uses the
    > term "method", but it is in common use to describe what C++ call
    > member functions; something that doesn't exist in C.
    >
    > C and and C++  are two significantly different languages. If your
    > question is actually about C++, then this is the wrong newsgroup. You
    > should go to comp.lang.c++. There will be a much larger number of
    > people there who are competent to answer your question.
    >
    >
    >
    > > ... I know, of course, that in this example I
    > > can
    > >    get this by newskb->iph = iphdr (this also appears in a commented
    > >    line in the example below) ; but I want to achieve the same where
    > >    the left side is : ip_hdr(newskb). Alas, if I try this , I get
    > >    a compilation error about line 25.
    > >    line 25 is:
    > >      ip_hdr(newskb)=iphdr;
    > >    the error I get is:
    > >    lval.c:25: error: invalid lvalue in assignment
    > >    I use gcc-4.1.2-33c, and I compile without any flag.

    >
    > >    I tried casting,
    > >    like : (struct iphdr*)ip_hdr(newskb)=iphdr;
    > >    or like:
    > >    ip_hdr(newskb)=(struct iphdr*)iphdr;
    > >    and got the same error.
    > >    Any ideas?

    >
    > Yes - I've got the idea that you have no concept of the kind of
    > information that is needed to answer your question. You should provide
    > the following information:
    >
    > What is the definition of ip_hdr()? How is it related to iphdr? What
    > is newskb? And what in the world are you actually trying to do?
    >
    > If you are writing in C++, the existence of a "struct iphdr"
    > declaration somewhere in your code makes "iphdr" a type name. In all
    > three statements you've provided, the final use of 'iphdr' is in a
    > context where a type name is not allowed. This makes it very unclear
    > what it is that you're actually trying to do. If you're writing in C,
    > iphdr is not necessarily a type name - you're allowed to define a
    > variable with the same name, but it's not a good idea  to actually do
    > so.
    >
    > I would strongly recommend creating a complete program, as small as
    > possible, that actually demonstrates what it is that you're trying to
    > do. Compile it, and then post the COMPLETE TEXT of the program, and
    > the COMPLETE TEXT of the compiler's error messages. Please make sure
    > that you post it to the appropriate newsgroup.
     
    , Sep 9, 2008
    #6
  7. Guest

    Hello,
    Would it be correct to do it thus:
    *(ip_hdr(newskb))=*iphdr;

    this compiles OK.

    Regards,
    Mark







    On Sep 9, 8:41 am, "" <> wrote:
    > Hello,
    > First, thanks a lot for you (and the others who replied to
    > my question).
    > Second, I simply forgot to insert the little program I already wrote
    > into my post. Sorry about it. Here it is:
    > // lval.c
    > #include <stdlib.h>
    >
    > struct iphdr
    > {
    >         int i;
    >
    > };
    >
    > struct sk_buff
    > {
    >   struct iphdr *iph;
    >
    > };
    >
    > struct iphdr* ip_hdr(struct sk_buff *skb)
    > {
    >         return skb->iph;
    >
    > };
    >
    > int main()
    > {
    > struct iphdr* iphdr    = malloc(sizeof (struct iphdr));
    > struct sk_buff *newskb = malloc(sizeof (struct sk_buff));
    > ip_hdr(newskb)=iphdr;
    >
    > }
    >
    > compiling this program gives:
    > lval.c: In function ‘main’:
    > lval.c:26: error: lvalue required as left operand of assignment
    >
    > where line 26 is:
    > ip_hdr(newskb)=iphdr;
    >
    > And I am talking (solely) about "C", not C++.
    >
    > Regards,
    > Mark
    >
    > On Sep 8, 10:24 pm, wrote:
    >
    > > wrote:
    > > > Hello,
    > > >   Followed here is a simplified code example of something which I
    > > >    try to implement; in essence , I want to assign a value to a return
    > > >    value of a method is C.

    >
    > > It is possible in C++ to use the value returned by a function call as
    > > the left operand of an assignment operator; this is not possible in
    > > C.

    >
    > > So, are you programming in C or in C++? Your use of the term "method"
    > > makes me think you're using C++ - neither language actually uses the
    > > term "method", but it is in common use to describe what C++ call
    > > member functions; something that doesn't exist in C.

    >
    > > C and and C++  are two significantly different languages. If your
    > > question is actually about C++, then this is the wrong newsgroup. You
    > > should go to comp.lang.c++. There will be a much larger number of
    > > people there who are competent to answer your question.

    >
    > > > ... I know, of course, that in this example I
    > > > can
    > > >    get this by newskb->iph = iphdr (this also appears in a commented
    > > >    line in the example below) ; but I want to achieve the same where
    > > >    the left side is : ip_hdr(newskb). Alas, if I try this , I get
    > > >    a compilation error about line 25.
    > > >    line 25 is:
    > > >      ip_hdr(newskb)=iphdr;
    > > >    the error I get is:
    > > >    lval.c:25: error: invalid lvalue in assignment
    > > >    I use gcc-4.1.2-33c, and I compile without any flag.

    >
    > > >    I tried casting,
    > > >    like : (struct iphdr*)ip_hdr(newskb)=iphdr;
    > > >    or like:
    > > >    ip_hdr(newskb)=(struct iphdr*)iphdr;
    > > >    and got the same error.
    > > >    Any ideas?

    >
    > > Yes - I've got the idea that you have no concept of the kind of
    > > information that is needed to answer your question. You should provide
    > > the following information:

    >
    > > What is the definition of ip_hdr()? How is it related to iphdr? What
    > > is newskb? And what in the world are you actually trying to do?

    >
    > > If you are writing in C++, the existence of a "struct iphdr"
    > > declaration somewhere in your code makes "iphdr" a type name. In all
    > > three statements you've provided, the final use of 'iphdr' is in a
    > > context where a type name is not allowed. This makes it very unclear
    > > what it is that you're actually trying to do. If you're writing in C,
    > > iphdr is not necessarily a type name - you're allowed to define a
    > > variable with the same name, but it's not a good idea  to actually do
    > > so.

    >
    > > I would strongly recommend creating a complete program, as small as
    > > possible, that actually demonstrates what it is that you're trying to
    > > do. Compile it, and then post the COMPLETE TEXT of the program, and
    > > the COMPLETE TEXT of the compiler's error messages. Please make sure
    > > that you post it to the appropriate newsgroup.

    >
    >
     
    , Sep 9, 2008
    #7
  8. wrote:
    > Hello,
    > First, thanks a lot for you (and the others who replied to
    > my question).
    > Second, I simply forgot to insert the little program I already wrote
    > into my post. Sorry about it. Here it is:


    Look over the following rewrite and see whether it does what you want.
    There may be further gotchas in it to be fixed.

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

    struct iphdr
    {
    int i;
    };


    struct sk_buff
    {
    struct iphdr *iph;
    };


    /* note changes */
    struct iphdr **ip_hdr(struct sk_buff *skb)
    {
    return &(skb->iph);
    }

    /* removed stray ';' */

    int main(void)
    {
    struct iphdr *iphdr = malloc(sizeof *iphdr);
    struct sk_buff *newskb = malloc(sizeof *newskb);
    if (!iphdr || !newskb) {
    fprintf(stderr, "At least one allocation attempt failed,\n"
    "Giving up.\n");
    free(iphdr);
    free(newskb);
    exit(EXIT_FAILURE);
    }
    *ip_hdr(newskb) = iphdr; /* note change */
    free(iphdr);
    free(newskb);
    return 0;
    }
     
    Martin Ambuhl, Sep 9, 2008
    #8
  9. CBFalconer Guest

    "" wrote:
    >
    > First, thanks a lot for you (and the others who replied to my
    > question). Second, I simply forgot to insert the little program
    > I already wrote into my post. Sorry about it. Here it is:


    Please do not top-post. Your answer belongs after (or intermixed
    with) the quoted material to which you reply, after snipping all
    irrelevant material. See the following links:

    <http://www.catb.org/~esr/faqs/smart-questions.html>
    <http://www.caliburn.nl/topposting.html>
    <http://www.netmeister.org/news/learn2quote.html>
    <http://cfaj.freeshell.org/google/> (taming google)
    <http://members.fortunecity.com/nnqweb/> (newusers)

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Sep 9, 2008
    #9
  10. James Kuyper Guest

    wrote:
    > Hello,
    > Would it be correct to do it thus:
    > *(ip_hdr(newskb))=*iphdr;


    No. That has several problems. See below.

    ....
    > On Sep 9, 8:41 am, "" <> wrote:
    >> Hello,
    >> First, thanks a lot for you (and the others who replied to
    >> my question).
    >> Second, I simply forgot to insert the little program I already wrote
    >> into my post. Sorry about it. Here it is:
    >> // lval.c
    >> #include <stdlib.h>
    >>
    >> struct iphdr
    >> {
    >> int i;
    >>
    >> };
    >>
    >> struct sk_buff
    >> {
    >> struct iphdr *iph;
    >>
    >> };
    >>
    >> struct iphdr* ip_hdr(struct sk_buff *skb)
    >> {
    >> return skb->iph;
    >>
    >> };
    >>
    >> int main()
    >> {
    >> struct iphdr* iphdr = malloc(sizeof (struct iphdr));
    >> struct sk_buff *newskb = malloc(sizeof (struct sk_buff));


    Note that at this point, newskb points at an uninitialized sk_buff. This
    means that newskb->iph is an uninitialized pointer. As a result, the
    behavior of ip_hdr(newsk) is undefined.

    I presume that you want your code to have the same effect as if you had
    written

    newskb->iph = iphdr;

    Well, the result of a function call is not an lvalue in C, and therefore
    can never be the left operand of an assignment operator. However,
    *ip_hdr(newskb) is an lvalue; the only problem is that it's an lvalue of
    type iphdr; and at this point no object of type iphdr has yet been
    associated with newskb. What is associated with newskb is an object of
    type "struct iphdr*", so you need to make sure that *ip_hdr(newskb) has
    that type. this means that ip_hdr needs to return a pointer to a pointer:

    struct iphdr** ip_hdr(struct sk_buff *skb)
    {
    return &skb->iph;
    }

    With that definition, you can now write

    *ip_hdr(newskb) = iphdr;
     
    James Kuyper, Sep 9, 2008
    #10
  11. Re: using a method as an lvalue and "invalid lvalue in assignment" compilation error

    On Mon, 8 Sep 2008 12:24:40 -0700 (PDT),
    wrote:
    <snip>
    > So, are you programming in C or in C++? Your use of the term "method"
    > makes me think you're using C++ - neither language actually uses the
    > term "method", but it is in common use to describe what C++ call
    > member functions; something that doesn't exist in C.
    >
    > C and and C++ are two significantly different languages. <snip>


    Concur. (In general; it turns out this OP was writing C.)

    > If you are writing in C++, the existence of a "struct iphdr"
    > declaration somewhere in your code makes "iphdr" a type name. In all
    > three statements you've provided, the final use of 'iphdr' is in a
    > context where a type name is not allowed. This makes it very unclear
    > what it is that you're actually trying to do. If you're writing in C,
    > iphdr is not necessarily a type name - you're allowed to define a
    > variable with the same name, but it's not a good idea to actually do
    > so.
    >

    But this is not a distinguisher. Yes, in C++ and not C a struct/etc
    tag is automatically usable as a typename, but it is still possible to
    (explicitly) declare a variable with the same name. (Whether it's a
    good idea, in either language, is a very different question.)

    - formerly david.thompson1 || achar(64) || worldnet.att.net
     
    David Thompson, Sep 22, 2008
    #11
  12. James Kuyper Guest

    David Thompson wrote:
    > On Mon, 8 Sep 2008 12:24:40 -0700 (PDT),
    > wrote:
    > <snip>
    >> So, are you programming in C or in C++? Your use of the term "method"
    >> makes me think you're using C++ - neither language actually uses the
    >> term "method", but it is in common use to describe what C++ call
    >> member functions; something that doesn't exist in C.
    >>
    >> C and and C++ are two significantly different languages. <snip>

    >
    > Concur. (In general; it turns out this OP was writing C.)
    >
    >> If you are writing in C++, the existence of a "struct iphdr"
    >> declaration somewhere in your code makes "iphdr" a type name. In all
    >> three statements you've provided, the final use of 'iphdr' is in a
    >> context where a type name is not allowed. This makes it very unclear
    >> what it is that you're actually trying to do. If you're writing in C,
    >> iphdr is not necessarily a type name - you're allowed to define a
    >> variable with the same name, but it's not a good idea to actually do
    >> so.
    >>

    > But this is not a distinguisher. Yes, in C++ and not C a struct/etc
    > tag is automatically usable as a typename, but it is still possible to
    > (explicitly) declare a variable with the same name. (Whether it's a
    > good idea, in either language, is a very different question.)


    It was the use of the word "method" that made me wonder whether he was
    talking about C++ code. I was not trying to suggest that those uses of
    such an identifier indicates that this code is C++ code; with a suitable
    declaration it could be legal (but confusing) code in both languages;
    without such a declaration, it's illegal in both languages; I was just
    pointing out that it was illegal in a different way in C++ than in C.
     
    James Kuyper, Sep 22, 2008
    #12
    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. A. Farber
    Replies:
    5
    Views:
    621
    A. Farber
    Oct 6, 2006
  2. Kavya
    Replies:
    9
    Views:
    513
    Dik T. Winter
    Oct 28, 2006
  3. mdh

    invalid lvalue in assignment

    mdh, Oct 28, 2007, in forum: C Programming
    Replies:
    4
    Views:
    363
  4. Chad

    invalid lvalue in assignment

    Chad, Jan 9, 2009, in forum: C Programming
    Replies:
    16
    Views:
    995
    Default User
    Jan 10, 2009
  5. Replies:
    2
    Views:
    1,894
Loading...

Share This Page