locating an array

C

Charles Arnett

Hello
I'll try this
I have a structure composedx of floats and strings. I want a dummy array
that is the same length starting at the same address. I do this so I cann
access the individual bytes of the structure.

Accually the structure is array[4] of the structure
charles arnett
(e-mail address removed)
 
S

Stefan Ram

Charles Arnett said:
I have a structure composedx of floats and strings. I want a dummy array
that is the same length starting at the same address. I do this so I cann
access the individual bytes of the structure.

I hope that there are not too many locations
with undefined behavior below, and that it is
always possible to align a »t*« at the address
of an »s*«:

#include <iostream>
#include <ostream>

struct s { float a, b, c; };

struct t { char a[ sizeof( s )]; };

int main()
{ s s0;
t * t0( reinterpret_cast< t* >( &s0 ));
::std::cout << sizeof( t0->a ); }
 
I

Ian Collins

Charles said:
Hello
I'll try this
I have a structure composedx of floats and strings. I want a dummy array
that is the same length starting at the same address. I do this so I cann
access the individual bytes of the structure.

How about something like (assuming your strings are char arrays):

struct X { int n; char c[64]; };

union U { X x; char bytes[sizeof(X)]; };
 
C

Charles Arnett

That does seem like what I want to do. Why do you have X x in the union U
{ X x; char bytes[sizeof(X)]; }? What is the lower case x for? I have not
used unions before but it is a great suggestion.
charles arnett

Ian Collins said:
Charles said:
Hello
I'll try this
I have a structure composedx of floats and strings. I want a dummy array
that is the same length starting at the same address. I do this so I
cann access the individual bytes of the structure.

How about something like (assuming your strings are char arrays):

struct X { int n; char c[64]; };

union U { X x; char bytes[sizeof(X)]; };
 
I

Ian Collins

Charles Arnett wrote:

Please don't top-post.
Ian Collins said:
Charles said:
Hello
I'll try this
I have a structure composedx of floats and strings. I want a dummy array
that is the same length starting at the same address. I do this so I
cann access the individual bytes of the structure.
How about something like (assuming your strings are char arrays):

struct X { int n; char c[64]; };

union U { X x; char bytes[sizeof(X)]; };
> That does seem like what I want to do. Why do you have X x in the union U
> { X x; char bytes[sizeof(X)]; }? What is the lower case x for? I have not
> used unions before but it is a great suggestion.

You'd better read up on them!

x and bytes are the two member of the union. For example

U u;

u.x.n = 42;

char c = u.bytes[0];
 
T

Triple-DES

Hello
I'll try this
I have a structure composedx of floats and strings.  I want a dummy array
that is the same length starting at the same address.  I do this so I cann
access the individual bytes of the structure.

Accually the structure is array[4] of the structure

You could (ab)use operator overloading to achieve your goal:

struct C
{
float a;
char str[8];
// ...

/*const*/ char& operator[](unsigned i) /*const*/
{
return *(reinterpret_cast< /*const*/ char*>(this) + i);
}
};

int main()
{
C c = {};
// now individual bytes can be accessed like this:
char firstByte = c[0];
c[1] = 0x13;
}
 
J

James Kanze

I hope that there are not too many locations
with undefined behavior below, and that it is
always possible to align a »t*« at the address
of an »s*«:
#include <iostream>
#include <ostream>
struct s { float a, b, c; };
struct t { char a[ sizeof( s )]; };
int main()
{ s s0;
t * t0( reinterpret_cast< t* >( &s0 ));
::std::cout << sizeof( t0->a );
}

This seems more complicated than necessary, as well as
unnecissarily introducing undefined behavior. If the goal is
just to look at the individual bytes in an object:

template< typename T >
void
dump( std::eek:stream& dest, T const& obj )
{
unsigned char const*p
= reinterpret_cast< unsigned char const* >( &obj ) ;
for ( size_t i = 0 ; i != sizeof( obj ) ; ++ i ) {
if ( i != 0 ) {
dest << ' ' ;
}
dest << HexFmt( 2 ) << static_cast< int >( p[ i ] ) ;
}
}

will do the trick, with no undefined behavior. (This can easily
be dressed up in a class, with an operator<<, and a free
function for type deduction, to make it easier to use.)
 
J

James Kanze

Charles Arnett wrote:
How about something like (assuming your strings are char
arrays):
struct X { int n; char c[64]; };
union U { X x; char bytes[sizeof(X)]; };

Accessing bytes when the last thing written to the union was x
is formally undefined behavior. In practice, it's likely to
work, however; with at least one compiler, it's even guaranteed,
where as the standard approved reinterpret_cast may cause
problems.
 
S

Stefan Ram

James Kanze said:
Accessing bytes when the last thing written to the union was x
is formally undefined behavior.

