Array of size zero!

P

prashna

Hi all,

I have seen a piece of code(while doing code review) which declared an
array of size 0.One of my friend told although it is not standard
C,some compilers will support this..I am very curious to know the use
of it..
The code was compiled using Diab C compiler.
Also the array was declared in structure like this

typedef struct someStruct
{
int i;
char array[0];
} someStruct;


Thanks
Regards
 
J

jacob navia

The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct;

Without the zero.
This is a flexible array and is supported by C99.

you allocate the structure with more than sizeof(int), to
allocate the size of the array
 
X

xarax

prashna said:
Hi all,

I have seen a piece of code(while doing code review) which declared an
array of size 0.One of my friend told although it is not standard
C,some compilers will support this..I am very curious to know the use
of it..
The code was compiled using Diab C compiler.
Also the array was declared in structure like this

typedef struct someStruct
{
int i;
char array[0];
} someStruct;


Thanks
Regards

I think the C99 variant of this is "char array[];". The
zero-length array thing is intended to get around the
problem of allocating a variable-length structure, where
the declared portion of the structure represents a fixed-length
"header" and the size of the variable-length portion is
calculated at run-time.

Some compilers have a non-standard extension that allows
an array length of zero specified, which is the same effect
as the C99 elided length specification.

For compilers that don't support either specification, the
infamous "struct hack" technique is used where the array
length is specified as 1, and size calculations for the
variable-length structure take into consideration the
presence of one element of the array in the structure length
returned by sizeof().
 
C

Case -

jacob said:
The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct;

Without the zero.
This is a flexible array and is supported by C99.

you allocate the structure with more than sizeof(int), to
allocate the size of the array

I geuss this is not correct because it assumes that
array[] starts right after i. As the FAQ tells us,
you should use the offsetof() macro, which can
calculate the byte offset of array in someStruct.
This macro should be defined in <stddef.h>. If not,
use the #definition in the FAQ.

Case
 
D

Dan Pop

In said:
jacob said:
The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct;

Without the zero.
This is a flexible array and is supported by C99.

you allocate the structure with more than sizeof(int), to
allocate the size of the array

I geuss this is not correct because it assumes that
array[] starts right after i.

Nonsense: no such assumption is needed at all.

Dan
 
R

Richard Delorme

prashna a écrit :
Hi all,

I have seen a piece of code(while doing code review) which declared an
array of size 0.One of my friend told although it is not standard
C,some compilers will support this..I am very curious to know the use
of it..
The code was compiled using Diab C compiler.
Also the array was declared in structure like this

typedef struct someStruct
{
int i;
char array[0];
} someStruct;

It was a pre-C99 standard trial to have a flexible member array.
The struct could be allocated this way :
someStruct *s = malloc(sizeof (someStruct) + 42);
So, with a single malloc, you allocated the struct and the array objects
simultaneously.
In C99 a flexible array member should be declared :
struct someStruct {
int i;
char array[];
};
 
A

Alex Fraser

Dan Pop said:
jacob said:
The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct;

Without the zero.
This is a flexible array and is supported by C99.

you allocate the structure with more than sizeof(int), to
allocate the size of the array

I geuss this is not correct because it assumes that
array[] starts right after i.

Nonsense: no such assumption is needed at all.

Right, but Jacob /is/ making that assumption. AIUI, this does not
necessarily allocate sufficient space for 10 elements in array:

struct someStruct *s = malloc(sizeof(int) + 10);

But, OTOH, this does:

struct someStruct *s = malloc(sizeof *s + 10);

(Assuming malloc() succeeds in both cases.)

The reason being that padding after i in struct someStruct is not allowed
for.

Alex
 
D

Dan Pop

In said:
Dan Pop said:
jacob navia wrote:
The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct;

Without the zero.
This is a flexible array and is supported by C99.

you allocate the structure with more than sizeof(int), to
allocate the size of the array


I geuss this is not correct because it assumes that
array[] starts right after i.

