c - For a structure variable,why is the initializer {21,19,3.6} same as {{21,19},3.6},but not vice-versa? -


in following example,i've illustrated using 2 structures test1 , test2.the first has 2 elements-an integer array sized two,and float element.the second structure has 3 elements,2 integers , 1 float.

i initialize 2 structure variables s1 , s2 test1 as:

s1={{23,52},2.5},s2={21,19,3.6}; 

both work fine though s2 have taken out braces enclose array elements.it works fine without warning , output correct.but when initialize 2 variables test2 follows:

 v1={{23,52},2.5},v2={21,19,3.6}; 

i incorrect output when try print out values of v1 , these warnings had got upon compilation:

warning: braces around scalar initializer| warning: (near initialization 'v1.list1')| warning: excess elements in scalar initializer| warning: (near initialization 'v1.list1')| ||=== build finished: 0 errors, 4 warnings ===| 

based on premise,please clear following doubt arise:

question: if using v1={{23,52},2.5} instead of v1={23,52,2.5} confuses compiler whether first 2 numbers distinct integer elements of structure or part of integer array element of structure,then why doesn't using s2={21,19,3.6} instead of s2={{21,19},3.6} confuse compiler thinking structure varialbe s2 has 3 elements (2 integer elements , 1 float),instead of 2 elements (one integer array of size 2 , float)?what want understand why first case v1's initialization wrong.

#include<stdio.h>  struct test1{ int list[2]; float rate; }s1={{23,52},2.5},s2={21,19,3.6}; //works fine  struct test2{ int list1; int list2; float rate; }v1={{23,52},2.5},v2={21,19,3.6};  //messes things  int main(void) {     printf("%d,%d,%f\n",s1.list[1],s2.list[1],s2.rate);     printf("%d,%d,%f\n",v1.list1,v1.list2,v1.rate); } 

this consequence of how rules initialisers defined. if current object of initialisation struct, union or array, if next initialiser begins { initialisers enclosed brace , matching } used initialise members of object; otherwise, marches through list of initialisers, taking many needs.

so, in first case s1={{23,52},2.5}, current object starts out s1.list. array, , next initialiser { 23, 52 }, that's used initialise array. s1.rate current object, , next initialiser 2.5, works expected.

in second case s2={21,19,3.6}, current object starts out s2.list. array, next initialiser not start out { - takes many values needs (in case, two), , initialises array 21 , 19. s2.rate current object, , next initialiser 2.5, again works expected.

in third case v1={{23,52},2.5}, current object starts out v1.list1. scalar, , corresponding initialiser {23, 52}. violates constraint of language - "the initializer scalar shall single expression, optionally enclosed in braces" - that's why warning. formally behaviour of program undefined, appears compiler uses first value contained in initialiser , discards excess ones. current object v1.list2, , next initialiser 2.5, wrong value used initialise member. there no initialiser v1.rate; since v1 has static storage duration, member initialiser 0.0.

in forth case v2={21,19,3.6}, current object starts out v1.list1, , next initialiser 21 - value used initialise member. after current object v1.list2 , next initialiser 19; v1.rate current object , next initialiser 3.6.

for minimum confusion, should use brace-enclosed initialiser each struct or array subobject.


Comments

Popular posts from this blog

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -