相关疑难解决方法(0)

什么是严格别名规则?

当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?

c strict-aliasing undefined-behavior type-punning

778
推荐指数
10
解决办法
19万
查看次数

在C中将大端转换为小端[不使用提供的函数]

我需要在C中编写一个将big endian转换为little endian的函数.我不能使用任何库函数.

c swap endianness

87
推荐指数
9
解决办法
33万
查看次数

为什么memcmp(a,b,4)有时只针对uint32比较进行优化?

鉴于此代码:

#include <string.h>

int equal4(const char* a, const char* b)
{
    return memcmp(a, b, 4) == 0;
}

int less4(const char* a, const char* b)
{
    return memcmp(a, b, 4) < 0;
}
Run Code Online (Sandbox Code Playgroud)

x86_64上的GCC 7引入了第一种情况的优化(Clang已经做了很长时间):

    mov     eax, DWORD PTR [rsi]
    cmp     DWORD PTR [rdi], eax
    sete    al
    movzx   eax, al
Run Code Online (Sandbox Code Playgroud)

但第二种情况仍然是memcmp():

    sub     rsp, 8
    mov     edx, 4
    call    memcmp
    add     rsp, 8
    shr     eax, 31
Run Code Online (Sandbox Code Playgroud)

是否可以对第二种情况应用类似的优化?什么是最好的装配,有没有明确的理由为什么它没有完成(由GCC或Clang)?

在Godbolt的Compiler Explorer上看到它:https://godbolt.org/g/jv8fcf

c gcc x86-64 clang compiler-optimization

68
推荐指数
3
解决办法
3930
查看次数

如何编写endian不可知的C/C++代码?

我做了一些谷歌搜索,在这个问题上找不到任何好文章.在实现我想要与endian无关的应用程序时,我应该注意什么?

c c++ endianness

35
推荐指数
4
解决办法
2万
查看次数

从二进制文件读取时将big endian转换为little endian

我一直在寻找如何将big-endian转换为little-endians.但我找不到任何可以解决我问题的好处.似乎有很多方法可以进行这种转换.无论如何,以下代码在big-endian系统中正常工作.但是我应该如何编写转换函数,以便它也适用于little-endian系统?

这是一个功课,但它只是一个额外的,因为在学校运行大端系统的系统.这只是我很好奇,并希望它也可以在我的家用电脑上工作

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
   ifstream file;

   file.open("file.bin", ios::in | ios::binary);

   if(!file)
      cerr << "Not able to read" << endl;
   else
   {
      cout << "Opened" << endl;

      int i_var;
      double d_var;

      while(!file.eof())
      {
         file.read( reinterpret_cast<char*>(&i_var) , sizeof(int) );
         file.read( reinterpret_cast<char*>(&d_var) , sizeof(double) );
         cout << i_var << " " << d_var << endl;
      }
   }
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

解决了

所以Big-endian VS Little-endian只是字节的逆序.我写的这个功能似乎无论如何都符合我的目的.我在这里添加它以防万一其他人将来需要它.这只是双倍,但是对于整数,要么使用建议的函数torak,要么可以通过使它仅交换4个字节来修改此代码.