Nonsense: no such assumption is needed at all.

Right, but Jacob /is/ making that assumption.

Where?!? He says more than sizeof(int), which might be misleading, but
not technically wrong.
AIUI, this does not
necessarily allocate sufficient space for 10 elements in array:

struct someStruct *s = malloc(sizeof(int) + 10);

It should, except for deliberately perverse implementations, but, in
theory, you're correct. OTOH, Jacob didn't say anywhere that this is
the right way of allocating memory for the structure, did he?
But, OTOH, this does:

struct someStruct *s = malloc(sizeof *s + 10);

(Assuming malloc() succeeds in both cases.)

The reason being that padding after i in struct someStruct is not allowed
for. ^^^

The reason being that padding after i in struct someStruct is
theoretically allowed. But, since it would merely waste memory, don't
expect to find it, until someone revives the DS9K project.

Dan
 
E

Emmanuel Delahaye

In said:
I have seen a piece of code(while doing code review) which declared an
array of size 0.One of my friend told although it is not standard

Wrong. It's a C99 feature.
C,some compilers will support this..I am very curious to know the use
of it..
The code was compiled using Diab C compiler.
Also the array was declared in structure like this

typedef struct someStruct
{
int i;
char array[0];
} someStruct;

It's used to do some linear mapping. It's a sort of trick... Not very good C
(outbounds-based technique), but it works and can be useful.
 
A

Alex Fraser

Dan Pop said:
In said:
Dan Pop said:
In <[email protected]> Case -

jacob navia wrote:
The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct; [snip]
you allocate the structure with more than sizeof(int), to
allocate the size of the array

I geuss this is not correct because it assumes that
array[] starts right after i.

Nonsense: no such assumption is needed at all.

Right, but Jacob /is/ making that assumption.

Where?!? He says more than sizeof(int), which might be misleading, but
not technically wrong.

By fortunate vagueness, yes. That too is an assumption, but a reasonable
one, don't you think?
It should, except for deliberately perverse implementations, but, in
theory, you're correct. OTOH, Jacob didn't say anywhere that this is
the right way of allocating memory for the structure, did he?

See above.

(I wrote this as applying to the first sentence but it doesn't read that
way. Oops.)
The reason being that padding after i in struct someStruct is
theoretically allowed. But, since it would merely waste memory, don't
expect to find it, until someone revives the DS9K project.

Agreed, in this specific case it is extremely unlikely. But for some
combinations of types of i and/or array, it's almost "guaranteed" (eg struct
{int i, double array[]}).

Alex
 
C

Case -

Dan said:
In <[email protected]> Case - <[email protected]>
writes:

jacob navia wrote:

The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct;

Without the zero.
This is a flexible array and is supported by C99.

you allocate the structure with more than sizeof(int), to
allocate the size of the array


I geuss this is not correct because it assumes that
array[] starts right after i.

Nonsense: no such assumption is needed at all.

Right, but Jacob /is/ making that assumption.


Where?!? He says more than sizeof(int), which might be misleading, but
not technically wrong.

AIUI, this does not
necessarily allocate sufficient space for 10 elements in array:

struct someStruct *s = malloc(sizeof(int) + 10);


It should, except for deliberately perverse implementations, but, in
theory, you're correct. OTOH, Jacob didn't say anywhere that this is
the right way of allocating memory for the structure, did he?

This is the theoretical case I was addressing. So, no nonsense
according to the C spec! And, come on, what else could Jacob
have meant?

Case
 
K

Keith Thompson

Emmanuel Delahaye said:
Wrong. It's a C99 feature.

No, C99 doesn't allow zero-sized arrays. There is a new feature
called "flexible array members" (discussed elsewhere in this thread),
but they're not implemented with zero-sized arrays.
 
D

Dan Pop

In said:
Dan said:
In <[email protected]> Case - <[email protected]>

writes:

jacob navia wrote:

The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct;

Without the zero.
This is a flexible array and is supported by C99.

