Connecting Tech Pros Worldwide Help | Site Map

Data initialization (is this correct?)

 
LinkBack Thread Tools Search this Thread
  #1  
Old May 27th, 2006, 02:25 AM
mathieu
Guest
 
Posts: n/a
Default 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;
}


  #2  
Old May 27th, 2006, 02:45 AM
Jerry Coffin
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

In article <1148696512.476379.294630
@i39g2000cwa.googlegroups.com>,
mathieu.malaterre@gmail.com says...

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

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.
  #3  
Old May 27th, 2006, 04:15 AM
Luke Meyers
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

mathieu wrote:[color=blue]
> 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;
> }
> };[/color]

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.
[color=blue]
> 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[/color]

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.
[color=blue]
> but I would like to avoid duplicating
> the logic that take place when initializing s1.[/color]

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

  #4  
Old May 27th, 2006, 05:35 PM
Tomás
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

mathieu posted:

[color=blue]
> s2 = reinterpret_cast<String&>( array ); // is this legal[/color]


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
  #5  
Old May 27th, 2006, 05:35 PM
Tomás
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

Jerry Coffin posted:
[color=blue]
> In article <1148696512.476379.294630
> @i39g2000cwa.googlegroups.com>,
> mathieu.malaterre@gmail.com says...
>
> [ ... ]
>[color=green]
>> String s2;
>> char array[] = "123D";
>> s2 = reinterpret_cast<String&>( array ); // is this legal[/color]
>
> That depends on what you mean by "legal". It doesn't give
> defined results, if that's what you mean.[/color]

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
  #6  
Old May 27th, 2006, 06:05 PM
Jerry Coffin
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

In article <O50eg.9610$j7.306562@news.indigo.ie>,
No.Email@Address says...

[ ... ]
[color=blue]
> 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."[/color]

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

--
Later,
Jerry.

The universe is a figment of its own imagination.
  #7  
Old May 27th, 2006, 06:45 PM
Roland Pibinger
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

On Sat, 27 May 2006 17:33:39 GMT, "Tomás" <No.Email@Address> wrote:[color=blue]
>mathieu posted:[color=green]
>> s2 = reinterpret_cast<String&>( array ); // is this legal[/color]
>
>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:[/color]

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

Best wishes,
Roland Pibinger

  #8  
Old May 27th, 2006, 08:15 PM
Tomás
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

Roland Pibinger posted:

[color=blue][color=green]
>>Therefore the reverse must be true:[/color]
>
> Nope. It probably 'works' in most cases but it's not correct C++, not
> even for PODs.[/color]


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
  #9  
Old May 27th, 2006, 09:15 PM
Roland Pibinger
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

On Sat, 27 May 2006 20:10:37 GMT, "Tomás" <No.Email@Address> wrote:[color=blue]
>Roland Pibinger posted:
>[color=green][color=darkred]
>>>Therefore the reverse must be true:[/color]
>>
>> Nope. It probably 'works' in most cases but it's not correct C++, not
>> even for PODs.[/color]
>
>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.:[/color]

Ok
[color=blue]
> 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;[/color]

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
  #10  
Old May 27th, 2006, 09:35 PM
Tomás
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

Roland Pibinger posted:

[color=blue]
> 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).[/color]


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

[color=blue]
> Even alignment restricitions might be different (unlikely).[/color]


Interesting point. I wonder if that's possible... ?


-Tomás
  #11  
Old May 29th, 2006, 03:15 AM
mathieu
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)


Luke Meyers wrote:[color=blue]
> 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.
>[/color]

If you have nothing to do for memorial day here is the full source:
http://svn.sourceforge.net/viewcvs.c...?view=annotate
Comments welcome.
[color=blue]
> 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.[/color]

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.
[color=blue]
> 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.[/color]

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

  #12  
Old May 29th, 2006, 03:45 AM
mathieu
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)


Roland Pibinger wrote:
[color=blue]
> 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).[/color]

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

  #13  
Old May 29th, 2006, 04:05 AM
Tomás
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

mathieu posted:

[color=blue]
> Therefore the standard does not say anything for an array, I can only
> change the very first data member:
>
> struct Monkey {
> int array[10];
> };[/color]


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
  #14  
Old May 29th, 2006, 08:05 PM
Luke Meyers
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

mathieu wrote:[color=blue]
> If you have nothing to do for memorial day here is the full source:
> http://svn.sourceforge.net/viewcvs.c...?view=annotate
> Comments welcome.[/color]

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.
[color=blue][color=green]
> > Whatever you're trying
> > to achieve, reinterpret_cast is not the way.[/color]
>
> I simply need to fill in my structure at run time.[/color]

You mean like a constructor does?
[color=blue]
> 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.[/color]

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?
[color=blue]
> It's always the same problem interfacing templated code with run time
> information.[/color]

There are definitely complexities involved. I'm confused, though,
because your question had nothing to do with templates.
[color=blue][color=green]
> > 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.[/color]
>
> 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 :)[/color]

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

  #15  
Old May 31st, 2006, 05:25 PM
mathieu
Guest
 
Posts: n/a
Default Re: Data initialization (is this correct?)

Luke Meyers wrote:[color=blue]
> mathieu wrote:[color=green]
> > If you have nothing to do for memorial day here is the full source:
> > http://svn.sourceforge.net/viewcvs.c...?view=annotate
> > Comments welcome.[/color]
>
> 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.[/color]

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

 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,989 network members.