473,387 Members | 1,532 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.

cast struct question

Hi All,

This question has to do with interface design. Suppose I have an translation
tool. It can translates structs from type "general" to other types and then
does some processing.

Example:

typedef struct
{
int data1;
int data2;
}general;

typedef struct
{
int data3;
}specific_a;

For example, the translation looks like this:

void translate1(general * input)
{
specific_a * new_specific_a = malloc (.....);
new_specific_a->data3 = input->data1 * input->data2;

/* use here new_specific_a for a while */
}

Suppose have another type:
typedef struct
{
int data4;
int data5;
}specific_b;

In this specific case another translation looks like:

void translate2(general * input)
{
specific_b * new_specific_b = malloc(....);
new_specific_b->data4 = input->data1;
new_specific_b->data5 = input->data2;

/* do some processing with new_specific_b */

}

Because other interfaces are fixed I need type "specific_a" in the
"translate1" method and "specific_b" in "translate2".

I see an optimalization here in the translate2 method, namely:
void translate2(general * input)
{
specific_b * new_specific_b = (specific_b *) input;
}

(Note: I use the structures specific_b and specific_a only for reading).

Instead of generating the new message, I want to cast the struct (because in
this specific case the data items match exactly). Is this allowed?? In other
words, returns a call to new_specific_b->data4 return data1 and
new_specific_b->data5 return data2 or are there some compiler issues to take
keep in mind?

Grz Milux

Jun 11 '07 #1
12 5497
Milux wrote On 06/11/07 13:01,:
Hi All,

This question has to do with interface design. Suppose I have an translation
tool. It can translates structs from type "general" to other types and then
does some processing.

Example:

typedef struct
{
int data1;
int data2;
}general;

typedef struct
{
int data3;
}specific_a;

For example, the translation looks like this:

void translate1(general * input)
{
specific_a * new_specific_a = malloc (.....);
new_specific_a->data3 = input->data1 * input->data2;

/* use here new_specific_a for a while */
}

Suppose have another type:
typedef struct
{
int data4;
int data5;
}specific_b;

In this specific case another translation looks like:

void translate2(general * input)
{
specific_b * new_specific_b = malloc(....);
new_specific_b->data4 = input->data1;
new_specific_b->data5 = input->data2;

/* do some processing with new_specific_b */

}

Because other interfaces are fixed I need type "specific_a" in the
"translate1" method and "specific_b" in "translate2".

I see an optimalization here in the translate2 method, namely:
void translate2(general * input)
{
specific_b * new_specific_b = (specific_b *) input;
}

(Note: I use the structures specific_b and specific_a only for reading).

Instead of generating the new message, I want to cast the struct (because in
this specific case the data items match exactly). Is this allowed?? In other
words, returns a call to new_specific_b->data4 return data1 and
new_specific_b->data5 return data2 or are there some compiler issues to take
keep in mind?
In some very specific circumstances (which don't
apply here), the language requires the type punning
to work. The way most compilers make it work in those
special circumstances has the side-effect of making it
work even in cases like yours, where strictly speaking
it is not guaranteed. You are stepping outside the
bounds of the language's guarantees, but the chance
that it will cause trouble is small.

... except that the chance of trouble approaches
100% as time goes by. The two struct types are perfect
matches today, but what will happen to them as the
program is maintained, refined, and extended? You are
pinning your hopes on nothing more than a coincidence,
really. Somebody, someday will change one or the other
of the two "identical twin" structs, and all of a sudden
things will stop working.

You may think that you can solve this problem by
putting great big comment blocks on both structs, warning
the programmer who changes one of them that he must make
the same change in the other. Take it from a battle-
scarred veteran: This does *not* work in the long run.
The compiler does not enforce what you say in comments,
and mistakes *will* happen. Besides, the programmers who
read the comments will curse your name: You will have
violated an important principle of safe implementation
that states there should be exactly one authoritative
description of each data type, function, interface, or
other "thing" in the program. One and only one -- because
as soon as there are two, there can be disagreement.

You are erecting a house of cards on a day when the
air is still, even though you know for certain that
hurricanes will eventually come. Build your card house
if you insist -- but I for one will not sell you an
insurance policy on it.

--
Er*********@sun.com
Jun 11 '07 #2
On Jun 11, 6:00 pm, Eric Sosman <Eric.Sos...@sun.comwrote:
Milux wrote On 06/11/07 13:01,:
Instead of generating the new message, I want to cast the struct (because in
this specific case the data items match exactly). Is this allowed?? In other
words, returns a call to new_specific_b->data4 return data1 and
new_specific_b->data5 return data2 or are there some compiler issues to take
keep in mind?

In some very specific circumstances (which don't
apply here), the language requires the type punning
to work. The way most compilers make it work in those
special circumstances has the side-effect of making it
work even in cases like yours, where strictly speaking
it is not guaranteed. You are stepping outside the
bounds of the language's guarantees, but the chance
that it will cause trouble is small.
Why is this not guaranteed behavior? Is a compiler allowed to generate
struct{int,int} with varying memory footprints? If so, can you please
elaborate what freedoms a compiler has in this case?

I had always thought struct guaranteed the order of the elements. Is
this accurate?
... except that the chance of trouble approaches
100% as time goes by. The two struct types are perfect
matches today, but what will happen to them as the
program is maintained, refined, and extended? You are
pinning your hopes on nothing more than a coincidence,
really. Somebody, someday will change one or the other
of the two "identical twin" structs, and all of a sudden
things will stop working.
The OP did not provide sufficient context to make this conclusion.
Many structures never change by their very definition.

Jun 11 '07 #3
Richard Urich wrote On 06/11/07 15:44,:
On Jun 11, 6:00 pm, Eric Sosman <Eric.Sos...@sun.comwrote:
>>Milux wrote On 06/11/07 13:01,:
>>>Instead of generating the new message, I want to cast the struct (because in
this specific case the data items match exactly). Is this allowed?? In other
words, returns a call to new_specific_b->data4 return data1 and
new_specific_b->data5 return data2 or are there some compiler issues to take
keep in mind?

In some very specific circumstances (which don't
apply here), the language requires the type punning
to work. The way most compilers make it work in those
special circumstances has the side-effect of making it
work even in cases like yours, where strictly speaking
it is not guaranteed. You are stepping outside the
bounds of the language's guarantees, but the chance
that it will cause trouble is small.


Why is this not guaranteed behavior? Is a compiler allowed to generate
struct{int,int} with varying memory footprints? If so, can you please
elaborate what freedoms a compiler has in this case?
We hashed this out a couple weeks ago, in a thread
titled "Is this legal? Aesthetically acceptable?". Read
through it, and come back if you still have questions.
I had always thought struct guaranteed the order of the elements. Is
this accurate?
Yes, but it's not enough to ensure that the O.P.'s
code will work.
> ... except that the chance of trouble approaches
100% as time goes by. The two struct types are perfect
matches today, but what will happen to them as the
program is maintained, refined, and extended? You are
pinning your hopes on nothing more than a coincidence,
really. Somebody, someday will change one or the other
of the two "identical twin" structs, and all of a sudden
things will stop working.

The OP did not provide sufficient context to make this conclusion.
Many structures never change by their very definition.
It seems you've never met Major Murphy:

http://en.wikipedia.org/wiki/Edward_A._Murphy%2C_Jr.

Seriously, if two things are supposed to be -- in fact,
required to be -- identical, they should probably be just
one thing. Otherwise, the proper operation of the program
rests on nothing sturdier than a coincidence. Those of us
who *have* made the Major's acquaintance are distrustful
of mere coincidence.

--
Er*********@sun.com
Jun 11 '07 #4
On Jun 11, 8:43 pm, Eric Sosman <Eric.Sos...@sun.comwrote:
Richard Urich wrote On 06/11/07 15:44,:
Why is this not guaranteed behavior? Is a compiler allowed to generate
struct{int,int} with varying memory footprints? If so, can you please
elaborate what freedoms a compiler has in this case?

We hashed this out a couple weeks ago, in a thread
titled "Is this legal? Aesthetically acceptable?". Read
through it, and come back if you still have questions.
Thank you for letting me know about the article. It was worth the
read, but unfortunately I could not figure out how to apply it to this
example.

Since struct{int,int} S1 need not be equivalent to struct{int,int} S2,
which of these assumptions is not valid? Or is there another
assumption I have failed to enumerate below?

- the alignment requirements of a type (int) is constant throughout a
compiler
- a struct will maintain program order for all elements
- a struct will pad after each variable only enough to meet the
alignment for the next variable's type (int)
The OP did not provide sufficient context to make this conclusion.
Many structures never change by their very definition.

It seems you've never met Major Murphy:

http://en.wikipedia.org/wiki/Edward_A._Murphy%2C_Jr.

Seriously, if two things are supposed to be -- in fact,
required to be -- identical, they should probably be just
one thing. Otherwise, the proper operation of the program
rests on nothing sturdier than a coincidence. Those of us
who *have* made the Major's acquaintance are distrustful
of mere coincidence.

--
Eric.Sos...@sun.com
A network-aligned item and a host-aligned item can be identical on a
given architecture, yet I feel the items should still hold
distinction. I have used type-casting of structs in this instance
before (if same alignment, cast; else, byteswap), and apparently this
was non-portable code. Without devolving into a style debate, can you
please explain why these casts can fail for structs?

My sincere gratitude for the help,

Richard Urich

Jun 11 '07 #5
Richard Urich wrote:
Eric Sosman <Eric.Sos...@sun.comwrote:
.... snip ...
>
>... except that the chance of trouble approaches 100% as time
goes by. The two struct types are perfect matches today, but
what will happen to them as the program is maintained, refined,
and extended? You are pinning your hopes on nothing more than a
coincidence, really. Somebody, someday will change one or the
other of the two "identical twin" structs, and all of a sudden
things will stop working.

The OP did not provide sufficient context to make this conclusion.
Many structures never change by their very definition.
Ah, you have a vision of the future, and know how the program will
be modified, maintained, refined, extended in that future. How did
you acquire this very useful ability?

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 11 '07 #6
Richard Urich wrote:
[... about type-punning between "identically arranged" structs ...]

A network-aligned item and a host-aligned item can be identical on a
given architecture, yet I feel the items should still hold
distinction. I have used type-casting of structs in this instance
before (if same alignment, cast; else, byteswap), and apparently this
was non-portable code. Without devolving into a style debate, can you
please explain why these casts can fail for structs?
The point is that the distinct items should be treated
as such, and the program should not try to gloss over the
distinction. It may happen that on Machine M the two variants
are in fact identical -- but does that mean that a program
should rely on this coincidence of representation? No, I'd
say, because on Machine N where the variants differ in some
way the program will break. That's a fragile program; I have
a distaste for fragile programs.

The O.P. noticed that two of his structs just happened to
have similar members and in a similar order, and he tried to
achieve an "optimalization" by pretending the two structs were
identical. I advise against this course unless they truly
*are* identical, and the only way I know of to be sure of that
is to arrange that they are in fact the same struct type.

And, as I said at the end of my original response, the O.P.
is at liberty to ignore my advice and to persist in his folly;
it's not my funeral. (Cue the Therac-25 reference -- but that
was, in fairness, a different sort of problem altogether. Still,
it serves as a sobering, or even terrifying reminder that code
has a way of outlasting its original design parameters.)

--
Eric Sosman
es*****@acm-dot-org.invalid
Jun 12 '07 #7
CBFalconer wrote:
Richard Urich wrote:
>Eric Sosman <Eric.Sos...@sun.comwrote:
... snip ...
>>... except that the chance of trouble approaches 100% as time
goes by. The two struct types are perfect matches today, but
what will happen to them as the program is maintained, refined,
and extended? You are pinning your hopes on nothing more than a
coincidence, really. Somebody, someday will change one or the
other of the two "identical twin" structs, and all of a sudden
things will stop working.
The OP did not provide sufficient context to make this conclusion.
Many structures never change by their very definition.

