declaration meaning

K

krishna

Hi all,
char a[10];
will declare character array of size 10 starting with the index 0.
what is the meaning of the following declaration? what is the purpose
of such
declarations?
char a[0];

thanks,
Krishna
 
D

Darko

It's illegal. Compiler would complain. If you said for example
char a[1];
it would be one character, and the A would be a pointer to it.
Specifying zero sized arrays is illegal.
 
R

Roberto Waltman

krishna said:
Hi all,
char a[10];
will declare character array of size 10 starting with the index 0.
what is the meaning of the following declaration? what is the purpose
of such
declarations?
char a[0];

They are used sometimes to provide a name for a variable size array,
located at the adress of 'a'.
For example:

#include <stdlib.h>

struct message
{
int type;
int length;
char data[0];
};
typedef struct message message_t;

message_t *create_message(int type, int length)
{
message_t *temp;
temp = malloc(length + sizeof(message_t));
if (temp != NULL)
{
temp->type = type;
temp->length = length;
}
return temp;
}

int main()
{
message_t *abc;
abc = create_message(10);
return EXIT_SUCCESS;
}
 
D

Darko

If this works, then it's a work of art. :) Of course - if one was to
declare it as a variable, it would get a compiler error. However,
declaring it in a structure doesn't do the allocating itself, we just
get a name we later hold for when referring to (m)allocated memory.
Genialno. :) So, it actually works only for structs?
 
K

krishna

thanks for the info
sizeof(message_t) + length is allocated
How can we assign value to the member "data" of the structure message
After the allocation is "data" an character array of size 10?

thanks,
Krishna
 
K

krishna

yes actually in the code i am reading it is actually inside the
structure.
Sorry i just mentioned it as a variable
 
R

Roberto Waltman

krishna said:
sizeof(message_t) + length is allocated
How can we assign value to the member "data" of the structure message
After the allocation is "data" an character array of size 10?

Surprisingly, by using data, where i is declared as an integer type
and (i >= 0) and (i < 10).
Or any other way allowed by the C language...
 
V

void * clvrmnky()

Roberto said:
krishna said:
Hi all,
char a[10];
will declare character array of size 10 starting with the index 0.
what is the meaning of the following declaration? what is the purpose
of such
declarations?
char a[0];

They are used sometimes to provide a name for a variable size array,
located at the adress of 'a'.
For example:

#include <stdlib.h>

struct message
{
int type;
int length;
char data[0];
};

Is this strictly Standard ISO C? I know that GCC allows this form of an
array that forms a variable-length object. C90 wants it to be "char
data[1];" and C99 indicates that is should be "char data[];"
 
R

Roberto Waltman

They are used sometimes to provide a name for a variable size array,
located at the adress of 'a'.
For example:

#include <stdlib.h>

struct message
{
int type;
int length;
char data[0];
};
typedef struct message message_t;

message_t *create_message(int type, int length)
{
message_t *temp;
temp = malloc(length + sizeof(message_t));
if (temp != NULL)
{
temp->type = type;
temp->length = length;
}
return temp;
}

int main()
{
message_t *abc;
abc = create_message(10);
Sorry, this call should have two parameters, of course.
return EXIT_SUCCESS;
}

I think I misunderstood Krishna's 2nd question.
In this example the array could be accessed as
abc->data, abc->data[5], etc.
(If abc is not NULL).
 
E

Eric Sosman

void * clvrmnky() wrote On 05/05/06 15:18,:
Roberto said:
Hi all,
char a[10];
will declare character array of size 10 starting with the index 0.
what is the meaning of the following declaration? what is the purpose
of such
declarations?
char a[0];

They are used sometimes to provide a name for a variable size array,
located at the adress of 'a'.
For example:

#include <stdlib.h>

struct message
{
int type;
int length;
char data[0];
};


Is this strictly Standard ISO C?

No.
 
R

Roberto Waltman

Roberto said:
krishna said:
Hi all,
char a[10];
will declare character array of size 10 starting with the index 0.
what is the meaning of the following declaration? what is the purpose
of such
declarations?
char a[0];

They are used sometimes to provide a name for a variable size array,
located at the adress of 'a'.
For example:

#include <stdlib.h>

struct message
{
int type;
int length;
char data[0];
};

Is this strictly Standard ISO C? I know that GCC allows this form of an
array that forms a variable-length object. C90 wants it to be "char
data[1];" and C99 indicates that is should be "char data[];"

No. Thanks for pointing this out. From ISO/IEC-9899 2nd edition:

"6.7.5.2 Array declarators
Constraints
1 In addition to optional type qualifiers and the keyword static, the
[ and ] may delimit an expression or *. If they delimit an expression
(which specifies the size of an array), the expression shall have an
integer type. If the expression is a constant expression, it shall
have a value greater than zero."
 
K

Keith Thompson

Roberto Waltman said:
krishna said:
char a[10];
will declare character array of size 10 starting with the index 0.
what is the meaning of the following declaration? what is the purpose
of such
declarations?
char a[0];

