473,796 Members | 2,559 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How come C allow structure members to be addressed like an array ?

#include <stdio.h>

typedef struct
{
double x, y, z;
}vector;

int main(void)
{
int i;
vector v;
double *cord;

v.x = 10;
v.y = 1;
v.z = 2;

cord = &v.x;

for(i = 0; i < 3; i++)
{
printf("%f\n", cord[i]);
}
return 0;
}

here's the output i get:
10.000000
1.000000
2.000000

which is the same as v

i don't how it happens as i was just trying some random ideas but
great stuff really. helped me to reduce some of my code to almost
1/3rd its size.
Jun 27 '08
85 2444
Ian Collins <ia******@hotma il.comwrites:
Tomás Ó hÉilidhe wrote:
>Others have explained the padding situation, but if you want re-
assurance, you might add a routine to the start of your code that
makes sure it's OK:

void EnsureItWorks(v oid)
{
Vector const v = { 99, 56, 42 };

if (99 == (&v.x)[0] &&
56 == (&v.x)[1] &&
42 == (&v.x)[2]) return;
(&v.x)[0] is guaranteed to be correct. The other two can be better
tested just by ensuring that

&v.x + 2 == &v.z

The value test could give a false positive if the padding between
elements happened to have the "right" value.
> puts("ERROR: There's padding in the Vector struct.");
exit(EXIT_FAILU RE);
}

int main(void) { EnsureItWorks() ; }
A very verbose way of writing

int main()
{
assert( sizeof(vector)= =sizeof(double) *3);
}
Except the structure can have padding at the end and still be suitable.

--
Ben.
Jun 27 '08 #11
Ian Collins <ia******@hotma il.comwrites:
viza wrote:
>Hi

On Sun, 15 Jun 2008 10:51:28 +1200, Ian Collins wrote:
>>Tomás Ó hÉilidhe wrote:
>>> if (99 == (&v.x)[0] &&
56 == (&v.x)[1] &&
42 == (&v.x)[2]) return;
puts("ERROR: There's padding in the Vector struct.");
exit(EXIT_FAILU RE);
>>A very verbose way of writing
assert( sizeof(vector)= =sizeof(double) *3);

The two are not equivalent and neither is perfect. Better is:

assert( offsetof(vector ,y) == sizeof(double)
&& offsetof(vector ,z) == sizeof(double)* 2 );
Why?
Tomás's code is over complex (one test is enough) and could fail in
unusual cases (see my other posting) and your test will be thrown if
there is padding at the end of the struct.
Anyway, if offsetof(vector ,z) == sizeof(double)* 2, how can
offsetof(vector ,y) be anything other than sizeof(double)?
Agreed. I still prefer my address test, though.

By the way, This is all about making the best of a bad job. To the
OP: if you want to index things, make them an array as Keith Thompson
suggested. In addition to using #define to name the elements one
could also do:

typedef struct {
double v[3];
} vector;

enum { x, y, z };

vector point;

so that one can write point.v[x] and so on (even x[&point] if you
want to make your readers do a double-take!).

--
Ben.
Jun 27 '08 #12
Ben Bacarisse wrote:
Ian Collins <ia******@hotma il.comwrites:
>viza wrote:
>>Hi

On Sun, 15 Jun 2008 10:51:28 +1200, Ian Collins wrote:
Tomás Ó hÉilidhe wrote:
if (99 == (&v.x)[0] &&
56 == (&v.x)[1] &&
42 == (&v.x)[2]) return;
puts("ERROR: There's padding in the Vector struct.");
exit(EXIT_FAILU RE);
A very verbose way of writing
assert( sizeof(vector)= =sizeof(double) *3);
The two are not equivalent and neither is perfect. Better is:

assert( offsetof(vector ,y) == sizeof(double)
&& offsetof(vector ,z) == sizeof(double)* 2 );
Why?

Tomás's code is over complex (one test is enough) and could fail in
unusual cases (see my other posting) and your test will be thrown if
there is padding at the end of the struct.
OK, make it

