Re: size of a variable
On 2015-02-18, David Brown <david.brown@hesbynett.no> wrote:
On 17/02/15 23:51, Barry Schwarz wrote:
On Tue, 17 Feb 2015 20:36:40 +0100, David Brown
<david.brown@hesbynett.no> wrote:
On 17/02/15 19:51, Barry Schwarz wrote:
On Tue, 17 Feb 2015 14:36:20 +0100, David Brown
<david.brown@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.
That doesn't stop sub-byte bit fields.
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).
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