Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

size of a variable

125 views
Skip to first unread message

ghada glissa

unread,
Feb 16, 2015, 7:48:35 AM2/16/15
to
Dear all,


I'm sorry to ask such trivial Questions.
I want to know if there is any type of integer with a size of 16 Bytes because I would like to point to an array with each cell is 16 bytes.

Also, i want to know the length of a table (which has a variable size)
when I write :

uint8_t *AuthData= new uint8_t[48];
printf("the size of authdata est %d",sizeof(AuthData));

it return 8 and not 48 ??

so any help please.

Regards.
Message has been deleted

ghada glissa

unread,
Feb 16, 2015, 8:16:17 AM2/16/15
to

> char( *p )[][ 16 ]

I can't use "char" type because i need to do arithmetic operations (exp: XORing 2 hex number)


Victor Bazarov

unread,
Feb 16, 2015, 8:23:40 AM2/16/15
to
On 2/16/2015 7:48 AM, ghada glissa wrote:
> I'm sorry to ask such trivial Questions.
> I want to know if there is any type of integer with a size of 16
> Bytes
because I would like to point to an array with each cell is 16 bytes.
>

Why is it important for each element of your array to be 16 bytes? The
usual design decisions are made based on what you're going to be doing
with objects. Perhaps you could elaborate on the interface (operations)
in which you see your array elements involved.

> Also, i want to know the length of a table (which has a variable size)
> when I write :
>
> uint8_t *AuthData= new uint8_t[48];
> printf("the size of authdata est %d",sizeof(AuthData));
>
> it return 8 and not 48 ??

The 8 is most likely the size of the pointer on your platform. It is
not unusual for pointers on a 64-bit OS to be 8 bytes.

What book on C++ are you reading that doesn't explain how 'sizeof' works?

V
--
I do not respond to top-posted replies, please don't ask

ghada glissa

unread,
Feb 16, 2015, 8:35:56 AM2/16/15
to
The example that i'm working on says:

"Parse the message AuthData as B1 || B2 || ... ||Bt, where each message block Bi is a 16-octet string"

AuthData has a variable length, and the Bi will have arithmetic operations in the following steps.
Message has been deleted

David Brown

unread,
Feb 16, 2015, 9:12:56 AM2/16/15
to
You can do xor and arithmetic on char's.

But I strongly recommend you use uint8_t (or other sized uintXX_t types)
rather than char or any non-sized types.

Christopher Pisz

unread,
Feb 16, 2015, 11:31:05 AM2/16/15
to
AuthData is a pointer..

You called size of on the pointer, so it gave you the size of the
pointer in bytes.

You could use std::array instead of a raw array and use its size member
instead. Or you can calculate it yourself if you want to use the raw
array by multiplying the size of the type (uint8_t) by the number of
elements.


ghada glissa

unread,
Feb 16, 2015, 11:41:11 AM2/16/15
to
What i'm supposed to do is

1) Form the 16-octet B0 field consisting of the 1-octet Flags field,the (15-L)-octet Nonce field, and the L-octet representation of the Length field l(m), as follows:

B0 = Flags || Nonce N || l(m).

the next step is:

2)Parse the message AuthData as B1 || B2 || ... ||Bt, where each message block Bi is a 16-octet string.

and the next step is to do some arithmetic operation with all the Bi

So i have many problems:

1. the 16 bytes variable,(may i use pointer to pointer ??)
2. the wrong use of memcpy : memcpy (B[i],AuthData,16);
3. wrong use of the left shift << operator with AuthData : AuthData<<128;

So any help please.

Regards.

Vlad from Moscow

unread,
Feb 16, 2015, 12:05:51 PM2/16/15
to
I bthink that some structure would be more approproate to this definition.

B0 = Flags || Nonce N || l(m).

For example

struct BaseField
{
std::uint8_t flags;
std::uint8_t nonce[14];
std::uint8_t length;
};

So you could use standard container std::vector specialized for this structure. For example

#include <iostream>
#include <cstdint>
#include <vector>

struct BaseField
{
std::uint8_t flags;
std::uint8_t nonce[14];
std::uint8_t length;
};

