Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it legal to access a field of a returned union without a variable? [duplicate]

Tags:

c

unions

I have a function returning a union type. Is it allowed by the standard (C99) to access a field of a returned value directly from the call without copying the value to a variable. Here an example to illustrate what I mean:

union thinga { int integ; char arr[4]; };

union thinga f(void)
{
  union thinga t = {.integ = 1};
  return t;
}
int main(void)
{
   printf("thinga is %d\n", f().integ);
}

Is the call with field f().integ allowed? In my example it's a union but the issue is the same for struct. I ask the question, because I remember vividly that gcc 3.3 on Solaris didn't like this construct and would warn like hell. Its problem was that it had to generate internally an invisible variable to be able to access the field of the struct or the union. Newer compilers seem not to mind the construct but I would like to know if there is a hidden catch (i.e. undefined bevaviour that I didn't think of.

EDIT: Ok it looks like my contrived example is a bit too simple and as commenter 2501 noticed by giving links to array decaying to pointer on out of scope objects, let's see if we are in the same situation if I change a bit my code.

 union thinga f(const char *val)
 {
   union thinga t = {.integ = 0};
   t.arr[0] = val[0];
   return t;
 }

 int main(void)
 {
     printf(" thinga.integ=%d .arr=%s\n", f("1").integ, f("1").arr);
 }

is this case the same as given in arrays that are not lvalues and sequence point restriction and Undefined behavior: when attempting to access the result of function call ? (the value returned are obviously impementation dependend (endiannes) but that is not the issue here).

like image 570
Patrick Schlüter Avatar asked Mar 16 '16 15:03

Patrick Schlüter


People also ask

Would you use UNION or UNION all if there were no duplicates?

The main difference between UNION and UNION ALL is that: UNION: only keeps unique records. UNION ALL: keeps all records, including duplicates.

Does UNION exclude duplicates?

Both UNION and UNION ALL operators combine rows from result sets into a single result set. The UNION operator removes eliminate duplicate rows, whereas the UNION ALL operator does not.

How do you avoid duplicates in UNION query?

The SQL UNION ALL operator does not remove duplicates. If you wish to remove duplicates, try using the UNION operator.

Does UNION include duplicates SQL?

Anyway, the answer to this question is simple, though both UNION and UNION ALL are used to combine the result of two separate SQL queries on the same or different table, UNION does not keep a duplicate record (a row is considered duplicate if the value of all columns is same), while UNION ALL does.


1 Answers

This is valid and allowed by c standard and there is no undefined behavior in this code.

EDIT: For the snippet

 int main(void)
 {
     printf(" thinga.integ=%d .arr=%s\n", f("1").integ, f("1").arr);
 }  

f("1").arr is referencing arr element of the union. Since arr is an array and as per C rule, in this context array will decay to pointer to its first element. Since t is local to the function (an automatic local variable and will no longer be exist once function return), accessing arr elements will invoke undefined behavior.

like image 127
haccks Avatar answered Nov 15 '22 05:11

haccks