473,387 Members | 1,705 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,387 software developers and data experts.

struct compatibility

Hi,

I'd like to know whether the following code is standard-compliant:
struct generic {
int x;
int a[1];
};
void f(struct generic *s)
{
int i;

for (i = 0; i < 10; i++)
s->a[i] = i;
}
int main(void)
{
struct special {
int x;
int a[10];
} s;

f((struct generic *) &s);

return 0;
}
Thanks,
Christian
Jan 31 '06 #1
6 1924
Le 31-01-2006, Christian Kandeler <ch****************@hob.de> a écrit*:
Hi,

I'd like to know whether the following code is standard-compliant:
struct generic {
int x;
int a[1];
};
void f(struct generic *s)
{
int i;

for (i = 0; i < 10; i++)
s->a[i] = i;
}
int main(void)
{
struct special {
int x;
int a[10];
} s;

f((struct generic *) &s);

return 0;
}


Interesting question...
If s was allocated on the heap, in C99, I think the code
would be standart because of compatibility with flexible
array member.

The standart says that, 6.7.2.1/16-18, if there exist
struct s {
int x;
int a[]; // No size !
};

Then, generic and s are 'compatible' when allocated
with malloc, and also are special and s.
In your example, there is no s, but I do not think
it will create any difference for compilers.
Marc Boyer
Jan 31 '06 #2
Christian Kandeler wrote:
Hi,

I'd like to know whether the following code is standard-compliant:
struct generic {
int x;
int a[1];
};

void f(struct generic *s)
{
int i;

for (i = 0; i < 10; i++)
s->a[i] = i;
}

int main(void)
{
struct special {
int x;
int a[10];
} s;

f((struct generic *) &s);

return 0;
}


No, it is not. Do you want a C99 or C89 answer?
Essentially, offsetof(struct generic, a) needs not
be equal to offsetof(struct special, a)...

BTW:
struct special {
struct generic access_me;
int a[10 - ((sizeof (struct generic) - offsetof(struct generic,
a))/sizeof (int))];
} s;
(with <stddef.h> included) gives you essentially the struct hack,
so you have no "additional badness" related to other struct layout.
The struct hack, even though not covered by the standard, works
presumably on all known implementations.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Jan 31 '06 #3
Michael Mair wrote:
Christian Kandeler wrote:
I'd like to know whether the following code is standard-compliant:

struct generic {
int x;
int a[1];
};

void f(struct generic *s)
{
int i;

for (i = 0; i < 10; i++)
s->a[i] = i;
}

int main(void)
{
struct special {
int x;
int a[10];
} s;

f((struct generic *) &s);

return 0;
}


No, it is not. Do you want a C99 or C89 answer?
Essentially, offsetof(struct generic, a) needs not
be equal to offsetof(struct special, a)...


Okay. But if I use a flexible array:

struct generic {
int x;
int a[];
}

is the offset the same, then? I'm not sure if I can deduce that from the
standard. If it is, does that make the rest of the code legal?
Christian
Feb 1 '06 #4
In article <44************@individual.net>,
Christian Kandeler <ch****************@hob.de> wrote:
Michael Mair wrote:
Christian Kandeler wrote:
I'd like to know whether the following code is standard-compliant:

struct generic {
int x;
int a[1];
};

void f(struct generic *s)
{
int i;

for (i = 0; i < 10; i++)
s->a[i] = i;
}

int main(void)
{
struct special {
int x;
int a[10];
} s;

f((struct generic *) &s);

return 0;
}


No, it is not. Do you want a C99 or C89 answer?
Essentially, offsetof(struct generic, a) needs not
be equal to offsetof(struct special, a)...


Okay. But if I use a flexible array:

struct generic {
int x;
int a[];
}

is the offset the same, then? I'm not sure if I can deduce that from the
standard. If it is, does that make the rest of the code legal?


With a flexible array, the offset if a is the same as the offset in
_some_ variant of the struct with fixed array size. Lets say the
compiler chooses one offset when the array size is < 10 and another one
if array size is >= 10, and no other offset, then the offset in the
flexible struct is one of those two offsets. But you don't know which
one.