int main()
{
std::vector<BaseField> v;

return 0;

Mr Flibble

unread,
Feb 16, 2015, 12:19:37 PM2/16/15
to
So you've finally accepted that there is nothing wrong with the sized
typedefs? Progress.

/Flibble

Christopher Pisz

unread,
Feb 16, 2015, 12:40:06 PM2/16/15
to
He isn't mixing and matching types here is he?

Jens Thoms Toerring

unread,
Feb 16, 2015, 1:05:03 PM2/16/15
to
Since you seem to be using C++ I'd recommend to create a class,
let's call it 'Byte_Block'. In that class you have an array for
storing your 16 bytes of data. And beside that you implement all
kinds of operations you need to do on whole blocks of 16 bytes,
including e.g. an operator for XOR and whatever else you need.
One of te constructors may take three arguments, a flag,
the Nonce and l(m), from which you construct the block as
needed for point 1.

class Byte_Block
{
private:

uint8_t m_block[ 16 ];
size_t const m_L = 1; // set this to whatever L is supposed to be,
// just make sure it's not larger than 15

public:

// Constructor for empty block (initialized to all 0)

Byte_Block( )
{
std::fill_n( m_block, 16, 0 );
}

// Constructor from flags, Nonce and l(m)

Byte_Block( uint8_t flags,
uint8_t const * Nonce,
uint8_t const * lm )
{
m_block[ 0 ] = flags;
std::copy_n( Nonce, 15 - m_L, m_block + 1 );
std::copy_n( lm, m_L, m_block + 16 - m_L );
}

// XOR operator (may need some modification if the flags or l(m)
// parts of the blocks must be treated differently)

Byte_Block
operator ^ ( Byte_Block const & other ) const
{
Byte_Block result;
for ( size_t i = 0; i < 16, ++i )
result[ i ] = m_block[ i ] ^ other.m_block[ i ];
return result;
}

// Single byte read access operator

uint8_t
operator [ ] ( size_t pos ) const
{
assert( pos < 16 );
return m_block[ pos ];
}

// Single byte write access operator

uint8_t &
operator [ ] ( size_t pos )
{
assert( pos < 16 );
return m_nlock[ pos ];
}
};

Note: the code has not been testet - not even an attempt to
compile it has been made! So the mistakes all are your's
to find and correct;-)

With something like this you will have split up most problems
into nice little sub-problems, which will look a lot easier to
handle than when you try to solve them all at once. Of course,
you will need a couple of other building blocks in that class.

Now you can do

Byte_Block B1( flags, Nonce
Byte_Block B2( B1 );
std::cout << B1[ 5 ] << std::endl;
B1[ 7 ] = 0xab;
Byte_Block B3 = B1 ^ B2;

etc. So, keep the low level details hidden in the class
and otherwise concentrate on the bigger picture. You don't
need no pointers (to pointers), just, if you in- sist a
dynamic array of pointers to Byte_Block objects (but a
std::vector<Byte_Block> probably would be a simpler and
perhaps somewhat cleaner approach since it doesn't re-
quire that you keep track all of the time of how many
of such blocks you've got).

Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de

Mr Flibble

unread,
Feb 16, 2015, 2:04:18 PM2/16/15
to
That's a yes then. Next time think before you post tons of bullshit.

/Flibble

Christopher Pisz

unread,
Feb 16, 2015, 2:16:00 PM2/16/15
to
Can you at least go argue your nonsensical points of view in the
appropriate thread?


Mr Flibble

unread,
Feb 16, 2015, 2:46:42 PM2/16/15
to
What is nonsense exactly? First you made the mistake of thinking
uint16_t was 16 bytes not 16 bits and then you posted a diatribe
compounding your mistake rather that admitting to it. Am I wrong?

/Flibble

Barry Schwarz

unread,
Feb 16, 2015, 3:10:37 PM2/16/15
to
On Mon, 16 Feb 2015 08:40:58 -0800 (PST), ghada glissa
<ghada...@gmail.com> wrote:

>What i'm supposed to do is
>
>1) Form the 16-octet B0 field consisting of the 1-octet Flags field,the (15-L)-octet Nonce field, and the L-octet representation of the Length field l(m), as follows:
>
>B0 = Flags || Nonce N || l(m).
>
>the next step is:
>
>2)Parse the message AuthData as B1 || B2 || ... ||Bt, where each message block Bi is a 16-octet string.
>
>and the next step is to do some arithmetic operation with all the Bi
>
>So i have many problems:
>
>1. the 16 bytes variable,(may i use pointer to pointer ??)