double swap(double d)
{
   double a;
   unsigned char *dst = (unsigned …
Run Code Online (Sandbox Code Playgroud)

c++ binaryfiles endianness

18
推荐指数
2
解决办法
6万
查看次数

将整数写入二进制文件(C++)

我有一个非常简单的问题,这对我来说很难,因为这是我第一次尝试使用二进制文件,我不太了解它们.我想要做的就是将一个整数写入二进制文件.

我是这样做的:

#include <fstream>
using namespace std;
int main () {
    int num=162;
    ofstream file ("file.bin", ios::binary);
    file.write ((char *)&num, sizeof(num));
    file.close (); 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我做错了什么,你能告诉我什么?

给我带来麻烦的部分是与file.write一致,我不明白.

先感谢您.

c++ binary integer fstream

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

没有ntohs的字节顺序交换

我正在编写一个ELF分析器,但我在转换字节顺序方面遇到了一些麻烦.我有函数来确定分析器的字节顺序和目标文件的endiannness.

基本上,有四种可能的情况:

  1. 一个大端编译分析器在大端目标文件上运行
    • 没有必要转换
  2. 一个大端编译分析器在一个小端对象文件上运行
    • 字节顺序需要交换,但是ntohs/l()和htons/l()都是大端机器上的空宏,因此它们不会交换字节顺序.这就是问题
  3. 一个小端编译分析器在大端目标文件上运行
    • 字节顺序需要交换,所以使用htons()来交换字节顺序
  4. 一个小端编译分析器在一个小端对象文件上运行.
    • 没有必要转换

是否有一个函数我可以用来显式交换字节顺序/更改字节顺序,因为ntohs/l()和htons/l()考虑了主机的字节序,有时不转换?或者我是否需要查找/编写自己的交换字节顺序功能?

c++ endianness

9
推荐指数
3
解决办法
2万
查看次数

c/c ++中endian的最佳和可移植转换

给定一个需要解析的32位little-endian字段的二进制文件,我想编写正确编译的解析代码,而不依赖于执行该代码的机器的字节顺序.目前我用

uint32_t fromLittleEndian(const char* data){
  return uint32_t(data[3]) << (CHAR_BIT*3) |
         uint32_t(data[2]) << (CHAR_BIT*2) |
         uint32_t(data[1]) << CHAR_BIT |
         data[0]; 
}
Run Code Online (Sandbox Code Playgroud)

然而,这会产生不理想的装配.在我的机器上g++ -O3 -S产生:

_Z16fromLittleEndianPKc:
.LFB4:
    .cfi_startproc
    movsbl  3(%rdi), %eax
    sall    $24, %eax
    movl    %eax, %edx
    movsbl  2(%rdi), %eax
    sall    $16, %eax
    orl %edx, %eax
    movsbl  (%rdi), %edx
    orl %edx, %eax
    movsbl  1(%rdi), %edx
    sall    $8, %edx
    orl %edx, %eax
    ret
    .cfi_endproc
Run Code Online (Sandbox Code Playgroud)

为什么会这样?在小端机器上编译时,我怎么能说服它生成最佳代码:

_Z17fromLittleEndian2PKc:
.LFB5:
    .cfi_startproc
    movl    (%rdi), %eax
    ret
    .cfi_endproc
Run Code Online (Sandbox Code Playgroud)

我通过编译得到的:

uint32_t fromLittleEndian2(const char* data){
    return …
Run Code Online (Sandbox Code Playgroud)

c++ optimization endianness

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

如何字节换一个双?

我正在尝试为在Win XP上运行的C++程序编写一个byteswap例程.我正在使用Visual Studio 2008编译.这就是我想出的:

int byteswap(int v) // This is good
{
    return _byteswap_ulong(v);
}

double byteswap(double v) // This doesn't work for some values
{
    union { // This trick is first used in Quake2 source I believe :D
        __int64 i;
        double  d;
    } conv;
    conv.d = v;
    conv.i = _byteswap_uint64(conv.i);
    return conv.d;
}
Run Code Online (Sandbox Code Playgroud)

还有一个测试功能:

void testit() {
    double  a, b, c;
    CString str;

    for (a = -100; a < 100; a += 0.01) {
        b = byteswap(a);
        c …
Run Code Online (Sandbox Code Playgroud)

c++ endianness visual-studio-2008

6
推荐指数
3
解决办法
9873
查看次数

从Dukascopy读取数据滴答二进制文件

我已经下载了Dukascopy tick数据,我用easylzma库解压缩了它.原始压缩二进制文件是EURUSD/2010/00/08/12h_ticks.bi5(EURUSD/2010/ian/8/12h)解压后我们得到以下格式:

+-------------------------+--------+-------+
|           time          |  Bid   |   Ask |
+-------------------------+--------+-------+
000003CA 00022EC0 00022EB6 40CCCCCD 41180000
000004F5 00022EB6 00022EB1 4099999A 404CCCCD
Run Code Online (Sandbox Code Playgroud)

(您可以从以下网址下载原始压缩文件: EURUSD/2010/00/08/12h_ticks.bi5.使用lzma解压缩后我们得到文件: 12h_ticks)

读取二进制文件:

int ii1;
int ii2;
int ii3;
float ff1;
float ff2;
ifstream in("12h_ticks",ofstream::binary);
in.read((char*)(&ii1), sizeof(int));
in.read((char*)(&ii2), sizeof(int));
in.read((char*)(&ii3), sizeof(int));
in.read((char*)(&ff1), sizeof(float));
in.read((char*)(&ff2), sizeof(float));
std::cout << " ii1=" << ii1 << std::endl;
std::cout << " ii2=" << ii2 << std::endl;
std::cout << " ii3=" << ii3 << std::endl;
std::cout << …
Run Code Online (Sandbox Code Playgroud)

c++

6
推荐指数
2
解决办法
4588
查看次数