This is written so in ISO/IEC 9899:1999 (E), that is, »C«.

But I can not find corresponding wording in ISO/IEC 14882:2003(E),
that is, C++. It only says that only one of the union members
can be »active« at a time.

So, how can one derive from ISO/IEC 14882:2003(E) that this is
undefined behavior?
 
S

Stefan Ram

James Kanze said:
I have a structure composedx of floats and strings. I want a
dummy array that is the same length starting at the same
address. I do this so I cann access the individual bytes of
the structure.
#include <iostream>
#include <ostream>
struct s { float a, b, c; };
struct t { char a[ sizeof( s )]; };
int main()
{ s s0;
t * t0( reinterpret_cast< t* >( &s0 ));
::std::cout << sizeof( t0->a ); }
This seems more complicated than necessary, as well as
unnecissarily introducing undefined behavior.

Where does it introduce undefined behavior?
If the goal is just to look at the individual bytes in an
object:

The OP wanted to have an »array that is the
same length starting at the same address«.
 
J

James Kanze

James Kanze said:
I have a structure composedx of floats and strings. I want a
dummy array that is the same length starting at the same
address. I do this so I cann access the individual bytes of
the structure.
#include <iostream>
#include <ostream>
struct s { float a, b, c; };
struct t { char a[ sizeof( s )]; };
int main()
{ s s0;
t * t0( reinterpret_cast< t* >( &s0 ));
::std::cout << sizeof( t0->a ); }
This seems more complicated than necessary, as well as
unnecissarily introducing undefined behavior.
Where does it introduce undefined behavior?

When you access t0. T0 doesn't have a character type, so any
access of s through it is undefined behavior. (I think that
there are certain cases with g++ where this actually doesn't
work. But it's actually an interesting question---t-> is a
character type, and while I think that taken literally, the
standard says this is undefined behavior, I have a hard time
imagining an implementation where it wouldn't work, but
The OP wanted to have an »array that is the
same length starting at the same address«.

Why? What does he really mean by array? For better or for
worse (mostly worse), getting an "unsigned char*" to the first
byte and knowing the size of the type (sizeof) comes down to
pretty much the same thing.
 
J

James Kanze

This is written so in ISO/IEC 9899:1999 (E), that is, »C«.
But I can not find corresponding wording in ISO/IEC
14882:2003(E), that is, C++. It only says that only one of
the union members can be »active« at a time.
So, how can one derive from ISO/IEC 14882:2003(E) that this
is undefined behavior?

Because 14882 doesn't specify what happens when you access an
inactive member, and when the standard fails to specify
something, it's undefined behavior.

But I agree that the standard should say it; there are a couple
of points where C++ tries to improve on the wording in C, and
ends up getting it worse. (The intent, obviously, is that all
the low level stuff be compatible. And I'm pretty sure that
unions should be viewed as the "low level stuff".)
 
S

Stefan Ram

James Kanze said:
Because 14882 doesn't specify what happens when you access an
inactive member, and when the standard fails to specify
something, it's undefined behavior.

In ISO/IEC 14882:2003(E), there is no other definition of
»active«. To me, the definiton one can reasonably assume
seems to be »what is being used«.

This means, when one has been using a union member, and now
starts to use another union member, then the first member
becomes "inactive" and the other becomes "active". (Otherwise,
any other use of more than one member of a union - that is,
use that is allowed by ISO/IEC 9899:1999 (E) - would be
undefined behavior, too.)

Therefore, one might assume, that in the very moment »when you
access an inactive member« it becomes »active«.

Of course, we would like to read that the »activating access«
has to be a /write/ access - but they have not written this.
 
J

James Kanze

In ISO/IEC 14882:2003(E), there is no other definition of
»active«. To me, the definiton one can reasonably assume
seems to be »what is being used«.
This means, when one has been using a union member, and now
starts to use another union member, then the first member
becomes "inactive" and the other becomes "active". (Otherwise,
any other use of more than one member of a union - that is,
use that is allowed by ISO/IEC 9899:1999 (E) - would be
undefined behavior, too.)
Therefore, one might assume, that in the very moment »when you
access an inactive member« it becomes »active«.
Of course, we would like to read that the »activating access«
has to be a /write/ access - but they have not written this.

One would like for it to be more precise. Definitely. Given
what is written, your interpretation does seem to be valid. Of
course, if the access to the member isn't a write, then you're
accessing an uninitialized object, which is also undefined
behavior (except if the object has type char or unsigned
char---and this is yet another stupid difference from C: in C, a
char (but not an unsigned char) is allowed to have a trapping
representation; in C++, it isn't).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,901
Members
47,439
Latest member
elif2sghost

Latest Threads

Top