You can but why you need to is not immediately obvious to me.

>2. the wrong use of memcpy : memcpy (B[i],AuthData,16);

Valid only if CHAR_BIT is 8. But then, depending on the types of B
and AuthData, you would want something along the lines of
memcpy(&B[i], &AuthData+i*16, 16);

>3. wrong use of the left shift << operator with AuthData : AuthData<<128;

Based on my previous comment, this would be unneeded.

One thing that might affect your design is whether L is constant. For
every B0 you will need to construct, does the Length field always
occupy the same number of octets. The question has two parts:
In a single execution of the program do all the AuthData have the
same format?
In subsequent executions do the AuthData have the same format as
in previous executions?

If you work on a system where CHAR_BIT is 8 (simple to test during
compilation), then you can construct B0 easily using memcpy with:
unsigned char B0[16];
memcpy(B0, Flags, 1);
memcpy(B0+1, Nonce, 15-L);
memcpy(B0+16-L, Length, L);

If not, you will have to perform your own bit twiddling using the
bitwise and shift operators. For example, if CHAR_BIT is 16:
unsigned char B0[8], x;
memset(B0, 0, 8);
x = (unsigned)(Flags & 0xff) << 8;
B0[0] |= x;
Then, in a loop you would extract each octet of Nonce and store it in
the next octet of B0. The first would go in the second half of B0[0],
the next in the first half of B0[1], then the second half of B0[1],
etc. Similarly for Length.

--
Remove del for email

David Brown

unread,
Feb 16, 2015, 4:05:59 PM2/16/15
to
Could you tell us what you are trying to do here? In particular, is
this an exercise in a book or class, or is it something you are learning
on your own? We can help with learning, but we need to know so that we
can give appropriate help.

If this is /real/ code, handling some sort of encryption or security,
then /please/ give up now - you are not remotely qualified to work on
security code. It is difficult stuff, because it is vital that there
are no flaws in either the algorithms or the implementations.

I am not saying this to criticise your lack of experience - everyone
starts at the beginning. But you don't learn to swim by taking a couple
of lessons and then leaping into the middle of the Atlantic.

Christopher Pisz

unread,
Feb 16, 2015, 5:44:49 PM2/16/15
to
I said no such thing.

Go quote me in the appropriate post and I will try my best to break it
down to your level of understanding.

Mr Flibble

unread,
Feb 16, 2015, 5:49:49 PM2/16/15
to
Either you have memory problems or you are a bald faced liar; either way
the evidence is there.

/Flibble


Christopher Pisz

unread,
Feb 16, 2015, 5:51:57 PM2/16/15
to
Or you're just trolling, since you can't seem to reply in the
appropriate thread, much less quote someone when making false claims
about what they said and didn't say.

Jens Thoms Toerring

unread,
Feb 16, 2015, 6:11:04 PM2/16/15
to
Christopher Pisz <nos...@notanaddress.com> wrote:
> On 2/16/2015 4:49 PM, Mr Flibble wrote:
> > On 16/02/2015 22:44, Christopher Pisz wrote:
> >> On 2/16/2015 1:46 PM, Mr Flibble wrote:
> >>> On 16/02/2015 19:15, Christopher Pisz wrote:
> >>>> On 2/16/2015 1:04 PM, Mr Flibble wrote:
> >>>>> On 16/02/2015 17:39, Christopher Pisz wrote:
> >>>>>> On 2/16/2015 11:19 AM, Mr Flibble wrote:
> >>>>>>> On 16/02/2015 16:30, Christopher Pisz wrote:

