android_noob_xx
android_noob_xx

Reputation: 83

Not able to understand array and struct together in this C program

I am trying to understand a C program that is below,

#include <stdio.h>

struct {
    int a;
    int b;
} id_gpios[] = { {1},{2},{3},{4} };

int main()
{
    printf("%d\n",id_gpios[0].a);
    printf("%d\n",id_gpios[0].b);
    printf("%d\n",id_gpios[1].a);
    printf("%d\n",id_gpios[1].b);
    printf("%d\n",id_gpios[2].a);
    printf("%d\n",id_gpios[2].b);
    return 0;
}

#~: ./a.out
1
0
2
0
3
0

The program compiles fine with gcc -Wall test.c

  1. How are values assigned to each struct member here?
  2. how array property is used in this case so as to justify the output?

P.S

variables l and q are just for shortening the code to be asked on SO. Actually these are mux values using big muxing macros. Changed to 'a' and 'b'.

Upvotes: 1

Views: 84

Answers (3)

WedaPashi
WedaPashi

Reputation: 3872

Broadly stating, its due to bad way of initialization. C11 (and older standards too) specify under the Section 6.7.9: Initialization the ways to Initialization a variable properly.

For the legal definition of what an Initializer is, refer the standard, it says,

An initializer specifies the initial value stored in an object.

In your code,

struct {
    int l;
    int q;
} id_gpios[] = { {1},{2},{3},{4} };

{ {1},{2},{3},{4} }; is an Initializer.

Here, q isn't initialized explicitly, hence it will be initialized to 0. This is due to what standard calls as "Inconsistently bracketed initialization".
See an example of the same provided in standard, section of Initialization, EXAMPLE 5

Quoting the same,

struct { int a[3], b; } w[] = { { 1 }, 2 };

Standard says,

The declaration is a definition with an inconsistently bracketed initialization. It defines an array with two element structures: w[0].a[0] is 1 and w[1].a[0] is 2; all the other elements are zero.

So, change your declaration/initialization to:

struct {
    int l;
    int q;
} id_gpios[] = { {1, 1},{2, 2},{3, 3},{4, 4} };

or whatever is applicable for your requirement, and is compatible.

Also, since l and q as variable makes no sense (to me and most of other developers around), change l and q to whatever that makes more sense in terms of what value these variables hold. With this naming convention, you are assured to be failed in Code Review if someone is taking Code Review even a wee-bit seriously.

Upvotes: 0

Lundin
Lundin

Reputation: 213812

It's sloppily written code. What it does is to create an array of 4 structs and initialize the member l only in each struct. Good compilers will warn here (for gcc use -Wextra), since the struct is partially initialized.

Since q isn't initialized explicitly, it will get set to zero. This is a special rule for partially initialized structs.

Properly written, the equivalent code looks like this:

typedef struct 
{
  int l;
  int q;
} id_gpios_t;

id_gpios_t id_gpios[] = 
{ 
  {1,0},
  {2,0},
  {3,0},
  {4,0},
};

(Using l as an identifier is well-known bad practice, since it looks like 1 on a lot of editor fonts.)

Upvotes: 4

Massimo Costa
Massimo Costa

Reputation: 1860

this code

struct {
    int l;
    int q;
} id_gpios[] = { {1},{2},{3},{4} };

defines an array of 4 elements, each element is initialized with l taking the value in the inner curly braces and q equals to 0.

Upvotes: 0

Related Questions