首先,相关应用程序始终位于同一处理器上,并且编译器始终为 gcc,因此我不担心位域不可移植。
gcc 布局位字段,使得第一个列出的字段对应于字节的最低有效位。因此,在以下结构中,a = 0,b = 1,c = 1,d = 1,您将得到一个字节值 e0。
struct Bits {
unsigned int a:5;
unsigned int b:1;
unsigned int c:1;
unsigned int d:1;
} __attribute__((__packed__));
Run Code Online (Sandbox Code Playgroud)
(实际上,这是C++,所以我说的是g++。)
现在假设我希望a是一个六位整数。
现在,我明白为什么这不起作用,但我编写了以下结构:
struct Bits2 {
unsigned int a:6;
unsigned int b:1;
unsigned int c:1;
unsigned int d:1;
} __attribute__((__packed__));
Run Code Online (Sandbox Code Playgroud)
将b、c和d设置为 1,将a设置为 0 会产生以下两个字节:
c0 01
Run Code Online (Sandbox Code Playgroud)
这不是我想要的。我希望看到这个:
e0 00
Run Code Online (Sandbox Code Playgroud)
有没有办法指定一个结构,该结构在第一个字节的最高有效位中具有三位,并且在第一个字节的五个最低有效位和第二个字节的最高有效位中具有六个位?
请注意,我无法控制这些位的布局位置:它是由其他人的接口定义的位布局。
我试图理解位域的概念.但我无法找到CASE III中以下结构的大小为8字节的原因.
struct B
{
unsigned char c; // +8 bits
} b;
Run Code Online (Sandbox Code Playgroud)
的sizeof(B); //输出:1(因为unsigned char在我的系统上占用1个字节)
struct B
{
unsigned b: 1;
} b;
sizeof(b); // Output: 4 (because unsigned takes 4 bytes on my system)
Run Code Online (Sandbox Code Playgroud)
struct B
{
unsigned char c; // +8 bits
unsigned b: 1; // +1 bit
} b;
sizeof(b); // Output: 8
Run Code Online (Sandbox Code Playgroud)
我不明白为什么案例III的输出为8.我期待1(char)+ 4(无符号)= 5.
我正在寻找模板重载解析中位域的解决方法。
我有一个函数模板,用于完美转发其参数:
template <typename... Args> void f(Args &&...args) { }
Run Code Online (Sandbox Code Playgroud)
如果我尝试将它与位域参数一起使用,如下所示:
struct bits { unsigned int foo:1; };
bits b{1};
f(b.foo);
Run Code Online (Sandbox Code Playgroud)
...它无法编译:
main.cpp:26:7: 错误:非常量引用无法绑定到位字段“foo”
f(b.foo);
^~~~~
有没有办法重载f(),使其按值获取位字段,但在常见情况下仍按引用获取其他参数?
到目前为止我还做不到。例如,如果我添加一个按值接受参数的重载......
main.cpp:27:5: 错误:对“f”的调用不明确
f(b.foo);
^ 考虑以下:
class A { public:
int gate_type : 4;
bool storage_elem : 1;
uint8_t privilege : 2;
bool present : 1;
} __attribute__((packed));
class B { public:
struct Sub {
int gate_type : 4;
bool storage_elem : 1;
uint8_t privilege : 2;
bool present : 1;
} type_attr; //Also tried with "__attribute__((packed))" here in addition to outside
} __attribute__((packed));
Run Code Online (Sandbox Code Playgroud)
编译器是g ++ 4.8.1.sizeof(A)== 1,sizeof(B)== 4.为什么会这样?我需要像结构B这样的东西,大小为1.
在C我可以做这样的事情:
struct byte_nibbles {
unsigned char b1: 4;
unsigned char b2: 4;
unsigned char b3: 4;
unsigned char b4: 4;
unsigned char b5: 4;
unsigned char b6: 4;
unsigned char b7: 4;
unsigned char b8: 4;
};
union {
unsigned long var;
struct byte_nibbles b;
}
u;
int main(void)
{
u.b.b1=0x01; u.b.b2=0x02; u.b.b3=0x03; u.b.b4=0x04;
u.b.b5=0x05; u.b.b6=0x06; u.b.b7=0x07; u.b.b8=0x08;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以我可以访问 byte_nibbles 的特定部分。显然这只是一个例子。可以创建适合基本类型的任何大小的位域。
尽管我付出了努力并进行了大量研究,但我无法弄清楚如何在Swift 中做到这一点。我可以使用按位获得相同的结果,但这不是那么可读和优雅。
任何的想法?
我有一些位域:
int somefield : 15;
Run Code Online (Sandbox Code Playgroud)
我正在尝试将 int 转换为 15 位(可以是正数或负数)。
有效执行此操作的最佳做法是什么?
从理论上讲,我们有两种选择来选择位字段成员的类型:
那么实际上是什么类型的位域成员(我在标准中找不到迄今为止的提示--C和C++一样)并且C和C++之间有什么区别?
虽然知道特定的编译器不是引用,但我试图通过C++函数重载和typeid运算符获得至少一些提示:
#include <typeinfo>
struct S
{
unsigned int n4 : 4;
unsigned int n12 : 12;
};
void f(unsigned char)
{
std::cout << "uc" << std::endl;
}
void f(unsigned short)
{
std::cout << "us" << std::endl;
}
void f(unsigned int)
{
std::cout << "ui" << std::endl;
}
int main(int argc, char* argv[])
{
S s; s.n4 = 0; s.n12 = 0;
f(s.n4);
f(s.n12);
std::cout << typeid(s.n4).name() << std::endl;
std::cout << typeid(s.n12).name() << std::endl;
std::cout << typeid(unsigned …Run Code Online (Sandbox Code Playgroud) 我在 IAR 中有以下类结构:
class A
{
public:
A(){}
virtual ~A() {};
virtual void load() {};
};
class C
{
public:
C()
{
//C does other stuff, not relevant
}
};
class D;
class B : public A
{
public:
B() : invert(false) {};
virtual ~B() {};
void load()
{
//Irrelevant stuff done here
}
private:
C member_c;
std::vector<D*> vector_of_d;
struct {
bool var_1:1;
bool var_2:1;
bool var_3:1;
bool var_4:1;
bool invert:1;
};
};
Run Code Online (Sandbox Code Playgroud)
我遇到了为初始化 B 而生成的程序集的错误,它似乎对 VTable 指针的位置与匿名结构位域的位置感到“困惑”。当它设置反转位为假时,它转到对象的第一个字(即 VTable 指针)并翻转地址中的一个位。当我稍后调用 …
我是一个来自C/C++的Rust初学者.首先,我尝试使用user32.MessageBox为Microsoft Windows创建一个简单的"Hello-World"程序,我偶然发现了与bitfields相关的问题.免责声明:所有代码段都是在SO编辑器中编写的,可能包含错误.
调用该函数的UTF-16LE版本所需的合并C声明是:
enum MessageBoxResult {
IDFAILED,
IDOK,
IDCANCEL,
IDABORT,
IDRETRY,
IDIGNORE,
IDYES,
IDNO,
IDTRYAGAIN = 10,
IDCONTINUE
};
enum MessageBoxType {
// Normal enumeration values.
MB_OK,
MB_OKCANCEL,
MB_ABORTRETRYIGNORE,
MB_YESNOCANCEL,
MB_YESNO,
MB_RETRYCANCEL,
MB_CANCELTRYCONTINUE,
MB_ICONERROR = 0x10UL,
MB_ICONQUESTION = 0x20UL,
MB_ICONEXCLAMATION = 0x30UL,
MB_ICONINFORMATION = 0x40UL,
MB_DEFBUTTON1 = 0x000UL,
MB_DEFBUTTON2 = 0x100UL,
MB_DEFBUTTON3 = 0x200UL,
MB_DEFBUTTON4 = 0x300UL,
MB_APPLMODAL = 0x0000UL,
MB_SYSTEMMODAL = 0x1000UL,
MB_TASKMODAL = 0x2000UL,
// Flag values.
MB_HELP = 1UL << 14,
MB_SETFOREGROUND = …Run Code Online (Sandbox Code Playgroud) 给定一个结构 S:
struct S {
bool a : 1;
bool b : 1;
};
Run Code Online (Sandbox Code Playgroud)
如何确定S::a和S::b是在编译时位字段?
我试图提出一个类似的宏,IsBitField(S, a)但很难将 SFINAE 应用到offsetof()或addressof()(众所周知,每个位域的操作都是无效的)。