Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A legal array assignment. Is it possible?

After reading the chapter about structures in the K&R book I decided to make some tests to understand them better, so I wrote this piece of code:

#include <stdio.h>
#include <string.h>

struct test func(char *c);

struct test
{
    int i ;
    int j ;
    char x[20];
};

main(void)
{
    char c[20];
    struct  {int i ; int j ; char x[20];}  a = {5 , 7 , "someString"} , b; 
    c = func("Another string").x;
    printf("%s\n" , c);
}

struct test func(char *c)
{
    struct test temp;
    strcpy(temp.x , c);
    return temp;    
}

My question is: why is c = func("Another string").x; working (I know that it's illegal, but why is it working)? At first I wrote it using strcpy() (because that seemed the most logical thing to do) but I kept having this error:

structest.c: In function ‘main’:
structest.c:16:2: error: invalid use of non-lvalue array
like image 525
Farouq Jouti Avatar asked Aug 23 '13 21:08

Farouq Jouti


1 Answers

    char c[20];
    ...
    c = func("Another string").x;

This is not valid C code. Not in C89, not in C99, not in C11.

Apparently it compiles with the latest gcc versions 4.8 in -std=c89 mode without diagnostic for the assignment (clang issues the diagnostic). This is a bug in gcc when used in C89 mode.

Relevant quotes from the C90 Standard:

6.2.2.1 "A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type. and if it is a structure or union. does not have any member (including. recursively, any member of all contained structures or unions) with a const-qualified type."

and

6.3.16 "An assignment operator shall have a modifiable lvalue as its left operand."

6.3.16 is a constraint and imposes at least for gcc to issue a diagnostic which gcc does not, so this is a bug.

like image 130
ouah Avatar answered Oct 29 '22 16:10

ouah