you allocate the structure with more than sizeof(int), to
allocate the size of the array


I geuss this is not correct because it assumes that
array[] starts right after i.

Nonsense: no such assumption is needed at all.

Right, but Jacob /is/ making that assumption.


Where?!? He says more than sizeof(int), which might be misleading, but
not technically wrong.

AIUI, this does not
necessarily allocate sufficient space for 10 elements in array:

struct someStruct *s = malloc(sizeof(int) + 10);


It should, except for deliberately perverse implementations, but, in
theory, you're correct. OTOH, Jacob didn't say anywhere that this is
the right way of allocating memory for the structure, did he?

This is the theoretical case I was addressing. So, no nonsense
according to the C spec! And, come on, what else could Jacob
have meant?

Ask him. The point is that offsetof is NEVER necessary in this case and
Jacob said "more than sizeof(int)", which is technically correct.

Dan
 
C

Case -

Dan said:
Dan Pop wrote:

In <[email protected]> Case - <[email protected]>

writes:


jacob navia wrote:


The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct;

Without the zero.
This is a flexible array and is supported by C99.

you allocate the structure with more than sizeof(int), to
allocate the size of the array


I geuss this is not correct because it assumes that
array[] starts right after i.

Nonsense: no such assumption is needed at all.

Right, but Jacob /is/ making that assumption.


Where?!? He says more than sizeof(int), which might be misleading, but
not technically wrong.



AIUI, this does not
necessarily allocate sufficient space for 10 elements in array:

struct someStruct *s = malloc(sizeof(int) + 10);


It should, except for deliberately perverse implementations, but, in
theory, you're correct. OTOH, Jacob didn't say anywhere that this is
the right way of allocating memory for the structure, did he?

This is the theoretical case I was addressing. So, no nonsense
according to the C spec! And, come on, what else could Jacob
have meant?


Ask him. The point is that offsetof is NEVER necessary in this case and
Jacob said "more than sizeof(int)", which is technically correct.

With 'NEVER' do you mean with ALL real-life implementations, or do
you mean according to the C standard?

He said "more than sizeof(int), to allocate the size of the array".
IAW: 'Everything more than sizeof(int), is the size of the array'.
When more == 1, and there's a padding of >= 1 bytes between the int
and the array ... So, not technically correct.

Case
 
D

Dan Pop

In said:
Dan said:
Dan Pop wrote:







In <[email protected]> Case - <[email protected]>

writes:


jacob navia wrote:


The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct;

Without the zero.
This is a flexible array and is supported by C99.

you allocate the structure with more than sizeof(int), to
allocate the size of the array


I geuss this is not correct because it assumes that
array[] starts right after i.

Nonsense: no such assumption is needed at all.

Right, but Jacob /is/ making that assumption.


Where?!? He says more than sizeof(int), which might be misleading, but
not technically wrong.



AIUI, this does not
necessarily allocate sufficient space for 10 elements in array:

struct someStruct *s = malloc(sizeof(int) + 10);


It should, except for deliberately perverse implementations, but, in
theory, you're correct. OTOH, Jacob didn't say anywhere that this is
the right way of allocating memory for the structure, did he?

This is the theoretical case I was addressing. So, no nonsense
according to the C spec! And, come on, what else could Jacob
have meant?


Ask him. The point is that offsetof is NEVER necessary in this case and
Jacob said "more than sizeof(int)", which is technically correct.

With 'NEVER' do you mean with ALL real-life implementations, or do
you mean according to the C standard?

Both. All you need is sizeof(somestruct) to which you add the number of
bytes you need for array.
He said "more than sizeof(int), to allocate the size of the array".
IAW: 'Everything more than sizeof(int), is the size of the array'.

Severely broken interpretation. The right amount is simply unspecified
in the original statement. E.g. "you need more than your $10 to buy this
car" doesn't imply that you can buy it for $10.01.
When more == 1, and there's a padding of >= 1 bytes between the int
and the array ... So, not technically correct.