The other difference is that with any fixed size array, the compiler can
assume that the index is within the bounds. If you use a fixed size
array of size 1, then the compiler can legally ignore the index you pass
and always access array element 0, because that is the only one that you
could access legally. With the flexible size array, the compiler must
produce code that works no matter how large the array is. So here you
have an improvement.
Feb 1 '06 #5
Le 01-02-2006, Christian Kandeler <ch****************@hob.de> a écrit*:
Michael Mair wrote:
Christian Kandeler wrote:
I'd like to know whether the following code is standard-compliant:

struct generic {
int x;
int a[1];
};

void f(struct generic *s)
{
int i;

for (i = 0; i < 10; i++)
s->a[i] = i;
}

int main(void)
{
struct special {
int x;
int a[10];
} s;

f((struct generic *) &s);

return 0;
}


No, it is not. Do you want a C99 or C89 answer?
Essentially, offsetof(struct generic, a) needs not
be equal to offsetof(struct special, a)...


Okay. But if I use a flexible array:

struct generic {
int x;
int a[];
}

is the offset the same, then? I'm not sure if I can deduce that from the
standard. If it is, does that make the rest of the code legal?


No. There was a restriction I had not seen at first glance 6.7.2.1/17.
"Assuming that all array membres are aligned the same".

You should malloc s or add some code like
assert( offsetof(generic, a) == offsetof(special, a) ).
Marc Boyer
Feb 1 '06 #6
On Tue, 31 Jan 2006 10:29:43 +0100, Christian Kandeler
<ch****************@hob.de> wrote:
Hi,

I'd like to know whether the following code is standard-compliant:
struct generic {
int x;
int a[1];
};
void f(struct generic *s)
{
int i;

for (i = 0; i < 10; i++)
s->a[i] = i;
}
int main(void)
{
struct special {
int x;
int a[10];
} s;

f((struct generic *) &s);
The standard guarantees that all pointers to struct have the same
representation. Therefore, casting the value of &s will produce a
representable result. It probably won't even change the
representation.

However, there is no guarantee that a struct special and a struct
generic have the same alignment. If a struct generic has a more
restrictive alignment that the struct special s does not meet, any
attempt to dereference the address, as is done in function f, results
in undefined behavior.

Furthermore, the compiler is allowed to insert different quantities of
padding between i and a in the two different structure types. It is
therefore possible that function f is storing its values in padding of
struct special s (if a struct special has the extra padding) or beyond
the end of struct special s (if a struct generic has the extra
padding). I'm not sure about the first but the second definitely
invokes undefined behavior.

Since it is possible for a compliant compiler to produce this
undefined behavior, the answer has to be the code is not compliant.

return 0;
}

Feb 5 '06 #7

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

Similar topics

3
by: Cgacc20 | last post by:
I have a c struct from old code that cannot be modified and I am trying to write a wrapper C++ class around it. This class is often passed as a pointer to some c functions of a library and I...
21
by: Kilana | last post by:
I see this all the time in code: typedef struct a_struct { ... }differentName, *differentNamePtr; I understand how I can use it, but could someone tell me why the above is
7
by: Razvan | last post by:
Hi ! Today I saw some code like this: struct foo { foo(foo* s2){ cout << "foo::foo"; }
13
by: Vincezo Ciaschini | last post by:
Supposing you have the following declaration in a header file: -- head.h -- struct s { int c; char v; #if defined(__cplusplus) s(); s(double); method1(int);
5
by: Martin Vorbrodt | last post by:
here's what i have: struct SCSI_CDB { .... union { struct { unsigned char address0; unsigned char address1; unsigned char address2;
4
by: Martin Vorbrodt | last post by:
why would you bother writing: typedef struct S { } S_t; instead of just: struct S { };
67
by: S.Tobias | last post by:
I would like to check if I understand the following excerpt correctly: 6.2.5#26 (Types): All pointers to structure types shall have the same representation and alignment requirements as each...
5
by: spasmous | last post by:
I'm looking into upgrading from version 2 to version 3 of the FFT code package FFTW (www.fftw.org). The two versions are incompatible - a lot of it has to do with changing from a complex struct...
2
by: Laurent Deniau | last post by:
I would like to know why the following small program does not compile (checked with gcc 4.1.2) and if the compiler behavior is correct: struct A; typedef void (T)(struct A*); void f(void) {...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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...

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.