Sorry, but both of you really get boring. May I start a new
thread for you two, perhaps with a title of "The Fibble/Pisz
cage fight" (or the other way round - I don't mind)? Or both
of you send me your email address (mine isn't munged) and I
pass it on to the other?
Best regards, Jens

Christopher Pisz

unread,
Feb 16, 2015, 6:16:07 PM2/16/15
to
On 2/16/2015 5:10 PM, Jens Thoms Toerring wrote:
> Christopher Pisz <nos...@notanaddress.com> wrote:
>> On 2/16/2015 4:49 PM, Mr Flibble wrote:
>>> On 16/02/2015 22:44, Christopher Pisz wrote:
>>>> On 2/16/2015 1:46 PM, Mr Flibble wrote:
>>>>> On 16/02/2015 19:15, Christopher Pisz wrote:
>>>>>> On 2/16/2015 1:04 PM, Mr Flibble wrote:
>>>>>>> On 16/02/2015 17:39, Christopher Pisz wrote:
>>>>>>>> On 2/16/2015 11:19 AM, Mr Flibble wrote:
>>>>>>>>> On 16/02/2015 16:30, Christopher Pisz wrote:
>
> Sorry, but both of you really get boring. May I start a new
> thread for you two, perhaps with a title of "The Fibble/Pisz
> cage fight" (or the other way round - I don't mind)? Or both
> of you send me your email address (mine isn't munged) and I
> pass it on to the other?
> Best regards, Jens
>


It's true. I'll just add him to the ignore filter.

Mr Flibble

unread,
Feb 16, 2015, 6:20:18 PM2/16/15
to
False claims?

Evidence:

(It was actually uint8_t not uint16_t)

"Calling everything a uint8_t rather than an unsigned long long
accomplishes what in 2015?! "

"Is it because you want to remind yourself that an unsigned long long is
8 bytes? Is it guaranteed to be 8 bytes by the standard anyway?"

Now stfu and gtfo you little liar.

/Flibble


Jens Thoms Toerring

unread,
Feb 16, 2015, 6:35:32 PM2/16/15
to
Christopher Pisz <nos...@notanaddress.com> wrote:
> On 2/16/2015 5:10 PM, Jens Thoms Toerring wrote:
> > Christopher Pisz <nos...@notanaddress.com> wrote:
> >> On 2/16/2015 4:49 PM, Mr Flibble wrote:
> >>> On 16/02/2015 22:44, Christopher Pisz wrote:
> >>>> On 2/16/2015 1:46 PM, Mr Flibble wrote:
> >>>>> On 16/02/2015 19:15, Christopher Pisz wrote:
> >>>>>> On 2/16/2015 1:04 PM, Mr Flibble wrote:
> >>>>>>> On 16/02/2015 17:39, Christopher Pisz wrote:
> >>>>>>>> On 2/16/2015 11:19 AM, Mr Flibble wrote:
> >>>>>>>>> On 16/02/2015 16:30, Christopher Pisz wrote:
> >
> > Sorry, but both of you really get boring. May I start a new
> > thread for you two, perhaps with a title of "The Fibble/Pisz
> > cage fight" (or the other way round - I don't mind)? Or both
> > of you send me your email address (mine isn't munged) and I
> > pass it on to the other?

> It's true. I'll just add him to the ignore filter.

Thank you - I think that's a wise decision. It doesn't look
likely that you'll reach any kind of agreement (or even a
"we agree to disagree") the way this has been developing.

woodb...@gmail.com

unread,
Feb 16, 2015, 8:40:39 PM2/16/15
to

Leigh, please don't swear here.

Brian
Ebenezer Enterprises
http://webEbenezer.net

Öö Tiib

unread,
Feb 16, 2015, 10:40:26 PM2/16/15
to
On Tuesday, 17 February 2015 03:40:39 UTC+2, woodb...@gmail.com wrote:
> Leigh, please don't swear here.

Brian, Flibble is kind of calm compared to old times but please still
don't beg for unneeded profanities? He is correct that Christopher Pisz
wrote that 'uint8_t' is 'unsigned long long' in that other thread.
https://groups.google.com/forum/#!msg/comp.lang.c++/zs3HWU6ULVM/u8JXT10XSo4J
If something is so boring then please let it be and leave unanswered.

ghada glissa

unread,
Feb 17, 2015, 6:56:03 AM2/17/15
to
Dear Barry,

Thank you for your help

> Valid only if CHAR_BIT is 8.

I want to ask why should i verify CHAR_BIT is 8 bit, why i don't use uint8_t and i'm sur it is 8 bit.

> But then, depending on the types of B and AuthData,

I used uint8_t *AuthData
uint8_t *B

> One thing that might affect your design is whether L is constant.

I think L is constant.

> In a single execution of the program do all the AuthData have the
> same format?

yes

> In subsequent executions do the AuthData have the same format as
> in previous executions?

It keep the same format but not the same length.

Regards.

Martijn Lievaart

unread,
Feb 17, 2015, 7:10:29 AM2/17/15
to
On Tue, 17 Feb 2015 03:54:51 -0800, ghada glissa wrote:

> Dear Barry,
>
> Thank you for your help
>
>> Valid only if CHAR_BIT is 8.
>
> I want to ask why should i verify CHAR_BIT is 8 bit, why i don't use
> uint8_t and i'm sur it is 8 bit.
>

Because memcpy works on chars (bytes) and chars (bytes) are not
guaranteed to be 8 bits in C.

M4

guinne...@gmail.com

unread,
Feb 17, 2015, 7:43:05 AM2/17/15
to
The quoted sentence, above, gives me the impression that you are
trying to implement Struik's "CCM*" or one of its close relatives.
(That sentence, with the missing space before 'Bt', appears in the
Authentication transformation description in his patent,
the IETF draft spec, the NIST draft spec, the IEEE adoption spec, etc.).

If that is the case, then the B[i] will *not* have arithmetic operations
performed on them - just simple bit-manipulation operations (of which
XOR is one). Thus you don't need a 128-bit integer - you just need a
block of 128 bits.

As others have hinted, uint8_t block[16] should be fine (perhaps
wrapped in a struct to give it copyability). std::bitset<128> might
also be a viable alternative.

David Brown

unread,
Feb 17, 2015, 8:36:30 AM2/17/15
to
As far as I can understand the details of the standard, there is no
(standards compliant) way to have a uint8_t type unless chars are 8-bit
on the given platform. In theory, a compiler could provide another
independent 8-bit unsigned type for uint8_t that is different from
"unsigned char" - but as it must be an integral multiple of "char" in
size, and char must be at least 8-bit, then char has to be /exactly/
8-bit if "uint8_t" exists on a platform.

So using <stdint.h> and uint8_t is a perfectly valid way of checking
that your chars are 8-bit - you will get a compile-time failure if
CHAR_BIT is not 8.

Thus if you need to have accurate sizes of types, use the standard sized
types, and leave checks on CHAR_BIT to C code of the previous century.


Daniel

unread,
Feb 17, 2015, 10:36:56 AM2/17/15
to
On Monday, February 16, 2015 at 6:11:04 PM UTC-5, Jens Thoms Toerring wrote:
"The Fibble/Pisz cage fight"

It's Flibble, if you please.

Daniel

Jens Thoms Toerring

unread,
Feb 17, 2015, 11:25:24 AM2/17/15
to
I apologize - it was late in the evening after a longish day.
And a beer or two may have been a contributing factor in this
outrage;-)
Regards, Jens

Drew Lawson

unread,
Feb 17, 2015, 11:47:05 AM2/17/15
to
In article <mbtrr7$bcn$1...@dont-email.me>
Correct, you thought uint8_t was 8 bytes.

>Go quote me in the appropriate post and I will try my best to break it
>down to your level of understanding.

In article <matglf$alo$2...@dont-email.me>
Christopher Pisz <nos...@notanaddress.com> writes:
>On 2/4/2015 10:13 AM, Christopher Pisz wrote:
>> What is a uint8_t and what's wrong with unsigned int?
>
>Correction: What is wrong with unsigned long long?
>See how confusing your silly typedefs are? Use the primitives C++ gave you.
>



--
Drew Lawson What would Brian Boitano do?

red floyd

unread,
Feb 17, 2015, 12:11:27 PM2/17/15
to
On 2/17/2015 8:25 AM, Jens Thoms Toerring wrote:
> Daniel <daniel...@gmail.com> wrote:
>> On Monday, February 16, 2015 at 6:11:04 PM UTC-5, Jens Thoms Toerring wrote:
>> "The Fibble/Pisz cage fight"
>
>> It's Flibble, if you please.
>
> I apologize - it was late in the evening after a longish day.
> And a beer or two may have been a contributing factor in this
> outrage;-)
> Regards, Jens
>

