C++ standard says only that int has to be at least 16 bits wide. And at least according to cppreference, it's almost always either 16 or 32 bits wide:
Run Code Online (Sandbox Code Playgroud)data model int width in bits ---------------------------------- C++ standard at least 16 LP32 16 ILP32 32 LLP64 32 LP64 32...
Other models are very rare. For example, ILP64 (8/8/8: int, long, and pointer are 64-bit) only appeared in some early 64-bit Unix systems (e.g. Unicos on Cray).
Is …
为什么C和C++中的基本类型没有像Java那样严格定义,其中a int始终为4个字节且long为8个字节等.据我所知,在C和C++中,只有a char被定义为1个字节,其他所有内容都由不同的编译器定义不同.所以int在C和C++中,只要它长于a short并且short更长,就不一定必须是4个字节char.
我只是想知道为什么会这样,它有用吗?
有没有人知道C标准支持的任何平台,对于这些平台仍然有积极的开发工作,但它们是:
编辑:或者,如果1995年至1998年期间有平台影响了C99决定包括上述内容,但已停止使用,我也会对它们感兴趣.
编辑:C理由有关填充位的说法:
填充位是用户可访问的无符号整数类型.例如,假设一台机器使用一对16位短路(每个都有自己的符号位)来构成一个32位的int,并且当在这个32位int中使用时,忽略较低short的符号位.然后,作为32位有符号整数,在确定32位有符号int的值时会忽略一个填充位(在32位的中间).但是,如果将此32位项目视为32位无符号整数,则该填充位对用户程序可见.C委员会被告知有一台机器以这种方式工作,这就是填充位被添加到C99的一个原因.
脚注44和45提到奇偶校验位可能是填充位.委员会不知道任何具有用户可访问的奇偶校验位的机器在整数内.因此,委员会不知道任何将奇偶校验位视为填充位的机器.
所以另一个问题是,C99提到的那台机器是什么?
编辑:看来,C99正在考虑消除对1的补支持和符号的振幅:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n868.htm HTTP://www.open- std.org/jtc1/sc22/wg14/www/docs/n873.htm(搜索6.2.6.2)
浮点是在C中定义的实现.因此没有任何保证.
我们的代码需要是可移植的,我们正在讨论在我们的协议中使用IEEE754浮点数是否可以接受.出于性能原因,如果我们不必在发送或接收数据时在固定点格式之间来回转换,那将是很好的.
虽然我知道平台和架构之间可能存在关于long或的大小的差异wchar_t.但我似乎无法找到任何具体的float和double.
到目前为止我发现字节顺序可能在大端平台上被反转.虽然有不带浮动包含代码,其中点支撑平台float和double甚至无法链接.否则平台似乎坚持IEEE754单精度和双精度.
那么可以假设浮点数在IEEE754可用时安全吗?
编辑:回应评论:
你对"安全"的定义是什么?
安全我的意思是,一个系统上的位模式在另一个系统上意味着相同(在字节旋转之后处理字节序).
我一直在寻找如何将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) 我%p在Stack Overflow中已经阅读了很多关于C语言中格式说明符用法的答案,但似乎没有一个解释为什么void*所有类型都需要显式转换为char*.
我当然知道这样一个事实,即强制转换的要求void*与使用可变函数(参见本答案的第一条评论)有关,而非强制性要求.
这是一个例子:
int i;
printf ("%p", &i);
Run Code Online (Sandbox Code Playgroud)
产生关于类型不兼容性的警告,并且&i应该进行铸造void*(根据标准的要求,再次参见此处).
虽然这一大块代码能够顺利编译,但没有关于类型转换的任何投诉:
char * m = "Hello";
printf ("%p", m);
Run Code Online (Sandbox Code Playgroud)
如何char*从这一要求中"解脱"?
PS:可能值得补充的是我在 x86_64架构上工作,因为指针类型大小依赖于它,并且使用 gcc作为linux上的-W -Wall -std=c11 -pedantic编译器和编译选项.
是否有一种有保证的(不是实现定义的!)方法来检查指针对齐?
查询指针对齐的最常见方法似乎是:
bool is_aligned(void const *ptr, size_t alignment) {
return reinterpret_cast<intptr_t>(ptr) % alignment == 0;
}
Run Code Online (Sandbox Code Playgroud)
例如,这就是Boost.Align 检查对齐方式的方式。
然而,至少在 C++17 中,basic.compound#3.4说:
指针类型的值表示是实现定义的。
指针可以显式转换为任何足够大以容纳它的整型。映射函数是实现定义的。
(例如)将指针表示为具有相反位顺序的整数似乎是合法的,在这种情况下,上面的简单算术将不起作用。
AFAICT,我们可以检查对齐的唯一有保证的方法是使用std::align,如果自由地阅读(我确信这是对 的滥用std::align),可以像这样使用:
bool is_aligned(void const *ptr, size_t alignment) {
void *mut_ptr = const_cast<void *>(ptr);
size_t space = alignment;
return std::align(alignment, alignment, mut_ptr, space) == ptr;
}
Run Code Online (Sandbox Code Playgroud)
然而,在绝大多数平台上,指针只是奇特的整数,或者我希望 Boost 有一个代码路径。是否有任何平台(除了 ds9k :P)其中指针不仅仅是花哨的整数?
通过标准化“应具有与”或“如果与”对齐reinterpret_cast<intptr_t>(ptr)相同的对象表示,我们会损失什么?似乎这些都不会排除分段内存或具有陷阱表示的指针,这是我能想到的两种非典型情况。ptrreinterpret_cast<intptr_t>(ptr) % alignment == 0ptr …
ISO C标准要求CHAR_BIT至少为8.
POSIX强制CHAR_BIT等于8,并且(几乎?)所有使用八位字节的网络和通信标准,是否有任何当代C实现CHAR_BIT> 8?
(注意:我对使用18或36位字的历史计算机体系结构不感兴趣.这是关于C的真正问题,因为它在当前的硬件上使用;考虑使用C99或更高版本的系统).
在128位数字变为现实之前,长64位并保留很长时间是不是更有意义?
当fgetc用于读取流的下一个字符时,通常会检查是否未达到文件结尾
if ((c = fgetc (stream)) != EOF)
Run Code Online (Sandbox Code Playgroud)
哪里c是int类型.然后,文件结束已经达到并且条件将失败,或者c应该是unsigned转换为的char int,预期与EOF-c 不同,因为EOF确保为负.很好......显然.
但是有一个小问题......通常char类型不超过8位,而且int必须至少有16位,所以每个unsigned char都可以表示为int.然而,在这种情况下char会有16或32位(我知道,在实践中情况从来都不是这样......),没有理由为什么人们不能拥有sizeof(int) == 1,所以它(理论上!)可能fgetc (stream)返回EOF(或另一个负值)但文件结尾尚未达到......
我错了吗?如果没有达到文件结尾,C标准中是否会阻止fgetc返回EOF?(如果是的话,我找不到它!).或者if ((c = fgetc (stream)) != EOF)语法不完全可移植?...
编辑:的确,这是问题#3860943的重复.我在第一次搜索时没有找到这个问题.谢谢您帮忙!:-)