Nope.

Dan
 
C

Case -

Dan said:
Dan Pop wrote:

Dan Pop wrote:










In <[email protected]> Case - <[email protected]>

writes:



jacob navia wrote:



The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct;

Without the zero.
This is a flexible array and is supported by C99.

you allocate the structure with more than sizeof(int), to
allocate the size of the array


I geuss this is not correct because it assumes that
array[] starts right after i.

Nonsense: no such assumption is needed at all.

Right, but Jacob /is/ making that assumption.


Where?!? He says more than sizeof(int), which might be misleading, but
not technically wrong.




AIUI, this does not
necessarily allocate sufficient space for 10 elements in array:

struct someStruct *s = malloc(sizeof(int) + 10);


It should, except for deliberately perverse implementations, but, in
theory, you're correct. OTOH, Jacob didn't say anywhere that this is
the right way of allocating memory for the structure, did he?

This is the theoretical case I was addressing. So, no nonsense
according to the C spec! And, come on, what else could Jacob
have meant?


Ask him. The point is that offsetof is NEVER necessary in this case and
Jacob said "more than sizeof(int)", which is technically correct.

I did. See below.
Both. All you need is sizeof(somestruct) to which you add the number of
bytes you need for array.
Correct!



Severely broken interpretation. The right amount is simply unspecified
in the original statement. E.g. "you need more than your $10 to buy this
car" doesn't imply that you can buy it for $10.01.




Nope.

I e-mailed Jacob and he replied that 'it would have been
better to say sizeof(struct) + 67, instead of sizeof(int). There
could be some obscure reasons for sizeof structure != sizeof int.'

So, originally he *did* mean to say that the 67 bytes would all
end up in the char array. In 99% of the cases this is correct
for this struct when using sizeof(int), he also wrote. Once again:
it was this C-spec 1% my initial reply was about.

Case
 
?

=?iso-8859-1?q?Nils_O=2E_Sel=E5sdal?=

Dan Pop said:
jacob navia wrote:
The standard way of writing this is:
typedef struct someStruct
{
int i;
char array[];
} someStruct;

Without the zero.
This is a flexible array and is supported by C99.

you allocate the structure with more than sizeof(int), to
allocate the size of the array


I geuss this is not correct because it assumes that
array[] starts right after i.

Nonsense: no such assumption is needed at all.

Right, but Jacob /is/ making that assumption. AIUI, this does not
necessarily allocate sufficient space for 10 elements in array:

struct someStruct *s = malloc(sizeof(int) + 10);

But, OTOH, this does:

struct someStruct *s = malloc(sizeof *s + 10);

(Assuming malloc() succeeds in both cases.)

The reason being that padding after i in struct someStruct is not allowed

Huh ? isn't the offset off empty arrays quaranteed to be the same as
sizeof(thestruct) in which it appears ?
struct someStruct *s = malloc(sizeof(someStruct) + 10);
 
A

Alex Fraser

Nils O. Selåsdal said:
AIUI, this does not necessarily allocate sufficient space for 10
elements in array:

struct someStruct *s = malloc(sizeof(int) + 10);

But, OTOH, this does:

struct someStruct *s = malloc(sizeof *s + 10);

(Assuming malloc() succeeds in both cases.)

The reason being that padding after i in struct someStruct is not
allowed [for.]

Huh ?

Please elaborate. Did you read my first reply to Dan Pop?
isn't the offset off empty arrays quaranteed to be the same as
sizeof(thestruct) in which it appears ?
Yes.

struct someStruct *s = malloc(sizeof(someStruct) + 10);

This is equivalent to the second example I gave.

Alex
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
No, C99 doesn't allow zero-sized arrays. There is a new feature
called "flexible array members" (discussed elsewhere in this thread),
but they're not implemented with zero-sized arrays.

Yes, I had cancelled my post... not everywhere, sadly...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,737
Latest member
Georgeengab

Latest Threads

Top