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
Post a Comment