473,416 Members | 1,859 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,416 software developers and data experts.

Flexible array member + variable length array

Hi all,

With this structure that records the length of an array of pointers as its
first member:

struct array {
ptrdiff_t length;
void *ptr[];
};

How does one initialise this structure using a variable length array?

ptrdiff_t len=10;
{
struct array a[len+1];
...
}

It appears the above code will only work to reserve space for len pointers
if the sizeof length is the same as sizeof pointers to void and there is
no padding between length and the pointers to void. Is there portable C99
syntax that I have overlooked? (or will I have to create a VLA of type
void * and keep casting the first argument to ptrdiff_t?)

Thanks,
Adam
Nov 14 '05 #1
10 6656
Adam Warner wrote:
Hi all,

With this structure that records the length of an array of pointers as its
first member:

struct array {
ptrdiff_t length;
void *ptr[];
};

How does one initialise this structure using a variable length array?

ptrdiff_t len=10;
{
struct array a[len+1];
...
}

It appears the above code will only work to reserve space for len pointers
if the sizeof length is the same as sizeof pointers to void and there is
no padding between length and the pointers to void. Is there portable C99
syntax that I have overlooked? (or will I have to create a VLA of type
void * and keep casting the first argument to ptrdiff_t?)


I am not sure what you are asking for. The example from the standard
runs like this:

(6.7.2.1)
"
17
EXAMPLE Assuming that all array members are aligned the same, after the
declarations:
struct s { int n; double d[]; };
struct ss { int n; double d[1]; };
the three expressions:
sizeof (struct s)
offsetof(struct s, d)
offsetof(struct ss, d)
have the same value. The structure struct s has a flexible array member
d.

18
If sizeof (double) is 8, then after the following code is executed:
struct s *s1;
struct s *s2;
s1 = malloc(sizeof (struct s) + 64);
s2 = malloc(sizeof (struct s) + 46);
and assuming that the calls to malloc succeed, the objects pointed to by
s1 and s2 behave as if the identifiers had been declared as:
struct { int n; double d[8]; } *s1;
struct { int n; double d[5]; } *s2;
"

Structures with flexible array members of course cannot be
put into arrays.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #2
Visit this page:

http://gcc.gnu.org/ml/gcc/2002-04/msg00026.html

Hope it helps.

Cheers
Shan

Adam Warner wrote:
Hi all,

With this structure that records the length of an array of pointers as its first member:

struct array {
ptrdiff_t length;
void *ptr[];
};

How does one initialise this structure using a variable length array?

ptrdiff_t len=10;
{
struct array a[len+1];
...
}

It appears the above code will only work to reserve space for len pointers if the sizeof length is the same as sizeof pointers to void and there is no padding between length and the pointers to void. Is there portable C99 syntax that I have overlooked? (or will I have to create a VLA of type void * and keep casting the first argument to ptrdiff_t?)

Thanks,
Adam


Nov 14 '05 #3

Shan wrote:
Visit this page:

http://gcc.gnu.org/ml/gcc/2002-04/msg00026.html

Hope it helps.

Cheers
Shan

Adam Warner wrote:
Hi all,

With this structure that records the length of an array of pointers as its
first member:

struct array {
ptrdiff_t length;
void *ptr[];
};

How does one initialise this structure using a variable length array?
ptrdiff_t len=10;
{
struct array a[len+1];
...
}

It appears the above code will only work to reserve space for len

pointers
if the sizeof length is the same as sizeof pointers to void and

there is
no padding between length and the pointers to void. Is there
portable C99
syntax that I have overlooked? (or will I have to create a VLA of

type
void * and keep casting the first argument to ptrdiff_t?)

Thanks,
Adam


Sorry, i top posted by mistake....

Nov 14 '05 #4
On Thu, 03 Feb 2005 10:29:48 +0100, Michael Mair wrote:
EXAMPLE Assuming that all array members are aligned the same, after the
declarations:
struct s { int n; double d[]; };
struct ss { int n; double d[1]; };
the three expressions:
sizeof (struct s)
offsetof(struct s, d)
offsetof(struct ss, d)
have the same value. The structure struct s has a flexible array member
d.

