int8_t/uint8_t

C

Chris Forone

hello group,

is the cast of int8_t and uint8_t in char for streaming in both
directions (put(), get()) defined/plattform independent?

i have read here in the forum, that int8_t and uint8_t are guaranteed 2s
complement, ist the cast between them bit-identical (or is to big
unsigned in signed undef)?

are all three chars (char, signed char, unsigned char) on every
plattform the same size?

is there a best practise to stream char plattform independend?

thanks a lot!

cheers, chris
 
J

joseph cook

hello group,

is the cast of int8_t and uint8_t in char for streaming in both
directions (put(), get()) defined/plattform independent?

i have read here in the forum, that int8_t and uint8_t are guaranteed 2s
complement, ist the cast between them bit-identical (or is to big
unsigned in signed undef)?

are all three chars (char, signed char, unsigned char) on every
plattform the same size?

is there a best practise to stream char plattform independend?

thanks a lot!

cheers, chris

I'm not sure I understand your question; but I think the quick answer
is 'no'; at the very least you must consider endianess issues.
 
F

Fred Zwarts

Chris Forone said:
hello group,

is the cast of int8_t and uint8_t in char for streaming in both
directions (put(), get()) defined/plattform independent?

I don't think int8_t and uint8_t are defined on all platforms.
i have read here in the forum, that int8_t and uint8_t are guaranteed 2s
complement, ist the cast between them bit-identical (or is to big
unsigned in signed undef)?
Probably.

are all three chars (char, signed char, unsigned char) on every
plattform the same size?

On all platforms sizeof (char) == sizeof (signed char) == sizeof (unsigned char) == 1.
is there a best practise to stream char plattform independend?

I don't understand this question, but probably there is a best practice.
 
C

Chris Forone

joseph said:
I'm not sure I understand your question; but I think the quick answer
is 'no'; at the very least you must consider endianess issues.

i only use (u)int8_t/(u)int16_t/(u)int32_t in my app. the endianess is
no problem, because i can only stream char, which is signed/unsigned
char (depends on impl.). the 16 bit i stream with Put(val >> 8) and
Put(val), the 32 bit with Put(val >> 24) ... Put(val), the Gets() are
equivalent. i think, serialized objects should be readable on most
plattforms, i only need the big 3 (linux/mac/win, alphabetical). the
only problem is, that i have to cast before the shift to unsigned char,
so the bit-identical is very important because i can only test on 2
plattforms...

cheers, chris
 
B

Bo Persson

Chris said:
hello group,

is the cast of int8_t and uint8_t in char for streaming in both
directions (put(), get()) defined/plattform independent?

i have read here in the forum, that int8_t and uint8_t are
guaranteed 2s complement, ist the cast between them bit-identical
(or is to big unsigned in signed undef)?

They are twos complement, *if they exist*. On platforms with ones
complement, or 9 bit bytes, you're toast.
are all three chars (char, signed char, unsigned char) on every
plattform the same size?

They are all the same size on a given platform. Was that your
question?
is there a best practise to stream char plattform independend?

The best way to be platform independent is to define the transport
format separately. They you have to implement this on each platform,
in a platform dependent way.


Bo Persson
 
G

Greg Herlihy

I'm not sure I understand your question; but I think the quick answer
is 'no'; at the very least you must consider endianess issues.

There are no endian issues to consider with 8-bit data. So the quick
answer is "yes", int8_t and uint8_t (unlike "char") are guaranteed to
use two's complement integer representation.

Greg
 
J

James Kanze

On Jul 3, 4:21 am, joseph cook <[email protected]> wrote:

[...]
There are no endian issues to consider with 8-bit data.

In the context of C++. If you're transmitting the data on a
serial line, there is (but of course, it's fully taken care of
by the hardware---and as far as I know, it's always little
endian).

But of course, that's really irrelvant here, since the smallest
unit you can access directly in C++ is a byte (8 or more bits).
And regardless of the processor or the local naming conventions,
0x01 has bit 0 (the low order bit) set, and the others not. (In
the traditional IBM mainframe terminology, 0x01 would have bit 8
set on a byte, bit 16 set on a half word, and bit 32 set on a
word.)
 
J

James Kanze

They are twos complement, *if they exist*. On platforms with
ones complement, or 9 bit bytes, you're toast.

One of the advantages of using them is that if the platform
doesn't support what you require, your code won't compile.
Whereas if you just use char, you're most likely to get some
strange behavior at run-time. (And of course, there's no
requirement that uint8_t be two's complement:).)
They are all the same size on a given platform. Was that your
question?
The best way to be platform independent is to define the
transport format separately. They you have to implement this
on each platform, in a platform dependent way.

Or not. It does depend a bit on what you're streaming.

For integer values, the standard guarantees that converting a
signed value to the corresponding unsigned type will result in
the bit pattern of 2's complement (assuming the value
fits---which is not guaranteed), e.g. on a 16 bit machine,
converting -1 to unsigned int always results in 0xFFFF,
regardless of the representation used for negative numbers.
(Note that compilers for machines which do not use 2's
complement may require a special option to be conformant in this
respect, since it means generating extra code to do the correct
conversion.) This means that regardless of the internal
representation, if the numeric value fits, you can always output
an integer in Internet format (four 8 bit bytes, high byte
first, 2's complement) by converting it to an unsigned long (to
be sure of having at least 32 bits), then outputting the four 8
bit blocks in the correct order, by shifting and masking.
Inputting is a bit trickier, since the results of converting an
unsigned integral type to a signed is implementation defined,
and may result in an implementation defined signal if the value
doesn't fit. Formally, I think you'd have to do something like:

if ( unsignedValue > 0x7FFFFFFF ) {
signedValue = ~ unsignedValue ;
signedValue = - signedValue ;
-- signedValue ;
}

(In practice, I use uint32_t and int32_t, memcpy'ing to do the
"conversion". Or just converting, if I know that only limited
portability is required, e.g. Sparc and PC, but nothing else.)
 

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
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top