They are used sometimes to provide a name for a variable size array,
located at the adress of 'a'.
For example:
[...]

struct message
{
int type;
int length;
char data[0];
};
[...]

This is not legal in standard C, though some compilers may allow it as
an extension. Another common way to express this is by declaring
char data[1];

Both forms are known as the "struct hack". C99 provides a new
features called "flexible array members", intended to provide the
functionality of the struct hack in a clearly legal manner.
 
C

CBFalconer

Darko said:
If this works, then it's a work of art. :) Of course - if one was to
declare it as a variable, it would get a compiler error. However,
declaring it in a structure doesn't do the allocating itself, we just
get a name we later hold for when referring to (m)allocated memory.
Genialno. :) So, it actually works only for structs?

Very clear. It is obvious to all what 'it' means. I suggest you
try reading your own posts before hitting the equivalent of a
'send' key, and seeing if it makes sense. Without context most
posts do not. To include suitable context, even with the insipidly
stupid google interface to usenet, see my sig. below.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
K

Keith Thompson

Darko said:
If this works, then it's a work of art. :) Of course - if one was to
declare it as a variable, it would get a compiler error. However,
declaring it in a structure doesn't do the allocating itself, we just
get a name we later hold for when referring to (m)allocated memory.
Genialno. :) So, it actually works only for structs?

What are you talking about?

Please read <http://cfaj.freeshell.org/google/>.
 
I

Ian Collins

i try the code in vs.net,it can not pass.
does it only work in gcc?
Please quote context.

The code will not compile in gcc (create_message is only called with one
parameter), the struct will compile with a warning.

Other compilers will correctly reject it.
 
T

Tomás

#include <stdlib.h>

struct message
{
int type;
int length;
char data[0];
};
typedef struct message message_t;

message_t *create_message(int type, int length)
{
message_t *temp;
temp = malloc(length + sizeof(message_t));
if (temp != NULL)
{
temp->type = type;
temp->length = length;
}
return temp;
}

int main()
{
message_t *abc;
abc = create_message(10);
return EXIT_SUCCESS;
}


In C, we can declare arrays of objects as follows:

message array[4];

And we're guaranteed that each element is DIRECTLY after the other in
memory, such that we can use a pointer like so:

message *p = &array[0];
++p; //now it points to the 2nd element
++p; //now it points to the 3rd element
++p; //now it points to the 4th element

To facilitate this, the "sizeof" operator returns the full size of the
struct including any necessary padding at the end, such that the next
element in an array can be directly after it.

So, if you define a struct as follows:

struct Monkey { int i; int k; char b; };

It is very probable that it will take up the following amount of memory:

a) 4 bytes for "i"
b) 4 bytes for "k"
b) 1 byte for "b"
c) 3 bytes of padding so the next element can be right after it.

This gives us an overall size of 12 bytes.

Now here's my question:

If we define a structure which has an array at the end of it, how can we be
sure that there's no padding at the end?

-Tomás
 
W

Walter Roberson

Now here's my question:
If we define a structure which has an array at the end of it, how can we be
sure that there's no padding at the end?

( ( (char *) &structname + sizeof structname) -
( (char *) &structname.arrayname + sizeof structname.arrayname ) ) == 0

This should be legal because you are allowed to construct pointers
to one element past the end of an object. If I recall a posting
from a few weeks ago correctly, C99 specifically indicates that
such pointers are comparable (so you could test them for
equality instead of subtracting them), but if I remember correctly,
C89 does not specifically indicate you can compare such pointers
to each other [which is why I take their difference, with the
potentially larger value first]
 
J

Joe Wright

Tomás said:
#include <stdlib.h>

struct message
{
int type;
int length;
char data[0];
};
typedef struct message message_t;

message_t *create_message(int type, int length)
{
message_t *temp;
temp = malloc(length + sizeof(message_t));
if (temp != NULL)
{
temp->type = type;
temp->length = length;
}
return temp;
}

int main()
{
message_t *abc;
abc = create_message(10);
return EXIT_SUCCESS;
}


In C, we can declare arrays of objects as follows:

message array[4];

And we're guaranteed that each element is DIRECTLY after the other in
memory, such that we can use a pointer like so:

message *p = &array[0];
++p; //now it points to the 2nd element
++p; //now it points to the 3rd element
++p; //now it points to the 4th element

To facilitate this, the "sizeof" operator returns the full size of the
struct including any necessary padding at the end, such that the next
element in an array can be directly after it.

So, if you define a struct as follows:

struct Monkey { int i; int k; char b; };

It is very probable that it will take up the following amount of memory:

a) 4 bytes for "i"
b) 4 bytes for "k"
b) 1 byte for "b"
c) 3 bytes of padding so the next element can be right after it.

This gives us an overall size of 12 bytes.

Now here's my question:

If we define a structure which has an array at the end of it, how can we be
sure that there's no padding at the end?

-Tomás

Why do you care that there's padding? sizeof tells you all you need to
know doesn't it?
 

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,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top