Clearly, you need to have more sausages with your beer!!!


Barry Schwarz

unread,
Feb 17, 2015, 1:51:15 PM2/17/15
to
On Tue, 17 Feb 2015 14:36:20 +0100, David Brown
<david...@hesbynett.no> wrote:

>As far as I can understand the details of the standard, there is no
>(standards compliant) way to have a uint8_t type unless chars are 8-bit
>on the given platform. In theory, a compiler could provide another
>independent 8-bit unsigned type for uint8_t that is different from
>"unsigned char" - but as it must be an integral multiple of "char" in
>size, and char must be at least 8-bit, then char has to be /exactly/
>8-bit if "uint8_t" exists on a platform.

While the standard talks about uintN_t with N = 8, 16, 32, and 64, it
does not limit the compiler to just those values. The compiler is
free to provide a uint9_t type. That such a type would require two
bytes on an 8-bit system with some unused bits is just a detail the
code generator would need to deal with. (Note that the unused bits
are not padding, which is prohibited, since they are not part of the
type.)

Similarly, what in the standard prevents CHAR_BIT from being 16 and
the compiler using any 8 bits in the byte to represent the value of a
uint8_t?

Ian Collins

unread,
Feb 17, 2015, 2:11:27 PM2/17/15
to
Barry Schwarz wrote:
>
> Similarly, what in the standard prevents CHAR_BIT from being 16 and
> the compiler using any 8 bits in the byte to represent the value of a
> uint8_t?

