admin管理员组文章数量:1024424
Why is the following an error and what is the correct syntax?
struct a {
int b[4];
};
int c[4];
struct a a = {.b = &c};
Shouldn't a.b
be of type int *
or int[]
, why is it of type int
?
(Note, that the declaration of struct a
can't be changed.)
Why is the following an error and what is the correct syntax?
struct a {
int b[4];
};
int c[4];
struct a a = {.b = &c};
Shouldn't a.b
be of type int *
or int[]
, why is it of type int
?
(Note, that the declaration of struct a
can't be changed.)
2 Answers
Reset to default 3The C language is a bit weird since for historical reasons it does not allow initialization or assignment between two arrays. That's just how the language is defined.
C does however allow structs to be initialized/assigned from other structs of the same type. Even if they happen to contain an array. So you could do this:
struct a c = { .b = {1,2,3,4} };
...
struct a a = c;
Or otherwise skip initialization and use run-time assignment instead. Since we're dealing with arrays we can't use =
but have to use memcpy
:
int c[4] = {1,2,3,4};
struct a a;
memcpy(a.b, c, sizeof(a.b));
As for the reason for the peculiar compiler error:
warning: initialization of 'int' from 'int (*)[4]' makes integer from pointer without a cast [-Wint-conversion]
Initialization of arrays (or structs) is done by the compiler internally keeping track on the current object to initialize. When we type in a designated initializer .b
, the compiler sets the current object to be initialized to the first item b[0]
in the array b
. And then expects a number of initializers with type int
from there on. For each int
we hand it in the initializer list, it will automatically shift current initialized object to the next one in the list, b[1]
, b[2]
and so on.
If written properly that would look like .b = {1,2,3,4}
but the braces are actually optional. What matters is the compiler keeping track of the current object. We could as well write sloppy code like .b = 1,2,3,4
. Very bad practice but valid C.
Anyway, since the compiler expects an int
but is given a pointer to array with &c
, it raises a constraint violation diagnostic message. It expected an int
but got a int (*)[4]
and that is invalid C.
.b = something
is fine as far as the syntax is concerned, the types just didn't match in case of .b = &c
. The types are regulated by the constraints of the assignment operator. A compiler must give a diagnostic message whenever the code violates either the C syntax or the C constraints.
You are correct in your assessment: b
should have type int *
or int const *
but you should drop the &
from the initializer:
struct a {
int *b;
};
int c[4];
struct a a = { .b = c };
Or equivalently:
struct a a = { c };
Why is the following an error and what is the correct syntax?
struct a {
int b[4];
};
int c[4];
struct a a = {.b = &c};
Shouldn't a.b
be of type int *
or int[]
, why is it of type int
?
(Note, that the declaration of struct a
can't be changed.)
Why is the following an error and what is the correct syntax?
struct a {
int b[4];
};
int c[4];
struct a a = {.b = &c};
Shouldn't a.b
be of type int *
or int[]
, why is it of type int
?
(Note, that the declaration of struct a
can't be changed.)
-
You can't initialize one array from another unfortunately.
a.b
is of typeint[4]
which is different fromint *
. – interjay Commented Nov 28, 2024 at 10:32 -
"Shouldn't a.b be of type int * or int[], why is it of type int?" Yes, it is one of your 2 options. But you seem to think, that they are the same, which they are not. You use it as if it was
int*
but you defined it asint[]
. Anda.b
is not of typeint
. Where do you get that idea from? – Gerhardh Commented Nov 28, 2024 at 10:41 - @Gerhardh I got that idea from my compiler. – Caulder Commented Nov 28, 2024 at 10:45
-
You must provide an initializer list:
struct a a = { .b={1, 2, 3, 4}};
You cannot initialize an array with a pointer (i.e. the address of another array). – Gerhardh Commented Nov 28, 2024 at 10:45 - 1 @Gerhardh I appended an explanation about that to my posted answer. – Lundin Commented Nov 28, 2024 at 11:00
2 Answers
Reset to default 3The C language is a bit weird since for historical reasons it does not allow initialization or assignment between two arrays. That's just how the language is defined.
C does however allow structs to be initialized/assigned from other structs of the same type. Even if they happen to contain an array. So you could do this:
struct a c = { .b = {1,2,3,4} };
...
struct a a = c;
Or otherwise skip initialization and use run-time assignment instead. Since we're dealing with arrays we can't use =
but have to use memcpy
:
int c[4] = {1,2,3,4};
struct a a;
memcpy(a.b, c, sizeof(a.b));
As for the reason for the peculiar compiler error:
warning: initialization of 'int' from 'int (*)[4]' makes integer from pointer without a cast [-Wint-conversion]
Initialization of arrays (or structs) is done by the compiler internally keeping track on the current object to initialize. When we type in a designated initializer .b
, the compiler sets the current object to be initialized to the first item b[0]
in the array b
. And then expects a number of initializers with type int
from there on. For each int
we hand it in the initializer list, it will automatically shift current initialized object to the next one in the list, b[1]
, b[2]
and so on.
If written properly that would look like .b = {1,2,3,4}
but the braces are actually optional. What matters is the compiler keeping track of the current object. We could as well write sloppy code like .b = 1,2,3,4
. Very bad practice but valid C.
Anyway, since the compiler expects an int
but is given a pointer to array with &c
, it raises a constraint violation diagnostic message. It expected an int
but got a int (*)[4]
and that is invalid C.
.b = something
is fine as far as the syntax is concerned, the types just didn't match in case of .b = &c
. The types are regulated by the constraints of the assignment operator. A compiler must give a diagnostic message whenever the code violates either the C syntax or the C constraints.
You are correct in your assessment: b
should have type int *
or int const *
but you should drop the &
from the initializer:
struct a {
int *b;
};
int c[4];
struct a a = { .b = c };
Or equivalently:
struct a a = { c };
本文标签: cCorrect syntax for whole array initializaitionStack Overflow
版权声明:本文标题:c - Correct syntax for whole array initializaition - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745517683a2154150.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
a.b
is of typeint[4]
which is different fromint *
. – interjay Commented Nov 28, 2024 at 10:32int*
but you defined it asint[]
. Anda.b
is not of typeint
. Where do you get that idea from? – Gerhardh Commented Nov 28, 2024 at 10:41struct a a = { .b={1, 2, 3, 4}};
You cannot initialize an array with a pointer (i.e. the address of another array). – Gerhardh Commented Nov 28, 2024 at 10:45