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

M

markryde

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
 
G

gw7rib

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

Keith Thompson

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

jameskuyper

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

viza

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:
 
M

markryde

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
 
M

markryde

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

this compiles OK.

Regards,
Mark
 
M

Martin Ambuhl

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;
}
 
C

CBFalconer

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

James Kuyper

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

No. That has several problems. See below.

....
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;
 
D

David Thompson

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
 
J

James Kuyper

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

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.
 

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,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top