相关疑难解决方法(0)

访问非活动的union成员和未定义的行为?

我的印象是访问union除最后一个成员之外的成员是UB,但我似乎无法找到一个可靠的参考(除了声称它是UB但没有标准支持的答案).

那么,这是不确定的行为?

c++ undefined-behavior unions language-lawyer

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

C程序检查小与大端

可能重复:
C宏定义确定大端或小端机器?

int main()
{
  int x = 1;

  char *y = (char*)&x;

  printf("%c\n",*y+48);
}
Run Code Online (Sandbox Code Playgroud)

如果它是小端,它将打印1.如果它是大端,它将打印0.这是正确的吗?或者将char*设置为int x始终指向最低有效位,而不管字节顺序如何?

c byte endianness

60
推荐指数
4
解决办法
14万
查看次数

在编译时确定字节序

是否有一种安全,可移植的方法来确定(在编译期间)我的程序正在编译的平台的字节顺序?我在用C写作

[编辑]感谢您的回答,我决定坚持运行时解决方案!

c endianness

59
推荐指数
8
解决办法
3万
查看次数

为什么在C++中没有像签名那样的字节顺序修饰符?

(我想这个问题可能适用于许多类型语言,但我选择使用C++作为例子.)

为什么没有办法写:

struct foo {
    little int x;   // little-endian
    big long int y; // big-endian
    short z;        // native endianness
};
Run Code Online (Sandbox Code Playgroud)

指定特定成员,变量和参数的字节顺序?

与签名比较

我知道变量的类型不仅决定了用于存储值的字节数,还决定了在执行计算时如何解释这些字节.

例如,这两个声明每个都分配一个字节,对于两个字节,每个可能的8位序列都是有效值:

signed char s;
unsigned char u;
Run Code Online (Sandbox Code Playgroud)

但是相同的二进制序列可能会有不同的解释,例如11111111,在分配时指的是-1,而指定时指的是s255 u.当有符号和无符号变量涉及相同的计算时,编译器(主要)负责正确的转换.

在我的理解中,字节序只是同一原则的变体:基于关于存储它的存储器的编译时信息对二进制模式的不同解释.

在允许低级编程的类型语言中使用该功能似乎是显而易见的.但是,这不是C,C++或我所知的任何其他语言的一部分,我没有在网上找到任何关于此的讨论.

更新

我会试着总结一下我在询问后的第一个小时内收到的许多评论中的一些内容:

  1. signness是严格二进制的(无论是有符号还是无符号),并且总是与endianness相反,endianness也有两个众所周知的变体(大和小),但也有较少知名的变体,如mixed/middle endian.未来可能会发明新的变种.
  2. 字节顺序访问多字节值时,字节顺序很重要.除了字节序之外还有很多方面会影响多字节结构的内存布局,所以这种访问通常是不受欢迎的.
  3. C++旨在针对抽象机器并最小化有关实现的假设数量.这个抽象机器没有任何字节序.

此外,现在我意识到签名和字节序不是一个完美的类比,因为:

  • endianness仅定义某些事物如何表示为二进制序列,但现在可以表示什么.双方big intlittle int会具有完全相同的数值范围.
  • 有符号性定义比特和实际值如何相互映射,但也影响可以表示的内容,例如-3不能用a表示unsigned char(假设char有8位)130不能用a表示signed …

c++ language-features static-typing endianness

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

53
推荐指数
8
解决办法
6万
查看次数

有没有办法做一个C++样式的编译时断言来确定机器的字节序?

我有一些模板化的低级序列化代码,我需要在编译时明确知道系统的字节顺序(因为模板专门基于系统的字节顺序).

现在我有一个带有一些平台定义的标题,但是我宁愿通过一些模板化测试(如static_assert或boost_if)来做关于字节序的断言.原因是我的代码需要编译并在许多专业供应商的各种机器上运行,并且可能是2008年不存在的设备,因此我无法猜测可能需要进入标题年份的内容在路上.而且由于代码库的预期寿命约为10年.所以我无法永远遵循代码.

希望这能使我的情况变得清晰.