18
If sizeof (double) is 8, then after the following code is executed:
struct s *s1;
struct s *s2;
s1 = malloc(sizeof (struct s) + 64);
s2 = malloc(sizeof (struct s) + 46);
and assuming that the calls to malloc succeed, the objects pointed to by
s1 and s2 behave as if the identifiers had been declared as:
struct { int n; double d[8]; } *s1;
struct { int n; double d[5]; } *s2;
"

Structures with flexible array members of course cannot be
put into arrays.


Indeed. It looks like I was after alloca-style functionality (which is
non-standard) to duplicate the example above on the stack instead of the
heap.

Regards,
Adam
Nov 14 '05 #5
On Thu, 03 Feb 2005 20:50:36 +1300, Adam Warner wrote:
Hi all,

With this structure that records the length of an array of pointers as its
first member:

struct array {
ptrdiff_t length;
void *ptr[];
};

This is a structure containing a C99 flexible array member.
How does one initialise this structure using a variable length array?
You don't. Flexible array members and VLAs are different and unrelated
constructs. Flexible array members are designed to be allocated using
malloc() and friends, e.g.

struct array *p = malloc(sizeof *p + len * sizeof *p->ptr);
ptrdiff_t len=10;
{
struct array a[len+1];
...
}


You can't make arrays of structures containing flexible array members
because the size of each element is not known or fixed.

Lawrence
Nov 14 '05 #6
Lawrence Kirby <lk****@netactive.co.uk> wrote:
On Thu, 03 Feb 2005 20:50:36 +1300, Adam Warner wrote:
Hi all,

With this structure that records the length of an array of pointers as its
first member:

struct array {
ptrdiff_t length;
void *ptr[];
};
This is a structure containing a C99 flexible array member. How does one initialise this structure using a variable length array? You don't. Flexible array members and VLAs are different and unrelated
constructs. Flexible array members are designed to be allocated using
malloc() and friends, e.g. struct array *p = malloc(sizeof *p + len * sizeof *p->ptr);
Well, if an object was declared with the type struct with FAM, then
you actually could initialize it's leading members, couldn't you?
(Of course, declaring such objects would be against the purpose
of FAM.)
(Note: you cannot initialize FAM itself, even if the struct were
the first member of a suitable union, because FAM is ignored in
all contexts, except `sizeof', `.' and `->'.)
ptrdiff_t len=10;
{
struct array a[len+1];
...
}

You can't make arrays of structures containing flexible array members
because the size of each element is not known or fixed.


Would you please kindly elaborate on that?

Indeed, FAMs (flexible array members) and VLAs are different. FAMs are
described in 6.7.2.1p16. The size of a struct with a FAM is the
offset of the FAM, therefore such a struct is not an incomplete type.
It is not variably modified type either, because it does not contain a
VLA type (the definition of VM types is in 6.7.5p3).

The last place I looked was in array declarators, and all I found was
in 6.7.5.2p1:
# The element type shall not be an incomplete or function type.

I see nothing that would forbid to create arrays of structs with FAM.

+++

However, I tried this program with Comeau compiler in C99 mode:

struct flex
{
int i;
int tail[];
};

int main()
{
struct flex f;
int s = sizeof(struct flex);
struct flex a[5];
}

[...]
"t.c", line 11: error: type containing an unknown-size array is not allowed
struct flex a[5];
^