sizeof(uint8_t) being less than 1?

--
Ian Collins

David Brown

unread,
Feb 17, 2015, 2:36:57 PM2/17/15
to
On 17/02/15 19:51, Barry Schwarz wrote:
> On Tue, 17 Feb 2015 14:36:20 +0100, David Brown
> <david...@hesbynett.no> wrote:
>
>> As far as I can understand the details of the standard, there is no
>> (standards compliant) way to have a uint8_t type unless chars are 8-bit
>> on the given platform. In theory, a compiler could provide another
>> independent 8-bit unsigned type for uint8_t that is different from
>> "unsigned char" - but as it must be an integral multiple of "char" in
>> size, and char must be at least 8-bit, then char has to be /exactly/
>> 8-bit if "uint8_t" exists on a platform.
>
> While the standard talks about uintN_t with N = 8, 16, 32, and 64, it
> does not limit the compiler to just those values. The compiler is
> free to provide a uint9_t type. That such a type would require two
> bytes on an 8-bit system with some unused bits is just a detail the
> code generator would need to deal with. (Note that the unused bits
> are not padding, which is prohibited, since they are not part of the
> type.)

A compiler can provide any uintN_t and intN_t types, as long as those
types follow the rules - it can provide a uint9_t as long as the type
has the same sort of wrap on overflow semantics as other unsigned
integer types, and as long as there is a corresponding int9_t with two's
complement arithmetic.

But that does not change the fact that if the compiler provides a valid
uint8_t, then CHAR_BIT must be 8 (even though weird things are allowed,
if unlikely, such as "signed char" being 8-bit one's complement while
"int8_t" is 8-bit two's complement).

>
> Similarly, what in the standard prevents CHAR_BIT from being 16 and
> the compiler using any 8 bits in the byte to represent the value of a
> uint8_t?
>

The rules of C - a "char" is the smallest addressable unit of memory.

Barry Schwarz

unread,
Feb 17, 2015, 5:52:30 PM2/17/15
to
On Tue, 17 Feb 2015 20:36:40 +0100, David Brown
That doesn't stop sub-byte bit fields. There is also no restriction
in the standard that prohibits multiple objects sharing an address.

David Brown

unread,
Feb 18, 2015, 4:42:56 AM2/18/15
to
Bit-fields cannot be accessed except as part of their containing struct.
In particular, you cannot take the address of a bitfield (§6.5.3.2 of
N1570, if you want chapter and verse).

> There is also no restriction
> in the standard that prohibits multiple objects sharing an address.
>

I can't find the right paragraph for this one (but I'm sure others here
or in comp.lang.c can do so - the rules being the same for C and C++).
But different objects must have different addresses, unless they are
part of a union. This is why classes without data members (or virtual
functions) have size 1 rather than size 0 - the different addresses
allow them to be distinguished.

Greg Martin

unread,
Feb 18, 2015, 9:53:42 AM2/18/15
to
Ah, but if it walks like a duck and talks like a duck is it a duck?
note: I can't think of a single reason why you'd do this.


