M
MikeWhy
Why shouldn't the following work? VC2008 complains "shift count negative or
too big, undefined behavior". Indeed, foo.b and foo.c contain 0, given
non-zero values.
The following prints:
8
162e (5678:0:0)
162f (5679:0:0)
cd2000000000162e (5678:1234:1)
//=====================================
// fooBitfield.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
typedef unsigned __int64 Unt64;
struct Foo
{
//=============
Unt64 a : 52;
Unt64 b : 11;
Unt64 c : 1;
};
std:stream & operator<<(std:stream & os, const Foo & r)
{
const Unt64 ival = *reinterpret_cast<const Unt64*>(&r);
os << std::hex << ival << std::dec << " ("
<< r.a << ':'
<< r.b << ':'
<< r.c << ')';
return os;
}
int main(int argc, char** argv)
{
//-- doesn't work. Prints "(5678:0:0)"
{
const Foo foo = {
(Unt64)atoi(argv[1]),
(Unt64)atoi(argv[2]),
(Unt64)atoi(argv[3])
};
std::cout << sizeof(foo) << '\n'
<< foo << '\n';
}
//-- doesn't work. Prints "(5679:0:0)"
{
//!! const Foo foo2 = { 3, 3, 3};
const Foo foo2 = { 3ULL, 3ULL, 3ULL }; // makes no difference.
std::cout << foo2 << '\n';
}
//-- works just fine.
{
Foo foo3;
foo3.a = atoi(argv[1]);
foo3.b = atoi(argv[2]);
foo3.c = atoi(argv[3]);
std::cout << foo3 << '\n';
}
return 0;
}
too big, undefined behavior". Indeed, foo.b and foo.c contain 0, given
non-zero values.
The following prints:
8
162e (5678:0:0)
162f (5679:0:0)
cd2000000000162e (5678:1234:1)
//=====================================
// fooBitfield.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
typedef unsigned __int64 Unt64;
struct Foo
{
//=============
Unt64 a : 52;
Unt64 b : 11;
Unt64 c : 1;
};
std:stream & operator<<(std:stream & os, const Foo & r)
{
const Unt64 ival = *reinterpret_cast<const Unt64*>(&r);
os << std::hex << ival << std::dec << " ("
<< r.a << ':'
<< r.b << ':'
<< r.c << ')';
return os;
}
int main(int argc, char** argv)
{
//-- doesn't work. Prints "(5678:0:0)"
{
const Foo foo = {
(Unt64)atoi(argv[1]),
(Unt64)atoi(argv[2]),
(Unt64)atoi(argv[3])
};
std::cout << sizeof(foo) << '\n'
<< foo << '\n';
}
//-- doesn't work. Prints "(5679:0:0)"
{
//!! const Foo foo2 = { 3, 3, 3};
const Foo foo2 = { 3ULL, 3ULL, 3ULL }; // makes no difference.
std::cout << foo2 << '\n';
}
//-- works just fine.
{
Foo foo3;
foo3.a = atoi(argv[1]);
foo3.b = atoi(argv[2]);
foo3.c = atoi(argv[3]);
std::cout << foo3 << '\n';
}
return 0;
}