assert( sizeof(vector[2])==sizeof(doubl e)*6 );

Or even a compile time assert:

const int n = 1/( sizeof(vector[2])==sizeof(doubl e)*6 );
>Anyway, if offsetof(vector ,z) == sizeof(double)* 2, how can
offsetof(vecto r,y) be anything other than sizeof(double)?

Agreed. I still prefer my address test, though.
Fair enough, but the simplified offsetof (or sizeof) test has the
(small) advantage of not requiring an instance of vector to test.
Saying that, the address test could be evaluated at compile time, so the
vector would be eliminated by an optimiser.

--
Ian Collins.
Jun 27 '08 #13
Ian Collins <ia******@hotma il.comwrites:
Ben Bacarisse wrote:
>Ian Collins <ia******@hotma il.comwrites:
>>viza wrote:
Hi

On Sun, 15 Jun 2008 10:51:28 +1200, Ian Collins wrote:
Tomás Ó hÉilidhe wrote:
> if (99 == (&v.x)[0] &&
> 56 == (&v.x)[1] &&
> 42 == (&v.x)[2]) return;
> puts("ERROR: There's padding in the Vector struct.");
> exit(EXIT_FAILU RE);
A very verbose way of writing
assert( sizeof(vector)= =sizeof(double) *3);
The two are not equivalent and neither is perfect. Better is:

assert( offsetof(vector ,y) == sizeof(double)
&& offsetof(vector ,z) == sizeof(double)* 2 );

Why?

Tomás's code is over complex (one test is enough) and could fail in
unusual cases (see my other posting) and your test will be thrown if
there is padding at the end of the struct.
OK, make it

assert( sizeof(vector[2])==sizeof(doubl e)*6 );

Or even a compile time assert:

const int n = 1/( sizeof(vector[2])==sizeof(doubl e)*6 );
I think that this:

sizeof(vector) == sizeof(double) * 3

would suffice. An array of two thingies must have twice the size of a
single thingie, for any applicable value of "thingie".

[snip]

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #14
On Jun 15, 5:27 am, Keith Thompson <ks...@mib.orgw rote:
Ian Collins <ian-n...@hotmail.co mwrites:
Ben Bacarisse wrote:
Ian Collins <ian-n...@hotmail.co mwrites:
>viza wrote:
Hi
>>On Sun, 15 Jun 2008 10:51:28 +1200, Ian Collins wrote:
Tomás Ó hÉilidhe wrote:
if (99 == (&v.x)[0] &&
56 == (&v.x)[1] &&
42 == (&v.x)[2]) return;
puts("ERROR: There's padding in the Vector struct.");
exit(EXIT_FAILU RE);
A very verbose way of writing
assert( sizeof(vector)= =sizeof(double) *3);
The two are not equivalent and neither is perfect. Better is:
>>assert( offsetof(vector ,y) == sizeof(double)
&& offsetof(vector ,z) == sizeof(double)* 2 );
>Why?
Tomás's code is over complex (one test is enough) and could fail in
unusual cases (see my other posting) and your test will be thrown if
there is padding at the end of the struct.
OK, make it
assert( sizeof(vector[2])==sizeof(doubl e)*6 );
Or even a compile time assert:
const int n = 1/( sizeof(vector[2])==sizeof(doubl e)*6 );

I think that this:

sizeof(vector) == sizeof(double) * 3

would suffice. An array of two thingies must have twice the size of a
single thingie, for any applicable value of "thingie".
vector is not an array, it's a struct.
This:
struct vector { double x, y, z; };
sizeof(struct vector)
Needs not to evaluate to sizeof (double) * 3.
If it were a vector (array), then yes, it is guaranteed and you are
correct.
But vector is a struct.

Thomas: Please change your name to ASCII.
Jun 27 '08 #15
Keith Thompson wrote:
Ian Collins <ia******@hotma il.comwrites:
>Ben Bacarisse wrote:
>>Tomás's code is over complex (one test is enough) and could fail in
unusual cases (see my other posting) and your test will be thrown if
there is padding at the end of the struct.
OK, make it