////////////////////////////////////////////////////////////////////////
#include <iostream>

class uint8 {
friend std::ostream& operator<< (std::ostream& out, uint8& ui);
private:
struct {
unsigned char d : 8;
};
public:
uint8 (const unsigned int i) : d(i) {}
uint8 () : d(0) {}
uint8 (const uint8& o) : d(o.d) {}
uint8 (uint8&& o) : d(o.d) { o.d = 0; }
~uint8 () {}

uint8& operator= (const uint8& o) {
d = o.d;
return *this;
}

uint8& operator= (uint8&& o) {
d = o.d;
o.d = 0;
return *this;
}

uint8& operator= (const unsigned int i) {
d = i;
return *this;
}

bool operator== (const unsigned int i) {
return d == i;
}

bool operator== (const uint8& o) {
return d == o.d;
}

};

std::ostream& operator<< (std::ostream& out, uint8& ui) {
out << (unsigned int) ui.d;
return out;
}

int main () {
uint8 u8 = 255;

std::cout << u8 << "\n";
std::cout << (u8 == 255) << "\n";

uint8 u8_2 = u8 = 0xFFFE;

std::cout << u8 << "\n";
std::cout << (u8 == 255) << "\n";
std::cout << (u8 == u8_2) << "\n";

std::cout << sizeof u8 << "\n";

uint8* pu8 = &u8;

std::cout << *pu8 << "\n";

return 0;
}


--
http://www.softsprocket.com

David Brown

unread,
Feb 18, 2015, 10:48:55 AM2/18/15
to
Some languages (such as Python) have duck-typing, but C++ does not
(although templates come close, I suppose).

So no, this is not a duck - if you have a system with a 16-bit char,
then your uint8_t class would take 1 char, or 16 bits, of space, and
you'd lose the size and alignment requirements of a real uint8_t.

> note: I can't think of a single reason why you'd do this.

Actually, I can think of /two/ reasons why you might want something
similar, with a simple "unsigned char" for "d" rather than a bitfield.

While a single sort_of_uint8 on a 16-bit char system would not save much
space, you could use it with a specialised std::array template to let
you pack 8-bit items into an array taking half the space of a normal
"unsigned char" array. It wouldn't have all the features correct (you
couldn't take a reference to or address of elements), but it could still
be useful.

And on 8-bit processors (such as the AVR), wrapping a uint8_t inside a
class like this can lead to better code than using a plain uint8_t,
because in many situations a plain uint8_t gets "integer promotion" to
16-bit (and thus takes twice the number of instructions), while the
class version does not.



<snip implementation>

Scott Lurndal

unread,
Feb 18, 2015, 11:18:56 AM2/18/15
to
David Brown <david...@hesbynett.no> writes:

>
>Actually, I can think of /two/ reasons why you might want something
>similar, with a simple "unsigned char" for "d" rather than a bitfield.
>
>While a single sort_of_uint8 on a 16-bit char system would not save much
>space, you could use it with a specialised std::array template to let
>you pack 8-bit items into an array taking half the space of a normal
>"unsigned char" array. It wouldn't have all the features correct (you
>couldn't take a reference to or address of elements), but it could still
>be useful.

Not unlike the Burroughs large systems, where with a 48-bit addressible
object size, character data was generally packed 6 (EBCDIC) or 8 (6-bit BCD)
characters per word. I'm pretty sure there's an extant C compiler for
this architecture.

This was also commonly used on the PDP-8 (12-bit words) to pack two 6-bit
characters into a single memory word (subtracting 64 from character values
greater than 64 (or clearing bit[6])).

radix-50 encoding was used on the 18/36-bit word-sized PDP systems to pack
characters into a word and was also used on the PDP-11.

Paavo Helde

unread,
Feb 18, 2015, 1:59:09 PM2/18/15
to
David Brown <david...@hesbynett.no> wrote in
news:mc1mpe$g1q$1...@dont-email.me:
Objects of different types can have the same address. This is common for
the most derived object and its first base class subobject, for example.
And that's why empty base class optimization is possible.

The main meaning of sizeof() is to define element spacing when things are
put in an array. One cannot put bitfields or incomplete objects in an
array, so sizeof() does not apply for them.

Cheers
Paavo





0 new messages