在结构和模板中尝试工会和比特菲尔德
Experimenting with Unions and Bitfields within a structures and templates
获得更好的处理和了解结构的工作方式,我正在模拟模板寄存器结构。
我的登记册的要求如下:
- 寄存器的默认尺寸或宽度为8bits或1个字节
- 较大尺寸的寄存器必须是8的倍数
- 寄存器小于或等于64位或8个字节。
我有一组结构,这些结构从一个字节的基本单元开始到qword。
我的寄存器是模板专业。
这是我到目前为止的代码:
-main.cpp-
#include <iostream>
#include "Register.h"
int main() {
Register r1;
r1.value.value_ = 8;
Register<16> r2;
r2.value.value_ = 16;
Register<32> r3;
r3.value.value_ = 32;
Register<64> r4;
r4.value.value_ = 64;
std::cout << static_cast<std::uint8_t>( r1.value.value_) << "n";
std::cout << static_cast<std::uint16_t>(r2.value.value_) << "n";
std::cout << static_cast<std::uint32_t>(r3.value.value_) << "n";
std::cout << static_cast<std::uint64_t>(r4.value.value_) << "n";
return EXIT_SUCCESS;
}
-register.h-
#pragma once
#include <vector> // include for typedefs below.
typedef std::int8_t i8;
typedef std::int16_t i16;
typedef std::int32_t i32;
typedef std::int64_t i64;
struct MyByte {
union {
i8 value_;
struct {
i8 b0 : 1;
i8 b1 : 1;
i8 b2 : 1;
i8 b3 : 1;
i8 b4 : 1;
i8 b5 : 1;
i8 b6 : 1;
i8 b7 : 1;
};
};
};
struct MyWord { // same as short or i16
union {
i16 value_;
union {
MyByte byte_[2];
struct {
MyByte b0_;
MyByte b1_;
};
};
};
};
struct MyDWord { // same as int or i32
union {
i32 value_;
struct {
MyWord w0_;
MyWord w1_;
};
union {
MyByte byte_[4];
struct {
MyByte b0_;
MyByte b1_;
MyByte b2_;
MyByte b3_;
};
};
};
};
struct MyQWord { // same as long or i64
union {
i64 value_;
struct {
MyDWord d0_;
MyDWord d1_;
};
struct {
MyWord w0_;
MyWord w1_;
MyWord w2_;
MyWord w3_;
};
union {
MyByte byte_[8];
struct {
MyByte b0_;
MyByte b1_;
MyByte b2_;
MyByte b3_;
MyByte b4_;
MyByte b5_;
MyByte b6_;
MyByte b7_;
};
};
};
};
template<size_t N = 8>
struct Register {
MyByte value;
Register() {
static_assert(
((N % 8) == 0) &&
(N >= 8) &&
(N <= 64)
);
}
};
template<>
struct Register<16> {
MyWord value;
Register() = default;
};
template<>
struct Register<32> {
MyDWord value;
Register() = default;
};
template<>
struct Register<64> {
MyQWord value;
Register() = default;
};
上面的代码编译,运行和退出,并在Visual Studio 2017中使用0代码,并将编译器设置为最新草稿标准。
既然您已经看到了代码了,那么我在某种程度上就了解了比特菲尔德和工会,但是当我不使用它们时,他们经常会绊倒我。我确实知道,特别是以一种结合方式使用它们时,它可能会导致代码不可移植,尤其是在不同的编译器,操作系统和体系结构(Endian(之间。
。但是,这只是实验代码,可以作为一个很好的复习。
我在这里遇到的问题是我的输出。所有高阶寄存器似乎都可以正常工作,我只能直接通过内部成员变量值进行测试。但是,我从默认值或大多数基本注册中获得了8位大小的结果。随着目前的设置值。我将此作为输出:
--
16
32
64
,如果我将主要主机更改为
#include <iostream>
#include "Register.h"
int main() {
Register r;
for (i8 i = 0; i < 21; i++) {
1.value.value_ = i;
std::cout << static_cast<std::uint8_t>(r.value.value_) << "n";
}
return EXIT_SUCCESS;
}
我在其中的混合物中以蜂鸣声获得了此输出:
☺
☻
♥
♦
♣
♠
♂
♀
♫
☼
►
◄
↕
‼
¶
这与std::int8_t
的定义方式有关吗?它是基于char
值类型而不是int
类型吗?不过,它仍然是不可或缺的...如果是这种情况,那比必须在工会或比特菲尔德等内处理未签名的值吗?是什么导致ASCII符号打印到控制台。
它是基于char值类型而不是int类型的?
char
*是 *整数类型。该标准允许std::int8_t
是char
的Typedef。
std::cout << static_cast<std::uint64_t>(r.value.value_) << "n";
ftw。
相关文章:
- 瓦尔格林德:数学函数"Conditional jump or move depends on uninitialised value(s)"
- 为什么瓦尔格林德在不释放恶意内存后没有报告任何问题?
- C++结构到德尔福记录dll调用
- 瓦尔格林德的内存泄漏使用新的
- CPP 中的瓦尔格林德和记忆泄漏:"Conditional jump or move depends on uninitialised values"
- 在C++上实现高斯赛德尔迭代方法
- C++程序什么都不做,但瓦尔格林德显示内存分配
- 如何在德尔福中C++制作与此类似的结构
- 如何连接两个比特菲尔德
- 在结构和模板中尝试工会和比特菲尔德
- 来自数组的成员和比特菲尔德的结构
- 将1位宽的比特菲尔德设置为2表示Bitfield已设置或未设置
- [林菲尔]找不到"libgnustl_shared.so"
- 比特菲尔德,标志数为参数
- 如何将德尔菲的"字符串数组"参数翻译成C++?
- lexical_cast斯特托夫斯特托尔德失去了准确性
- 德尔菲函数和等价物C++
- 德尔菲相当于C++的记忆集吗?
- 德尔菲相当于C++"unsigned char"?
- 埃菲尔"create" C++构造函数?