assert( sizeof(vector[2])==sizeof(doubl e)*6 );

Or even a compile time assert:

const int n = 1/( sizeof(vector[2])==sizeof(doubl e)*6 );

I think that this:

sizeof(vector) == sizeof(double) * 3

would suffice. An array of two thingies must have twice the size of a
single thingie, for any applicable value of "thingie".
It would, my last suggestion was pointless. It would still fail if
there were padding at the end of the struct. I would still use the one
above, the chances of padding at the end but not in the middle are slim.

--
Ian Collins.
Jun 27 '08 #16
vi******@gmail. com said:

<snip>
Thomas: Please change your name to ASCII.
Won't that get rather confusing?

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #17
vi******@gmail. com writes:
On Jun 15, 5:27 am, Keith Thompson <ks...@mib.orgw rote:
>Ian Collins <ian-n...@hotmail.co mwrites:
Ben Bacarisse wrote:
Ian Collins <ian-n...@hotmail.co mwrites:
>>viza wrote:
Hi
>>>On Sun, 15 Jun 2008 10:51:28 +1200, Ian Collins wrote:
Tomás Ó hÉilidhe wrote:
> if (99 == (&v.x)[0] &&
> 56 == (&v.x)[1] &&
> 42 == (&v.x)[2]) return;
> puts("ERROR: There's padding in the Vector struct.");
> exit(EXIT_FAILU RE);
A very verbose way of writing
assert( sizeof(vector)= =sizeof(double) *3);
The two are not equivalent and neither is perfect. Better is:
>>>assert( offsetof(vector ,y) == sizeof(double)
&& offsetof(vector ,z) == sizeof(double)* 2 );
>>Why?
>Tomás's code is over complex (one test is enough) and could fail in
unusual cases (see my other posting) and your test will be thrown if
there is padding at the end of the struct.
OK, make it
assert( sizeof(vector[2])==sizeof(doubl e)*6 );
Or even a compile time assert:
const int n = 1/( sizeof(vector[2])==sizeof(doubl e)*6 );

I think that this:

sizeof(vector) == sizeof(double) * 3

would suffice. An array of two thingies must have twice the size of a
single thingie, for any applicable value of "thingie".
vector is not an array, it's a struct.
This:
struct vector { double x, y, z; };
sizeof(struct vector)
Needs not to evaluate to sizeof (double) * 3.
If it were a vector (array), then yes, it is guaranteed and you are
correct.
But vector is a struct.
Yes, I understand that. But vector[2] is an array type. My point
was that this:
assert(sizeof(v ector[2]) == sizeof(double) * 6);
is equivalent to this:
assert(sizeof(v ector) == sizeof(double) * 3);

In both cases, the asserted expression isn't guaranted to be true --
which is the whole point of the assert().

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #18
Ian Collins <ia******@hotma il.comwrites:
Keith Thompson wrote:
>Ian Collins <ia******@hotma il.comwrites:
>>Ben Bacarisse wrote:
>>>Tomás's code is over complex (one test is enough) and could fail in
unusual cases (see my other posting) and your test will be thrown if
there is padding at the end of the struct.

OK, make it

assert( sizeof(vector[2])==sizeof(doubl e)*6 );

Or even a compile time assert:

const int n = 1/( sizeof(vector[2])==sizeof(doubl e)*6 );

I think that this:

sizeof(vector) == sizeof(double) * 3

would suffice. An array of two thingies must have twice the size of a
single thingie, for any applicable value of "thingie".
It would, my last suggestion was pointless. It would still fail if
there were padding at the end of the struct. I would still use the one
above, the chances of padding at the end but not in the middle are slim.
I'd say the chances of padding at the end are higher than the chances
of padding in the middle.

Consider
struct foo { char a; char b; char c; };

It's plausible that sizeof(struct foo) == 4, with a padding byte at
the end.

