Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

C Programming Language

list = list->Next = malloc(sizeof(node));


Given:
#include <stdlib.h>
typedef struct Node {
    unsigned char Data[SIZE];
    struct Node *Next
} node_t, *list_t;

list_t list;

Does
    list = list->Next = malloc(sizeof(node));
cause UB? Is it any different (neglecting style) from
    list->Next = malloc(sizeof(node));
    list = list->Next;
?

In the former, apparently I only write to l itself once, and only
read l to determine what l->next is. So apparently it is OK to do
that within one sequence point. Am I wrong?

"Army1987" <please.@for.it> writes:
> Does
>     list = list->Next = malloc(sizeof(node));
> cause UB? Is it any different (neglecting style) from
>     list->Next = malloc(sizeof(node));
>     list = list->Next;
> ?

We've had several extensive threads on this over the years.  I
started one of them.  I'd suggest trying to find the earlier
discussions instead of starting a new one.
--
Ben Pfaff
http://benpfaff.org
On May 25, 11:39 am, "Army1987" <please.@for.it> wrote:

> In the former, apparently I only write to l itself once, and only
> read l to determine what l->next is. So apparently it is OK to do
> that within one sequence point. Am I wrong?

You are not sure whether your code invokes undefined behavior. It is
trivial to change it so that it will clearly not invoke undefined
behavior. If you don't change it, then yes, you are wrong.
On May 25, 10:39 pm, "Army1987" <please.@for.it> wrote:

> Does
>     list = list->Next = malloc(sizeof(node));
> cause UB?

Yes. 'list' is both written, and read for a purpose
other than to determine the value to be written,
without an intervening sequence point. (That purpose
is for determining the value of list->Next).

Although '=' is right-left associative, that doesn't
mean right-left order of evaluation. The associativity
means that A=B=C is read as A=(B=C) rather than (A=B)=C.
BTW. the latter would always cause undefined behaviour
because A would be written twice without a sequence point.

The code is like:
  void *x = malloc( sizeof(node) );
  list = x, list->Next = x;

except that there is no sequence point where I have
put the comma operator.

So you could end up with the result of malloc having
"->Next" applied to it. (Or any other result, since
this means the behaviour is undefined).

In article <1180313678.936468.323@n15g2000prd.googlegroups.com>,
Old Wolf  <oldw@inspire.net.nz> wrote:

>> Does
>>     list = list->Next = malloc(sizeof(node));
>> cause UB?
>Yes. 'list' is both written, and read for a purpose
>other than to determine the value to be written,
>without an intervening sequence point. (That purpose
>is for determining the value of list->Next).

That's not quite right, because the same is true of

  list = list->Next;

in which list is read to determine the value of list->Next, but that
is done in order to determine the value to be written, so there is no
problem.  The problem with the quoted example is that list is read in
order to determine the *location* to be written in the right-hand
assignment.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc