470,849 Members | 681 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,849 developers. It's quick & easy.

Data initialization (is this correct?)

I would like to know if the following operation on s2 is legal or not.
And if not what should I do instead (my data member are declared at the
begining of the struct).
I am pretty sure this is illegal, but I would like to avoid duplicating
the logic that take place when initializing s1.

Thanks for your help.
Mathieu

(*)
#include <iostream>

struct String
{
char Internal[4+1];
void Print() {
std::cout << Internal << std::endl;
}
};

int main()
{
String s1 = {"019Y"}; // give compiler error if too large
s1.Print();

String s2;
char array[] = "123D";
s2 = reinterpret_cast<String&>( array ); // is this legal
s2.Print();
return 0;
}

May 27 '06 #1
14 1629
In article <1148696512.476379.294630
@i39g2000cwa.googlegroups.com>,
ma***************@gmail.com says...

[ ... ]
String s2;
char array[] = "123D";
s2 = reinterpret_cast<String&>( array ); // is this legal


That depends on what you mean by "legal". It doesn't give
defined results, if that's what you mean.

--
Later,
Jerry.

The universe is a figment of its own imagination.
May 27 '06 #2
mathieu wrote:
I would like to know if the following operation on s2 is legal or not.
And if not what should I do instead (my data member are declared at the
begining of the struct).

struct String
{
char Internal[4+1];
void Print() {
std::cout << Internal << std::endl;
}
};
Kind of an odd struct -- is this something you're actually attempting
to use, or a dumbed-down example? If the latter, fine. If the
former... reconsider.
String s1 = {"019Y"}; // give compiler error if too large
s1.Print();

String s2;
char array[] = "123D";
s2 = reinterpret_cast<String&>( array ); // is this legal

I am pretty sure this is illegal
It's not technically illegal, but as with any use of reinterpret_cast,
there is no guarantee whatsoever as to what the result could be. It's
100% implementation-defined and non-portable. Whatever you're trying
to achieve, reinterpret_cast is not the way.
but I would like to avoid duplicating
the logic that take place when initializing s1.


Could you explain what you mean by this? There's not really any logic
to speak of. Are you attempting to optimize for speed? Avoid code
duplication? I don't think either is happening here.

Luke

May 27 '06 #3
mathieu posted:

s2 = reinterpret_cast<String&>( array ); // is this legal

Yes, it's perfectly okay. I'll show you why. Firstly the Standard
guarantees that the following is pefectly legal:

struct Monkey {
int array[10];
};

int main()
{
Monkey obj;

int (&array)[10] =
reinterpret_cast<int (&)[10]>(obj);

array[3] = 7;
}
Therefore the reverse must be true:
struct Monkey {
int array[10];
};

int main()
{
int array[10];

Monkey &monkey =
reinterpret_cast<Monkey &>(array);

monkey.array[3] = 7;
}
However, this only holds true for a POD. Here's the relevant passage from
the Standard:

9.2 p17: A pointer to a POD-struct, suitably converted using a
reinterpret_cast, points to its initial member (of if that member is a bit-
field, then to the unit in which it resides) and vice versa."
-Tomás
May 27 '06 #4
Jerry Coffin posted:
In article <1148696512.476379.294630
@i39g2000cwa.googlegroups.com>,
ma***************@gmail.com says...

[ ... ]
String s2;
char array[] = "123D";
s2 = reinterpret_cast<String&>( array ); // is this legal


That depends on what you mean by "legal". It doesn't give
defined results, if that's what you mean.


I disagree:

9.2 p17: "A pointer to a POD-struct, suitably converted using a
reinterpret_cast, points to its initial member (of if that member is a bit-
field, then to the unit in which it resides) and vice versa."

I demonstrate exploitation of this feature elsewhere in the thread.

-Tomás
May 27 '06 #5
In article <O5******************@news.indigo.ie>,
No.Email@Address says...

[ ... ]
I disagree:

9.2 p17: "A pointer to a POD-struct, suitably converted using a
reinterpret_cast, points to its initial member (of if that member is a bit-
field, then to the unit in which it resides) and vice versa."


Rereading his definition of String, you're right. I
apologize for the misinformation.

--
Later,
Jerry.

The universe is a figment of its own imagination.
May 27 '06 #6
On Sat, 27 May 2006 17:33:39 GMT, "Tomás" <No.Email@Address> wrote:
mathieu posted:
s2 = reinterpret_cast<String&>( array ); // is this legal


Yes, it's perfectly okay. I'll show you why. Firstly the Standard
guarantees that the following is pefectly legal:

struct Monkey {
int array[10];
};

int main()
{
Monkey obj;

int (&array)[10] =
reinterpret_cast<int (&)[10]>(obj);

array[3] = 7;
}
Therefore the reverse must be true:


Nope. It probably 'works' in most cases but it's not correct C++, not
even for PODs.

Best wishes,
Roland Pibinger

May 27 '06 #7
Roland Pibinger posted:

Therefore the reverse must be true:


Nope. It probably 'works' in most cases but it's not correct C++, not
even for PODs.

Care to elaborate on that?
Here's my logic:

We start off with a simple POD as follows:

struct Monkey { int array[10]; };
We can convert a "Monkey*" to a "int (*)[10]", and we can subsequently
use that pointer to access the array, i.e.:

Monkey obj;

int (*array)[10] = reinterpret_cast<int (*)[10]>(&obj);

(*array)[3] = 72;
Why do you suppose that the opposite cannot be done:

int array[10];

Monkey *p_monkey =
reinterpret_cast<Monkey*>( &array );

p_monkey->array[3] = 56;
-Tomás
May 27 '06 #8
On Sat, 27 May 2006 20:10:37 GMT, "Tomás" <No.Email@Address> wrote:
Roland Pibinger posted:
Therefore the reverse must be true:
Nope. It probably 'works' in most cases but it's not correct C++, not
even for PODs.


Care to elaborate on that?

Here's my logic:
We start off with a simple POD as follows:

struct Monkey { int array[10]; };

We can convert a "Monkey*" to a "int (*)[10]", and we can subsequently
use that pointer to access the array, i.e.:


Ok
Monkey obj;
int (*array)[10] = reinterpret_cast<int (*)[10]>(&obj);
(*array)[3] = 72;

Why do you suppose that the opposite cannot be done:

int array[10];
Monkey *p_monkey =
reinterpret_cast<Monkey*>( &array );
p_monkey->array[3] = 56;


You can only convert beetween a POD-stuct and its first data member
(and vice versa), not between an arbitrary 'int[10]' and 'struct
Monkey'. Monkey may be larger than array: sizeof (Monkey) >= sizeof
(array). Even alignment restricitions might be different (unlikely).

Best wishes,
Roland Pibinger
May 27 '06 #9
Roland Pibinger posted:

You can only convert beetween a POD-stuct and its first data member
(and vice versa), not between an arbitrary 'int[10]' and 'struct
Monkey'. Monkey may be larger than array: sizeof (Monkey) >= sizeof
(array).

I don't see how this would be a problem if we only use the resultant
Monkey* to access the struct's first member.

Even alignment restricitions might be different (unlikely).

Interesting point. I wonder if that's possible... ?
-Tomás
May 27 '06 #10

Luke Meyers wrote:
Kind of an odd struct -- is this something you're actually attempting
to use, or a dumbed-down example? If the latter, fine. If the
former... reconsider.

If you have nothing to do for memorial day here is the full source:
http://svn.sourceforge.net/viewcvs.c...?view=annotate
Comments welcome.
It's not technically illegal, but as with any use of reinterpret_cast,
there is no guarantee whatsoever as to what the result could be. It's
100% implementation-defined and non-portable. Whatever you're trying
to achieve, reinterpret_cast is not the way.
I simply need to fill in my structure at run time. The only other way I
can see is encapsulate all my templates (see link above) in one class
that would have a giant switch depending on the templates argument.
It's always the same problem interfacing templated code with run time
information.
Could you explain what you mean by this? There's not really any logic
to speak of. Are you attempting to optimize for speed? Avoid code
duplication? I don't think either is happening here.


I liked the fact the *compiler* was telling me something is wrong, such
as array is too big/small, not the right type. The idea was that I
could describe the whole DICOM standard, and then try to compile it, if
it does not compile the standard has a problem :)

Thanks for reading,
Mathieu

May 29 '06 #11

Roland Pibinger wrote:
You can only convert beetween a POD-stuct and its first data member
(and vice versa), not between an arbitrary 'int[10]' and 'struct
Monkey'. Monkey may be larger than array: sizeof (Monkey) >= sizeof
(array). Even alignment restricitions might be different (unlikely).


Oh I think I understand what you are saying. For instance:

struct Monkey {
int a;
int b;
};

the standard does not say anything on how to access Monkey.b. Is this
correct.
Therefore the standard does not say anything for an array, I can only
change the very first data member:

struct Monkey {
int array[10];
};

in this case: Monkey.array[0].

Thanks for your help,
Mathieu

May 29 '06 #12
mathieu posted:

Therefore the standard does not say anything for an array, I can only
change the very first data member:

struct Monkey {
int array[10];
};

No, the entire array is counted as "one object". However it does have
"sub-objects"... just like how an "std::string" is thought of as one
object, even though it may have a few sub-objects. To take it to an
extreme:
struct Monkey {
int a[10];
double b;
void *p;
};

struct Ape {
Monkey monkey;
char k;
float s;
};

struct Lizard {
Ape ape;
char a;
char n;
};

int main()
{
Lizard obj;

int (&array)[10] = reinterpret_cast<int (&)[10]>(obj);

array[3] = 37;
}
Or the inheritance way works aswell

struct Monkey { ...
struct Ape : Monkey { ...
struct Lizard : Ape { ...

Lizard obj;

int (&array)[10] = reinter...
Just so long as we're dealing with POD's.

-Tomás

-Tomás
May 29 '06 #13
mathieu wrote:
If you have nothing to do for memorial day here is the full source:
http://svn.sourceforge.net/viewcvs.c...?view=annotate
Comments welcome.
That's funny... looking at that source, "comments welcome" is exactly
what I was thinking ;). Sorry, not enough time for guesswork -- though
if you'd care to point out the problematic section and explain what
you're trying to do in words, maybe you'll get the help you want.
Whatever you're trying
to achieve, reinterpret_cast is not the way.


I simply need to fill in my structure at run time.


You mean like a constructor does?
The only other way I
can see is encapsulate all my templates (see link above) in one class
that would have a giant switch depending on the templates argument.
That sounds like a pretty ugly way to solve... some problem. What's
the problem you're trying to solve? All you've said is "fill in my
structure at run time," which sounds like a description of what
constructors do. What is it that you're trying to accomplish that you
feel you can't do with a constructor?
It's always the same problem interfacing templated code with run time
information.


There are definitely complexities involved. I'm confused, though,
because your question had nothing to do with templates.
Could you explain what you mean by this? There's not really any logic
to speak of. Are you attempting to optimize for speed? Avoid code
duplication? I don't think either is happening here.


I liked the fact the *compiler* was telling me something is wrong, such
as array is too big/small, not the right type. The idea was that I
could describe the whole DICOM standard, and then try to compile it, if
it does not compile the standard has a problem :)


That sounds very interesting -- what does it have to do with my
question? All I asked is what you meant about how you "would like to
avoid duplicating the logic that take [sic] place when initializing
s1."

Luke

May 29 '06 #14
Luke Meyers wrote:
mathieu wrote:
If you have nothing to do for memorial day here is the full source:
http://svn.sourceforge.net/viewcvs.c...?view=annotate
Comments welcome.


That's funny... looking at that source, "comments welcome" is exactly
what I was thinking ;). Sorry, not enough time for guesswork -- though
if you'd care to point out the problematic section and explain what
you're trying to do in words, maybe you'll get the help you want.


Ok I'll try to summarize my problem with this simple one.
struct MyInt {
int Internal[4];
};
int main()
{
MyInt i = { 0,1,2,3 };
// MyInt i = { 0,1,2,3,4 }; // should throw an error
return 0;
}

Please describe a constructor that would do this exact job. I could not
figure out a way to throw an error when there are too many initializers
(see commented line).

Thanks
Mathieu

May 31 '06 #15

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

17 posts views Thread by Thomas Lorenz | last post: by
35 posts views Thread by tuko | last post: by
8 posts views Thread by iluvatar | last post: by
2 posts views Thread by Dennis Jones | last post: by
13 posts views Thread by liujiaping | last post: by
6 posts views Thread by gs | last post: by
11 posts views Thread by subramanian100in | last post: by
17 posts views Thread by jb.simon | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.