Ah, you have a vision of the future, and know how the program will
be modified, maintained, refined, extended in that future. How did
you acquire this very useful ability?
In fairness to the poor, benighted, ignorant sod -- 'scuse
me, to the "aspirant" -- you and I are overstating the likelihood
that maintenance and modification will break anything that isn't
nailed down. I said it approached 100%, and while that may be
true I conveniently didn't say anything about the rate of approach.
It could be that the half-life of bug appearance might be on the
order of a few million years.

... but you and I, Chuck, bitter experience tells us that it's
on the order of a few million milliseconds. "Oh, ay; and you try
and tell the young people of today that, and they won't believe
you!"

--
Eric Sosman
es*****@acm-dot-org.invalid
Jun 12 '07 #8
On Jun 12, 1:54 am, Eric Sosman <esos...@acm-dot-org.invalidwrote:
The O.P. noticed that two of his structs just happened to
have similar members and in a similar order, and he tried to
achieve an "optimalization" by pretending the two structs were
identical. I advise against this course unless they truly
*are* identical, and the only way I know of to be sure of that
is to arrange that they are in fact the same struct type.
The OP noticed he had two structs with identically-typed, identically-
ordered members. He asked if, under those specific circumstances, the
C Standard guarantees they are identical.

You have claimed two structs that are identically coded are, in fact,
not identical as far as C is concerned. I am merely asking for some
guidance on where in the rather lengthy standard I might look to find
supporting evidence for this claim.

The draft standard does show 6.7.2.1#16:
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.

This implies to me that it is safe to cast from one identically-coded
struct to another. If there is some part of the standard which
overrides this behavior, please let me know.
Richard Urich

Jun 12 '07 #9
Richard Urich <Ri**********@gmail.comwrites:
On Jun 12, 1:54 am, Eric Sosman <esos...@acm-dot-org.invalidwrote:
> The O.P. noticed that two of his structs just happened to
have similar members and in a similar order, and he tried to
achieve an "optimalization" by pretending the two structs were
identical. I advise against this course unless they truly
*are* identical, and the only way I know of to be sure of that
is to arrange that they are in fact the same struct type.

The OP noticed he had two structs with identically-typed, identically-
ordered members. He asked if, under those specific circumstances, the
C Standard guarantees they are identical.

You have claimed two structs that are identically coded are, in fact,
not identical as far as C is concerned. I am merely asking for some
guidance on where in the rather lengthy standard I might look to find
supporting evidence for this claim.

The draft standard does show 6.7.2.1#16:
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.

This implies to me that it is safe to cast from one identically-coded
struct to another. If there is some part of the standard which
overrides this behavior, please let me know.
The example specifically assumes that all array members are aligned
the same. The standard does not guarantee that.

I don't think you'll find a specific passage in the standard that says
two identically declared structures aren't guaranteed to have the same
layout. The point is that you won't find a passage that says they
*are* guaranteed to have the same layout.

The ordering of structure members is guaranteed, but the amount of
padding is not. The compiler is not reuqired to use only the minimal
padding required for alignment.

See also C99 6.5.2.3p5:

One special guarantee is made in order to simplify the use of
unions: if a union contains several structures that share a common
initial sequence (see below), and if the union object currently
contains one of these structures, it is permitted to inspect the
common initial part of any of them anywhere that a declaration of
the complete type of the union is visible. Two structures share a
_common initial sequence_ if corresponding members have compatible
types (and, for bit-fields, the same widths) for a sequence of one
or more initial members.

This is guaranteed *only* when the structures are members of a union.
If they aren't, all bets are off.