It seems to accept a declared object (`f') of type struct flex, but
rejects an array for some reason.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #7
S.Tobias wrote:
Lawrence Kirby <lk****@netactive.co.uk> wrote:
On Thu, 03 Feb 2005 20:50:36 +1300, Adam Warner wrote:


Hi all,

With this structure that records the length of an array of pointers as its
first member:

struct array {
ptrdiff_t length;
void *ptr[];
};

This is a structure containing a C99 flexible array member.


How does one initialise this structure using a variable length array?
You don't. Flexible array members and VLAs are different and unrelated
constructs. Flexible array members are designed to be allocated using
malloc() and friends, e.g.


struct array *p = malloc(sizeof *p + len * sizeof *p->ptr);

Well, if an object was declared with the type struct with FAM, then
you actually could initialize it's leading members, couldn't you?
(Of course, declaring such objects would be against the purpose
of FAM.)
(Note: you cannot initialize FAM itself, even if the struct were
the first member of a suitable union, because FAM is ignored in
all contexts, except `sizeof', `.' and `->'.)

ptrdiff_t len=10;
{
struct array a[len+1];
...
}


You can't make arrays of structures containing flexible array members
because the size of each element is not known or fixed.

Would you please kindly elaborate on that?

Indeed, FAMs (flexible array members) and VLAs are different. FAMs are
described in 6.7.2.1p16. The size of a struct with a FAM is the
offset of the FAM, therefore such a struct is not an incomplete type.
It is not variably modified type either, because it does not contain a
VLA type (the definition of VM types is in 6.7.5p3).

The last place I looked was in array declarators, and all I found was
in 6.7.5.2p1:
# The element type shall not be an incomplete or function type.

I see nothing that would forbid to create arrays of structs with FAM.

+++

However, I tried this program with Comeau compiler in C99 mode:

struct flex
{
int i;
int tail[];
};

int main()
{
struct flex f;
int s = sizeof(struct flex);
struct flex a[5];
}

[...]
"t.c", line 11: error: type containing an unknown-size array is not allowed
struct flex a[5];
^

It seems to accept a declared object (`f') of type struct flex, but
rejects an array for some reason.


Because there is no guarantee that the alignment requirements hold
in the sense that there is padding at the end.
Example: Let sizeof(int)==4, sizeof(short)==2 and the alignment
requirements equal to the size of the type.
Hence,
struct s1 {
int i;
char c;
}
will have a size of 8, but
struct s2 {
int i;
char c;
short s[];
}
has as size of 6 as we assume that
sizeof(structs2)==offsetof(struct s2,s)
and offsetof(struct s2,s)==offsetof(struct s3,s)
with
struct s3 {
int i;
char c;
short s[1];
}
which follows from the (non-normative) example 6.7.2.1#17
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #8
Michael Mair <Mi**********@invalid.invalid> wrote:
S.Tobias wrote:
Lawrence Kirby <lk****@netactive.co.uk> wrote:
[snippage]
You can't make arrays of structures containing flexible array members
because the size of each element is not known or fixed.

Would you please kindly elaborate on that?

Indeed, FAMs (flexible array members) and VLAs are different. FAMs are
described in 6.7.2.1p16. The size of a struct with a FAM is the
offset of the FAM, therefore such a struct is not an incomplete type.
It is not variably modified type either, because it does not contain a
VLA type (the definition of VM types is in 6.7.5p3).

The last place I looked was in array declarators, and all I found was
in 6.7.5.2p1:
# The element type shall not be an incomplete or function type.

I see nothing that would forbid to create arrays of structs with FAM.

+++

However, I tried this program with Comeau compiler in C99 mode:
[snip code]
[...]
"t.c", line 11: error: type containing an unknown-size array is not allowed
struct flex a[5];
^

It seems to accept a declared object (`f') of type struct flex, but
rejects an array for some reason.


Thank you for answering, however I disagree with your POV.
Because there is no guarantee that the alignment requirements hold
in the sense that there is padding at the end.
But the Standard does not make any requirements for alignment
(it merely allows them); it's up to the implementation fulfill them.
Example: Let sizeof(int)==4, sizeof(short)==2 and the alignment
requirements equal to the size of the type.
Hence,
struct s1 {
int i;
char c;
}
will have a size of 8, but
struct s2 {
int i;
char c;
short s[];
}
has as size of 6 as we assume that
sizeof(structs2)==offsetof(struct s2,s)
Yes, but what's the point? On an architecture without alignment
this shouldn't be a problem, should it?

I think you use your logic in the wrong direction. My reasoning
would be that since the Standard doesn't forbid structs with FAM
being elements of an array, they are allowed. It means that on
an implementation with int alignment 4 bytes, the compiler must
provide padding bits so that sizeof(struct s2) == 8.
and offsetof(struct s2,s)==offsetof(struct s3,s)
with
struct s3 {
int i;
char c;
short s[1];
}
which follows from the (non-normative) example 6.7.2.1#17


No, the Standard is very clear that it does not guarantee this
(footnote 106; and the word "Assuming" in the example).

Note that 6.7.2.1p16 does not provide any recipe for building
struct s2 type; it uses words "an array of unspecified length",
which means it is up to the implementation to decide what length
should be the most suitable.

+++

I think it not wrong to imagine that a FAM is a "member" which
represents the bytes _after_ the body of the struct object
(ie. the FAM does not strictly belong to the struct).

===

For others' convenience, here's the full quote of 6.7.2.1p16:

# 16 As a special case, the last element of a structure with more
# than one named member may have an incomplete array type;
# this is called a flexible array member. With two exceptions,
# the flexible array member is ignored. First, the size of the
# structure shall be equal to the offset of the last element of
# an otherwise identical structure that replaces the flexible
# array member with an array of unspecified length.106) Second,
# when a . (or ->) operator has a left operand that is (a pointer
# to) a structure with a flexible array member and the right
# operand names that member, it behaves as if that member were
# replaced with the longest array (with the same element type)
# that would not make the structure larger than the object being
# accessed; the offset of the array shall remain that of the
# flexible array member, even if this would differ from that of
# the replacement array. If this array would have no elements, it
# behaves as if it had one element but the behavior is undefined
# if any attempt is made to access that element or to generate
# a pointer one past it.
#
# 106) The length is unspecified to allow for the fact that
# implementations may give array members different alignments
# according to their lengths.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #9
In message <36*************@individual.net>
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
I think you use your logic in the wrong direction. My reasoning
would be that since the Standard doesn't forbid structs with FAM
being elements of an array, they are allowed. It means that on
an implementation with int alignment 4 bytes, the compiler must
provide padding bits so that sizeof(struct s2) == 8.


Wrong. 6.7.2.1p2:

"...the last member of a structure with more than one named member
may have incomplete array type; such a structure ... shall not be a
member of a structure or an element of an array."

This is precisely to cope with alignment issues. On our implementation,
int has alignment 4, and given

struct s1 {
int i;
char c;
};

struct s2 {
int i;
char c;
short s[];
};

struct s1 has size 8, and struct s2 has size 6 (because sizeof(struct s2)
must equal offsetof(struct s2, s)), just as Michael suggests. Thus any
struct s2s placed in an array would be misaligned. Fortunately, the standard
forbids this.

There is a Defect Report #282 about sizeof such a structure, but it's bogus
as far as I can see - they're suggesting that they have to put padding before
s[] to make s2 be size 8 for alignment, but what they've missed is that s2
does not have to meet alignment requirements, because of the array
restriction, so s2 can be left unpadded.

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 14 '05 #10
Kevin Bracey <ke**********@tematic.com> wrote:
In message <36*************@individual.net>
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
I think you use your logic in the wrong direction. My reasoning
would be that since the Standard doesn't forbid structs with FAM
being elements of an array, they are allowed. It means that on

[snip]
Wrong. 6.7.2.1p2: "...the last member of a structure with more than one named member
may have incomplete array type; such a structure ... shall not be a
member of a structure or an element of an array."


Shame on me having missed that part! Many thanks!

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: pvinodhkumar | last post by:
The number of elemets of the array, the array bound must be constant expression?Why is this restriction? Vinodh
2
by: Christopher Benson-Manica | last post by:
Is the following program conforming under C99? #include <stdio.h> typedef struct foo { int bar; int baz; } foo; foo foos={
2
by: DevarajA | last post by:
Can someone help me understand what flexible array members exactly are, how they behave and how could them be implemented by a i386? Also I didn't understand the two exceptions that the standards...
20
by: mechanicfem | last post by:
I thought (as they're in c99) that flexible arrays were there for a number of reasons - but I also thought they'd be great for stepping into structures (say) that were aligned in memory after (say)...
4
by: Armand | last post by:
Hi Guys, I have a set of array that I would like to clear and empty out. Since I am using "Array" not "ArrayList", I have been struggling in finding the solution which is a simple prob for those...
45
by: VK | last post by:
(see the post by ASM in the original thread; can be seen at <http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/3716384d8bfa1b0b> as an option) As that is not in relevance to...
6
by: foreverbored75 | last post by:
Hello All! I am just learning c++ in school and I have the following question: Is there a way for the user to input the length of an array (console application) without using another variable?...
44
by: svata | last post by:
Hello, I wonder how to resize such array of structures using realloc()? #include <stdio.h> #include <stdlib.h> #define FIRST 7 typedef struct { char *name;
3
by: Hallvard B Furuseth | last post by:
to find the required alignment of a struct, I've used #include <stddef.h> struct Align_helper { char dummy; struct S align; }; enum { S_alignment = offsetof(struct Align_helper, align) };
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.