This is less likely to happen for a struct containing doubles, though.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #19
Antoninus Twink wrote:
On 14 Jun 2008 at 22:34, Tomás Ó hÉilidhe wrote:
> Vector const v = { 99, 56, 42 };

if (99 == (&v.x)[0] &&
56 == (&v.x)[1] &&
42 == (&v.x)[2]) return;

Holy crap, are you trying to follow the CBF anti-style rules?
>(I know that floating-point arithmetic isn't exact but as far as I
know it's exact for integer values... but I'm open to correction!)

It's nothing to do with integer values. Just passing around a
floating-point value won't magically change its bits.

In

double a=42;
double b=42.422242;
double c=1./3;
assert(a == 42);
assert(b == 42.422242);
assert(c == 1./3);

all the asserts will succeed.
I think you're missing the point. Tomás wantes to check whether it is safe
to assume that struct {double a;double; double c;} can be interpreted as
double[3], i.e. whether there are any padding bytes in the struct that would
prevent that.
And it seems on anything but a DS9K it is save to assume that no padding
bytes are between the members (of equal typr), but it is very well possible
that there are some after the last member.

Bye, Jojo
Bye, Jojo
Jun 27 '08 #20

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

Similar topics

19
6877
by: Thomas Matthews | last post by:
Hi, Given a structure of pointers: struct Example_Struct { unsigned char * ptr_buffer; unsigned int * ptr_numbers; }; And a function that will accept the structure:
4
2825
by: Thomas Matthews | last post by:
Hi, I'm writing code for an embedded system. In the system a Timer has 4 memory mapped registers of 32-bit lengths in contiguous locations: Timer 0: 0x1000 Configuration register 0x1004 Control register 0x1008 Input register 0x100C Output register.
6
4206
by: Eric Smith | last post by:
Is a structure containing an incomplete array as its last element (per paragraph 2 of section 6.7.2.1 of ISO/IEC 9899:1999 (E)) itself an incomplete type? That appears to be indicated by paragraph 22 of section 6.2.5. If so, that seems to make it difficult to allocate such structures, because sizeof() is not allowed on incomplete types (paragraph 1 of section 6.5.3.4). For instance, I've routinely done things like this: struct foo {...
11
2416
by: Mannequin* | last post by:
Hi all, I'm working on a quick program to bring the Bible into memory from a text file. Anyway, I have three questions to ask. First, is my implementation of malloc () correct in the program to follow? Second, have I correctly passed the structure's pointer to the functions in this program?
15
2789
by: damian birchler | last post by:
Hi I'm wondering of what type a structure is. Of course, it is a _structure_, but an array isn't an _array_ either. So of what type is a structure? I'd say a pointer, am I right?
10
2134
by: nambissan.nisha | last post by:
I am facing this problem.... I have to define a structure at runtime as the user specifies... The user will tell the number of fields,the actual fields...(maybe basic or array types or multiple arrays,etc) I do not understand how to define the structure at run time.i.e.what fields it will contain.
6
3026
by: noone | last post by:
What is the syntax to access members of a structure without explicitly naming the structure in every access? struct mytype { int a; char* b; long c; } IT; How can I access the structure members in a way similar to the old pascal
5
35801
Banfa
by: Banfa | last post by:
I thought I would write a little article about this because it is regularly asked as a question in the Forums. Firstly this is a C++ issue, it is strictly against the rules of C to create a class with no members. This makes sense because the only real use for a structure or class with no data members and virtual functions is as the base from which to derive other classes and structures or as a container for non-virtual methods. The reason...
5
3800
by: =?Utf-8?B?QXlrdXQgRXJnaW4=?= | last post by:
Hi Willy, Thank you very much for your work. C++ code doesnot make any serialization. So at runtime C# code gives an serialization error at "msg_file_s sa = (msg_file_s) bf.Deserialize(ms);" I thought that it is very hard to memory map structure array. I need both read and write memory mapped file at both side of C# and C++.
0
9673
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9525
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10221
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9050
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6785
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5569
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4115
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3730
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2924
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.