那么有没有人知道可以确定字节序的编译时测试,而不依赖于供应商特定的定义?

c++ templates metaprogramming endianness

30
推荐指数
3
解决办法
7728
查看次数

如何让GCC为没有内置的大端存储生成bswap指令?

我正在研究一种以大端格式将64位值存储到内存中的函数.我希望我能编写可在小端大端平台上运行的移植C99代码,并让现代x86编译器bswap自动生成指令而不需要任何内置函数或内在函数.所以我开始使用以下功能:

#include <stdint.h>

void
encode_bigend_u64(uint64_t value, void *vdest) {
    uint64_t bigend;
    uint8_t *bytes = (uint8_t*)&bigend;
    bytes[0] = value >> 56;
    bytes[1] = value >> 48;
    bytes[2] = value >> 40;
    bytes[3] = value >> 32;
    bytes[4] = value >> 24;
    bytes[5] = value >> 16;
    bytes[6] = value >> 8;
    bytes[7] = value;
    uint64_t *dest = (uint64_t*)vdest;
    *dest = bigend;
}
Run Code Online (Sandbox Code Playgroud)

这适用于clang,它将此函数编译为:

bswapq  %rdi
movq    %rdi, (%rsi)
retq
Run Code Online (Sandbox Code Playgroud)

但是GCC 无法检测到字节交换 …

c x86 gcc endianness compiler-optimization

19
推荐指数
2
解决办法
7215
查看次数

检测字节序

我正在尝试创建一个C源代码,无论目标系统的字节顺序如何,它都能正确处理I/O.

我选择了"little endian"作为我的I/O约定,这意味着,对于大端CPU,我需要在写入或读取时转换数据.

转换不是问题.我面临的问题是检测字节序,最好是在编译时(因为CPU在执行过程中不会改变字节序...).

到目前为止,我一直在使用这个:

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
...
#else
...
#endif
Run Code Online (Sandbox Code Playgroud)

它被记录为GCC预定义的宏,而Visual似乎也理解它.

但是,我收到报告说某些big_endian系统(PowerPC)的检查失败了.

所以,我正在寻找一个万无一失的解决方案,确保无论编译器和目标系统如何都能正确检测到字节顺序.好吧,他们中的大多数至少......

[编辑]:提出的大多数解决方案都依赖于"运行时测试".编译期间编译器有时可以正确评估这些测试,因此不会产生实际的运行时性能.

然而,用某种<< if (0) { ... } else { ... }>> 分支是不够的.在当前的代码实现中,变量和函数声明依赖于big_endian检测.使用if语句无法更改这些内容.

嗯,显然,有后备计划,即重写代码......

我宁愿避免这种情况,但是,它看起来像是一个越来越少的希望......

[编辑2]:我通过深度修改代码测试了"运行时测试".尽管他们正确地完成了工作,但这些测试也会影响性能.

我期待着,因为测试具有可预测的输出,编译器可以消除坏分支.但不幸的是,它并不是一直有效.MSVC是一个很好的编译器,并且成功地消除了坏分支,但是GCC的结果是混合的,这取决于版本,测试类型,以及对64位比对32位的影响更大.

真奇怪.而且这也意味着无法确保编译器处理运行时测试.

编辑3:这些天,我正在使用编译时常量联合,期望编译器将其解析为明确的是/否信号.它运作得很好:https: //godbolt.org/g/DAafKo

c endianness compile-time c-preprocessor

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

哪些标准C++功能可用于查询机器/ OS架构?

用于查询程序运行的硬件或操作系统功能属性的标准C++功能和实用程序是什么?
例如,std::thread::hardware_concurrency()为您提供机器支持的线程数.
但是,如何检测计算机具有多少RAM,或者进程使用了​​多少RAM,或者在某个目录中可以写入多少磁盘空间,或者有多少L2缓存可用?

我更喜欢通过()标准的答案,但TR2或者建议也会很好.

c++ computer-architecture c++11 c++14

16
推荐指数
4
解决办法
1312
查看次数

将整数写入二进制文件(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万
查看次数