In practice, it's very likely that you can get away with assuming the
same layout for sufficiently similar structure types. But it's safer,
and much clearer, simply to declare a single structure type so you
*know* that it will always have the same layout.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 12 '07 #10
Richard Urich wrote On 06/12/07 12:56,:
On Jun 12, 1:54 am, Eric Sosman <esos...@acm-dot-org.invalidwrote:
> The O.P. noticed that two of his structs just happened to
have similar members and in a similar order, and he tried to
achieve an "optimalization" by pretending the two structs were
identical. I advise against this course unless they truly
*are* identical, and the only way I know of to be sure of that
is to arrange that they are in fact the same struct type.


The OP noticed he had two structs with identically-typed, identically-
ordered members. He asked if, under those specific circumstances, the
C Standard guarantees they are identical.

You have claimed two structs that are identically coded are, in fact,
not identical as far as C is concerned. I am merely asking for some
guidance on where in the rather lengthy standard I might look to find
supporting evidence for this claim.
Sorry; I misunderstood your question. The passage
that says the two types are incompatible is 6.2.7p1,
third sentence. The description of the special case in
which the type-punning *is* safe is 6.5.2.3p5.
The draft standard does show 6.7.2.1#16:
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.

This implies to me that it is safe to cast from one identically-coded
struct to another. If there is some part of the standard which
overrides this behavior, please let me know.
Note the words "assuming that," which describe a
precondition the language allows but does not require.
Also, examples aren't normative.

--
Er*********@sun.com
Jun 12 '07 #11
On Jun 12, 5:38 pm, Eric Sosman <Eric.Sos...@sun.comwrote:
Sorry; I misunderstood your question. The passage
that says the two types are incompatible is 6.2.7p1,
third sentence. The description of the special case in
which the type-punning *is* safe is 6.5.2.3p5.
Thank you. This is exactly what I was looking for.

Jun 12 '07 #12
Richard Urich wrote:
>
.... snip ...
>
The OP noticed he had two structs with identically-typed, identically-
ordered members. He asked if, under those specific circumstances, the
C Standard guarantees they are identical.

You have claimed two structs that are identically coded are, in fact,
not identical as far as C is concerned. I am merely asking for some
guidance on where in the rather lengthy standard I might look to find
supporting evidence for this claim.
.... snip ...
>
This implies to me that it is safe to cast from one identically-coded
struct to another. If there is some part of the standard which
overrides this behavior, please let me know.
Why bother? At worst, you need a typedef for the common object
type, and then declare two objects of that type. No casts (which
are probably errors) needed.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 12 '07 #13

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

Similar topics

31
by: Jamie Burns | last post by:
Hello, I am writing a client / server application. There is 1 server, and many clients. The server processes requests from each client, and typically creates and manipulates C++ objects on their...
4
by: William Payne | last post by:
Hello! If a cast from a void pointer to a pointer to a struct fails at runtime, is NULL the result? I.E, is this code meaningful: struct my_struct_t foo* = (struct my_struct_t*)void_pointer; //...
11
by: Alberto Giménez | last post by:
Hi, I've seen some object oriented programming bits out there and i'm not sure if they're legal. For example: struct Object { int field1; int field2; }; struct SubObject { int field1; /*...
28
by: Tamir Khason | last post by:
Follwing the struct: public struct TpSomeMsgRep { public uint SomeId;
6
by: Jack | last post by:
Is it possible to cast a 4-byte data type (e.g. an unsigned int) to a 4-byte struct? Sometimes the HIWORD and LOWORD of a 4-byte value contain information independent of each other. Is there a...
10
by: Grizlyk | last post by:
1. Can abybody explain me why C++ function can not be overloaded by its return type? Return type can has priority higher than casting rules. For example: char input(); //can be compiled to name...
6
by: Nick Keighley | last post by:
Hi, Is this code fundamentally broken? class B { } class D: public B {
7
by: * Tong * | last post by:
Hi, I couldn't figure out how to properly type cast in this case: $ cat -n type_cast.c 1 #include <stdio.h> 2 3 typedef unsigned char Byte; 4 typedef signed char Small_Int; 5
7
by: Noah Roberts | last post by:
Consider the following hierarchy: struct record { }; struct test_record { };
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
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: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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: 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
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...

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.