相关疑难解决方法(0)

C++的严格别名规则 - 'char'别名豁免是否为双向街道?

就在几周前,我了解到C++标准有一个严格的别名规则.基本上,我曾经问过一个关于移位的问题 - 而不是一次一个地移动每个字节,以最大化性能我想加载我的处理器的本机寄存器(分别为32或64位)并执行4/8的移位所有字节都在一条指令中.

这是我想避免的代码:

unsigned char buffer[] = { 0xab, 0xcd, 0xef, 0x46 };

for (int i = 0; i < 3; ++i)
{
  buffer[i] <<= 4; 
  buffer[i] |= (buffer[i + 1] >> 4);
}
buffer[3] <<= 4;
Run Code Online (Sandbox Code Playgroud)

相反,我想使用类似的东西:

unsigned char buffer[] = { 0xab, 0xcd, 0xef, 0x46 };
unsigned int *p = (unsigned int*)buffer; // unsigned int is 32 bit on my platform
*p <<= 4;
Run Code Online (Sandbox Code Playgroud)

有人在评论中提到我提出的解决方案违反了C++别名规则(因为p是类型int*,缓冲区是类型的char*,我正在取消引用p来执行移位.(请忽略对齐和字节顺序的可能问题 - 我处理那个片段之外的那些人)我很惊讶地了解他严格别名规则,因为我经常对缓冲区中的数据进行操作,将其从一种类型转换为另一种类型并且从未出现任何问题.进一步调查显示我使用的编译器(MSVC) )没有强制执行严格的别名规则,因为我只是在业余时间开发gcc/g ++作为业余爱好,我可能还没有遇到过这个问题.

那么我问了一个关于严格别名规则和C++的Placement new运算符的问题:

IsoCpp.org提供有关放置新的常见问题解答,它们提供以下代码示例:

#include …
Run Code Online (Sandbox Code Playgroud)

c++ strict-aliasing

15
推荐指数
1
解决办法
790
查看次数

是否使用了一个联合代替了一个定义好的角色?

今天早上我和一位同事讨论了关于检测字节序的"编码技巧"的正确性.

诀窍是:

bool is_big_endian()
{
  union
  {
    int i;
    char c[sizeof(int)];
  } foo;


  foo.i = 1;
  return (foo.c[0] == 1);
}
Run Code Online (Sandbox Code Playgroud)

对我来说,似乎这种用法union是不正确的,因为设置联合的一个成员并读取另一个成员的定义并不明确.但我必须承认,这只是一种感觉,我缺乏实际的证据来强化我的观点.

这个技巧是否正确?谁在这?

c++ standards endianness unions

13
推荐指数
2
解决办法
2368
查看次数

标签 统计

c++ ×2

endianness ×1

standards ×1

strict-aliasing ×1

unions ×1