相关疑难解决方法(0)

uint8_t vs unsigned char

在C 中使用uint8_tover有什么好处unsigned char?

我知道几乎每个系统uint8_t都只是一个typedef unsigned char,为什么要用呢?

c typedef

218
推荐指数
6
解决办法
28万
查看次数

使用此指针会在热循环中导致奇怪的去优化

我最近遇到了一个奇怪的去优化(或者错过了优化机会).

考虑此函数可以有效地将3位整数数组解包为8位整数.它在每次循环迭代中解包16个int:

void unpack3bit(uint8_t* target, char* source, int size) {
   while(size > 0){
      uint64_t t = *reinterpret_cast<uint64_t*>(source);
      target[0] = t & 0x7;
      target[1] = (t >> 3) & 0x7;
      target[2] = (t >> 6) & 0x7;
      target[3] = (t >> 9) & 0x7;
      target[4] = (t >> 12) & 0x7;
      target[5] = (t >> 15) & 0x7;
      target[6] = (t >> 18) & 0x7;
      target[7] = (t >> 21) & 0x7;
      target[8] = (t >> 24) & 0x7;
      target[9] = …
Run Code Online (Sandbox Code Playgroud)

c++ optimization strict-aliasing compiler-optimization c++11

117
推荐指数
3
解决办法
5163
查看次数

char*和std :: uint8_t之间的reinterpret_cast* - 安全吗?

现在我们有时必须使用二进制数据.在C++中,我们使用字节序列,因为开头char是我们的构建块.定义为sizeof1,它是字节.char默认情况下,所有库I/O函数都使用.一切都很好,但总是有一点担心,有点奇怪,一些人的错误 - 一个字节中的位数是实现定义的.

所以在C99中,决定引入几个typedef让开发人员轻松表达自己的固定宽度整数类型.当然可选,因为我们从不想伤害便携性.其中uint8_t,迁移到C++ 11中std::uint8_t,固定宽度的8位无符号整数类型,对于真正想要使用8位字节的人来说是完美的选择.

因此,开发人员接受了新工具并开始构建库,这些库明确表示它们接受8位字节序列std::uint8_t*,std::vector<std::uint8_t>或者其他方式.

但是,或许经过深思熟虑,标准化委员会决定不要求实施,std::char_traits<std::uint8_t>因此禁止开发人员轻松,便携地实例化,比如说,std::basic_fstream<std::uint8_t>并轻松读取std::uint8_t二进制数据.或许,我们中的一些人不关心字节中的位数并且对它感到满意.

但遗憾的是,两个世界相互冲突,有时您必须将数据作为char*并将其传递给期望的库std::uint8_t*.但是等等,你说,是不是char变量位并std::uint8_t固定为8?它会导致数据丢失吗?

嗯,这里有一个有趣的标准.的char定义为保持正好一个字节和字节是内存的最低可寻址的块,所以用比特宽度比的较小不能有一个类型char.接下来,它被定义为能够保存UTF-8代码单元.这给了我们最小--8位.所以现在我们有一个typedef,它要求是8位宽,并且是一个至少8位宽的类型.但有其他选择吗?是的,unsigned char.请记住,签名char是实现定义的.还有其他任何一种 谢天谢地,没有.所有其他整数类型都需要超出8位的范围.

最后,std::uint8_t是可选的,这意味着如果未定义使用此类型的库将无法编译.但如果它编译呢?我可以非常自信地说,这意味着我们在8位字节的平台上CHAR_BIT == 8.

一旦我们有这方面的知识,我们已经8位字节,这std::uint8_t是实现为char或者unsigned char,我们可以假设,我们可以做reinterpret_cast的char*到std::uint8_t*,反之亦然?它是便携式的吗?

这是我的Standardese阅读技巧让我失望的地方.我读了关于安全派生的指针([basic.stc.dynamic.safety]),据我所知,以下内容:

std::uint8_t* buffer = /* ... */ ;
char* buffer2 …
Run Code Online (Sandbox Code Playgroud)

c++ strict-aliasing language-lawyer c++11 uint8t

58
推荐指数
2
解决办法
1万
查看次数

如果“long”和“int”的大小在一个平台上相同——“long”和“int”有什么不同吗?

如果 along int和 aint在平台上的表示相同,它们是否严格相同?根据 C 标准,这些类型在平台上的行为是否有任何不同?

例如。这是否总是有效:

int int_var;
long long_var;

void long_bar(long *l);
void int_bar(int *i);

void foo() 
{
    long_bar(&int_var); /* Always OK? */
    int_bar(&long_var);
}
Run Code Online (Sandbox Code Playgroud)

我想同样的问题适用于 short 和 int,如果它们碰巧是相同的表示。

在讨论如何为int32_t没有 stdint.h 的嵌入式 C89 编译器定义一个-like typedef时出现了问题,即 as intorlong以及是否重要。

c types integer representation

50
推荐指数
3
解决办法
4234
查看次数

c ++中最大的整数数据类型?

哪个是c ++中最大的整数数据类型?

c++

15
推荐指数
4
解决办法
3万
查看次数

从std :: stringstream读取uint8_t作为数字类型

我的理解是,uint8_t从a 中读取stringstream是一个问题,因为stringstream它将把它解释uint8_t为a char.我想知道如何uint8_t从stringstream一个数字类型中读取a .例如,以下代码:

#include <iostream>
#include <sstream>

using namespace std;

int main()
{
    uint8_t ui;
    std::stringstream ss("46");
    ss >> ui;
    cout << unsigned(ui);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

打印出来52.我想打印出来46.

编辑:另一种做法只是读取string距离stringstream,然后转换解决方案uint8_t,但是这打破了很好的链接属性.例如,在我必须编写的实际代码中,我经常需要这样的东西:

   void foobar(std::istream & istream){
       uint8_t a,b,c;
       istream >> a >> b >> c;
       // TODO...
   }
Run Code Online (Sandbox Code Playgroud)

c++

9
推荐指数
1
解决办法
641
查看次数

如何创建一个不破坏严格别名的uint8_t数组?

我最近问了这个问题:

使用此指针会在热循环中导致奇怪的去优化

问题是我正在写一个类型的数组,uint8_t并且编译器将它视为可以使用this方法的指针(类型struct T*)进行别名,因为void*和char*(= uint8_t*)总是可以在C++中对任何其他指针进行别名.此行为导致错过优化机会.当然,我想避免这种情况.所以问题是:我是否可以声明一个uint8_t强制执行严格别名的数组,即编译器将其视为从不与另一种类型的指针混淆?也就是说,我在寻找的东西像一个strict_uint8_t类型,它是一种uint8_t具有特殊混淆的行为.有没有办法实现这个目标?

显示我的意思的示例代码,借用其他问题并简化.有关更多详细信息,请阅读链接的问题及其接受的答案:

struct T{
   uint8_t* target;
   void unpack3bit(char* source, int size) {
        while(size > 0){
           uint64_t t = *reinterpret_cast<uint64_t*>(source);
           /** `this->target` cannot be cached in a register here but has
               to be reloaded 16 times because the compiler
               thinks that `this->target` could alias with `this` itself.
               What I want is a special uint8_t type that does not trigger
               this …
Run Code Online (Sandbox Code Playgroud)

c++ pointers strict-aliasing c++11

8
推荐指数
1
解决办法
921
查看次数

std :: uint8_t的底层类型

问题:
是否存在任何c ++工具链,std::uint8_t但不是unsigned char(或者char,如果它是无符号的)的typedef ?

编辑:相反:在符合标准的实施中,这样的事情是否可能?

背景/动机:
我主要是因为我想知道是否std::uint8_t*可以移植来访问单个字节(就像unsigned char*).是的,我知道std::byte,但这不相关.我主要对x86,arm和mips的工具链感兴趣,但出于好奇,我也想听听其他的例子.

c++ standard-library

8
推荐指数
1
解决办法
404
查看次数

将任何数据类型序列化为vector <uint8_t> - 使用reinterpret_cast?

我没有找到与搜索直接相关的任何内容,所以请原谅这是否重复.

我想要做的是通过网络连接序列化数据.我的方法是将我需要传输的所有内容转换std::vector< uint8_t >为接收方并将数据解压缩到适当的变量中.我的方法如下:

template <typename T>
inline void pack (std::vector< uint8_t >& dst, T& data) {
    uint8_t * src = static_cast < uint8_t* >(static_cast < void * >(&data));
    dst.insert (dst.end (), src, src + sizeof (T));
}   

template <typename T>
inline void unpack (vector <uint8_t >& src, int index, T& data) {
    copy (&src[index], &src[index + sizeof (T)], &data);
}
Run Code Online (Sandbox Code Playgroud)

我正在使用它

vector< uint8_t > buffer;
uint32_t foo = 103, bar = 443;
pack (buff, foo);
pack (buff, …
Run Code Online (Sandbox Code Playgroud)

c++ serialization templates network-programming

7
推荐指数
2
解决办法
1万
查看次数

如何拥有类似于 unsigned char 的类型,但不允许别名?

我想要一个类型,如下所示unsigned char:

\n\n
    \n
  • 大小为 1
  • \n
  • 可以为其分配整数值(无需任何强制转换)
  • \n
  • 允许位操作
  • \n
  • 算术是允许的,但不是必须的
  • \n
  • 未签名
  • \n
  • 可以简单地复制
  • \n
\n\n

但是,与 不同的是unsigned char,它不允许使用别名。我的意思是,一种没有例外的类型[basic.lval/11.8]:

\n\n
\n

如果程序尝试通过以下类型之一以外的泛左值访问对象的存储值,则行为未定义:

\n\n

[...]

\n\n
    \n
  • 一个 char,无符号字符或 std\xe2\x80\x8b::\xe2\x80\x8bbyte 类型。
  • \n
\n
\n\n

有可能有这样的类型吗?

\n\n

原因是:我几乎从不使用unsigned char\ 的别名属性。因此,我想使用一种类型,它不会阻止某些类型的优化(注意,我问这个问题是因为我实际上有一些函数,由于允许别名,因此没有很好地优化)的财产unsigned char)。因此,我希望有一种类型能够满足这一点:“不要为不使用的东西付费”。

\n\n
\n\n

这是一个unsigned char阻止优化的示例:使用此指针会导致热循环中奇怪的去优化

\n

c++ c++17

5
推荐指数
1
解决办法
433
查看次数

使用memcpy将float数组复制到uint8_t数组是否有效

我有一个浮点数组(每个浮点数4个字节),我想将数据复制到一个字节数组(uint8_t)并将其视为字节.后来我可能想要将字节数据复制回浮点数组,并将其再次作为各种操作的浮点数处理.这在c ++中有效吗?换句话说,就像这样,我暂时将浮点数视为字节有效?

std::array<std::uint8_t, 40> b;
b.fill(0);
std::array<float,10> f;
f.fill(3.14);
std::memcpy(b.data(),f.data(),40);
std::array<float,10> f2;
f2.fill(0);
std::memcpy(f2.data(),b.data(),40);
for(std::size_t i=0;i<10;i++)
{
  std::cout<<f2[i]<<std::endl; //now i want to access the float data
} 
Run Code Online (Sandbox Code Playgroud)

c++

2
推荐指数
1
解决办法
147
查看次数

在 C++ 中,为什么要使用 `uint8_t` 来声明字符串?

作为使用 React Native 的移动开发人员,我需要使用创建和加密文件的 C++ 代码。我对 C++ 没有太多经验(我上次写一些东西已经是 15 年前在大学时的事了)。

如果我错了,请纠正我。

这让我很烦恼。这是文件的类型定义:

typedef struct File 
{
    uint8_t FileName[64];
    uint8_t userName[64];
}File;
Run Code Online (Sandbox Code Playgroud)

为什么要使用类型uint8_t来存储字符串而不是std::string?

后来,事情变得更加扑朔迷离。我们需要将所有字符一一解析出来,并写入到临时文件中。

#define FILE_NAME_LEN   64


CustomFile CFile::getCustomFileFromFile(tFile f_File)
{
    CustomFile returnValue;
    for(int i = 0;i<FILE_NAME_LEN;i++){
        returnValue.FileName[i] = f_File.FileName[i]; 
    }
    for(int i = 0;i<FILE_NAME_LEN;i++){
        returnValue.user_name[i] = f_File.user_name[i];
    }
    return returnValue;
}



bool WriteEncryptFile(QString fpath,tFile *p_tFile)
{
    // Convert the tFile object to a CustomFile object
    CustomFile customFile = CFile::getCustomFileFromFile(*p_tFile);
}
Run Code Online (Sandbox Code Playgroud)

c++ uint8t

2
推荐指数
1
解决办法
275
查看次数

铸造时字节序是否重要

假设我有一个枚举,它只包含最多 0xFF 的值。我想将该枚举值放入一个字节变量中。AFAIK 枚举int位于 (vxWorks) 下方。我正在编码的机器是大端。当我想将它放入 uint8_t 时,我不明白这是否重要。这些选项中哪些有效,哪些是最好的?

typedef enum {
  kEnum1 = 0x00,
  kEnum2 = 0x01,
  kEnum3 = 0xFF
} MyEnum;

MyEnum myenum = kEnum3;
uint8_t mybyte = 0;

// option 1, do nothing
mybyte = myenum ;

// option 2, explicit cast
mybyte = (uint8_t)myenum;

// option 3, use operators
mybyte = (myenum & 0xFF000000) >> 24;
Run Code Online (Sandbox Code Playgroud)

当我在一个我认为是小端的在线编译器上测试时,选项 3 当然不起作用。但其他人会。我只是不明白大端机器将如何对待这些选项。

c

0
推荐指数
1
解决办法
56
查看次数