Accessing individual bytes of an integer

  • Thread starter =?iso-8859-1?q?Daniel_Lidstr=F6m?=
  • Start date
L

Larry Brasfield

Ioannis Vranos said:
Ioannis Vranos wrote:

[Cut many words about validity of byte-wise copying.]

As I mentioned, copying byte by byte is ok in my book.
4. The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T,
where N equals sizeof(T). The value representation of an object is the set of bits
that hold the value of type T. For POD types, the value representation is a set of bits in the object representation that
determines a value, which is one discrete element of an implementation-defined set of values.37)

5. Object types have alignment requirements (3.9.1, 3.9.2). The alignment of a complete object type is an implementation-defined
integer value representing a number of bytes; an object is allocated at an address that meets the alignment requirements of its
object type."

Unfortunately you are right.

Well, I suppose one could look at it that way. However, the
alignment issue arises from machine design decisions that are
made in the interest of cost, complexity and speed. So, to
the extent that having alignment requirements has made some
computers cheaper, more reliable and faster, they might be
regarded as fortunate by the beneficiaries.
Case 3:

At first the destination must be a pointer of the same object type (and presumably the allocated space must be for the same type
objects.


Secondly, the standard guarantees that only memcpy() works in this case, and not copying it char by char or unsigned char by
unsigned char. In other words, in an implementation memcpy() can be defined in some exotic way (e.g. assembly), and still copying
it unsigned char by unsigned char to the destination has undefined behaviour, while using memcpy() for the same destination is
guaranteed to work!

I think file I/O is supposed to work, too. And the language
about value residing in the bytes seems, to me, to guarantee
that any sizeof(T) byte-by-byte copy would preserve value.
So my examples fixed (and not producing exactly the same results):

Please see inserted comments.
#include <iostream>
#include <cstring>

int main()
{
using namespace std;

int integer=4;

int secondInteger;


memcpy(&secondInteger, &integer, sizeof(integer));


cout<<integer<<"\n";
}

Must emit '4' and a line boundary and is portable.
and


#include <iostream>
#include <cstring>


int main()
{
using namespace std;

int arrayInt[4]={1,2,3,4};

int secondArrayInt[sizeof(arrayInt)];

Do you mean to create these 2 arrays the same size?
That is not the effect of the above code.
memcpy(secondArrayInt, arrayInt, sizeof(arrayInt));

for(unsigned i=0; i< sizeof(4); ++i)
cout<<secondArrayInt<<"\n";
}


The sizeof(4) is the same as sizeof(int).
Please correct if I am wrong. Aren't the above guaranteed to be portable?

It will emit a number of integers in text format which
varies according to how many bytes an int occupies.
Not portable by my definition of the term.
 
I

Ioannis Vranos

Larry said:
int secondArrayInt[sizeof(arrayInt)];


Do you mean to create these 2 arrays the same size?
That is not the effect of the above code.


Yes you are right, it should have been 4 or
sizeof(arrayInt)/sizeof(*arrayInt)...



memcpy(secondArrayInt, arrayInt, sizeof(arrayInt));

for(unsigned i=0; i< sizeof(4); ++i)
cout<<secondArrayInt<<"\n";
}



The sizeof(4) is the same as sizeof(int).



Hmm, I was in a hurry and posted non-sense. This was meant to be i<4.


It will emit a number of integers in text format which
varies according to how many bytes an int occupies.
Not portable by my definition of the term.


My non-sense corrected (sorry about that):


#include <iostream>
#include <cstring>

int main()
{
using namespace std;

int integer=4;

int secondInteger;


memcpy(&secondInteger, &integer, sizeof(integer));


cout<<secondInteger<<"\n";
}


and


#include <iostream>
#include <cstring>


int main()
{
using namespace std;

int arrayInt[4]={1,2,3,4};

int secondArrayInt[4];


memcpy(secondArrayInt, arrayInt, sizeof(arrayInt));

for(unsigned i=0; i<4; ++i)
cout<<secondArrayInt<<"\n";
}
 
?

=?iso-8859-1?q?Daniel_Lidstr=F6m?=

Yes you can, but you have absolutely no assurance as to what the results
will be :)

What's wrong with

(bits>>n) & 0xff

where n is 0, 8, 16, or 24?

There is nothing wrong with that, and I think I will use this method.
Except I do it the other way around:

uint8 merge(const uint4 b[2])
{
return (uint8(b[0])<<32) | b[1];
}

Thanks!
 
K

Kurt Stutsman

Daniel said:
There is nothing wrong with that, and I think I will use this method.
Except I do it the other way around:

uint8 merge(const uint4 b[2])
{
return (uint8(b[0])<<32) | b[1];
}

Thanks!
Considering it looks like you're trying to merge 2 4-bit integers into 1
8-bit integer, you should be shifting left by 4 not 32.
 
A

Andrew Koenig

However the interesting part is that the entire union can be read as an
unsigned char/plain char array, as is the case with all POD types.

On the other hand, there's no particular assurance as to its content when
read that way.
 
R

Ron Natalie

Old said:
That passage is irrelevant to this situation. It says
"If (conditions) then the behaviour is undefined". The union
example in question does not meet (conditions). QED.

The passage doesn't say that. It says OTHER than the listed conditions
the behavior is undefined. Accessing a stored value via an lvalue
of char type IS defined.
To put it another way, the passage you quoted doesn't say that
the behaviour is defined for those listed bullet points.

Yes, but nothing says it's undefined otherwise. The only
prohibition in chapter 9 on unions is that you may only STORE
one value at a time in an union.
 
O

Old Wolf

Ron said:
The passage doesn't say that. It says OTHER than the listed conditions
the behavior is undefined. Accessing a stored value via an lvalue
of char type IS defined.

You used the wrong substitution for (conditions) in my quote.

(conditions) is "a program attempts to access the stored value
of an object through an lvalue of other than one of the following
types".
Yes, but nothing says it's undefined otherwise.
The only prohibition in chapter 9 on unions is that you
may only STORE one value at a time in an union.

The quote in question (which you snipped) had nothing to do with
unions and has no bearing on the OP's question.

The suggestion by Clark S Cox was rebuffed by the quote that
Andrew Koenig provided.
 

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

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,188
Latest member
Crypto TaxSoftware

Latest Threads

Top