如何解决在std :: uint8_t中移位位
我正在尝试将多个索引打包成一个字节(由GIF format定义):
never
我想使用
std::uint8_t global_color_table_flag; // bit [0]
std::uint8_t color_resolution; // bits [1-3]
std::uint8_t sort_flag; // bit [4]
std::uint8_t global_color_table_size; // bits [5-7]
但是左移位运算符std::uint8_t field = (global_color_table_flag << 7) |
(color_resolution << 4) | (sort_flag << 3) |
(global_color_table_size);
将我的<<
提升为std::uint8_t
,编译器抱怨(int
)。为什么?在-Werror
上使用它并不会提升到更大的int
。如果您不正确地使用它,它就是UB。为什么int
有什么不同?
如果我使用std::uint8_t
,则行为符合预期。但是,由于上述问题,代码相当难看:
std::byte
是否有更好的方法进行?作为附带的问题,为什么不能仅将std::byte global_color_table_flag_byte{global_color_table_flag};
global_color_table_flag_byte <<= 7;
std::byte color_resolution_byte{color_resolution};
color_resolution_byte <<= 4;
std::byte sort_flag_byte{sort_flag};
sort_flag_byte <<= 3;
std::byte global_color_table_size_byte{global_color_table_size};
std::byte packed_field = global_color_table_flag_byte |
color_resolution_byte | sort_flag_byte |
global_color_table_size_byte;
file_stream << std::to_integer<std::uint8_t>(packed_field);
写入二进制流?我认为这种类型的全部目的是为了便于操纵此类流。
解决方法
但是左移位运算符
因为您启用了一些在这种情况下会发出警告的编译器选项。
为什么移位运算符在int和std :: uint8_t上的工作方式不同。
由于std::uint8_t
是比int
小的类型,因此被提升。对于所有小于int
的类型和所有算术运算符(不仅仅是位移),都是相同的。
还有更好的方法吗?
您可以更改编译器选项,以不警告正确的表达式。
或者您可以根据编译器警告的内容对表达式进行一些更改。在不知道警告的情况下,我不能说得更具体。
我添加了所有警告
这通常不是很有用。使用-Wall
很好,但是由于某种原因它不能启用所有警告。排除在其中的许多警告选项适得其反,具有假阳性,或者仅用于调试复杂程序的含义而不是告知问题。
为什么我不能只将std :: byte写入二进制流?
将类型添加到语言中的提议并未提出字符流的其他重载。该提案并未包括这种选择的理由。但是我怀疑这是为了使更改保持最小。我不知道委员会是否讨论过这个问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。