当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的重复.我在第一次搜索时没有找到这个问题.谢谢您帮忙!:-)
C ++ 20将指定带符号整数类型必须使用二进制补码。鉴于(实际上?)每个实现当前都使用二进制补码,这似乎不是一个很大的变化。
但是我想知道这种改变是否会将某些“未定义的行为”转变为“实现定义”甚至“定义”。
考虑绝对值函数std::abs(int)及其一些重载。C ++标准通过引用C标准来包括此功能,该标准表示如果无法表示结果,则行为未定义。
用二进制补码时,没有与之相对应的正数INT_MIN:
abs(INT_MIN) == -INT_MIN == undefined behavior
Run Code Online (Sandbox Code Playgroud)
在符号幅度表示中,有:
-INT_MIN == INT_MAX
Run Code Online (Sandbox Code Playgroud)
因此,abs()留下一些未定义的行为似乎是合理的。
一旦需要二进制补码,abs(INT_MIN)就可以完全指定行为,或者至少定义实现,这似乎是有意义的,而没有任何向后兼容的问题。但我看不到有任何建议的改变。
我看到的唯一缺点是C ++标准将需要abs()明确指定,而不是引用C标准的abs()。(据我所知,C并不要求补码。)
这是否只是委员会的优先事项?还是有理由不利用两国补编任务规定所提供的简化和确定性?
如何测试编译器是否支持某种类型?像uint64_t一样说.有什么参考我可以用来学习如何测试任何给定的类型吗?
很难通过搜索引擎找到它.我尝试了"C测试数据类型"和许多其他的东西.
为什么所有数据类型大小总是2的幂?
我们举两个例子:
short int 16
char 8
Run Code Online (Sandbox Code Playgroud)
他们为什么不跟随?
short int 12
Run Code Online (Sandbox Code Playgroud) 我知道:char*是一个指向char的指针.和int*是指向int的指针.
所以,我想确认以下两件事:
所以现在假设我在32位机器上,那么这意味着内存地址是32位宽.这意味着char*和int*的大小都是32位(4字节),对吧?char**的大小也与int*的大小相同?
假设我有:int*ptr;
因此现在做*((char**)ptr)= 0x154与*((int*)ptr)= 0x514相同,对吧?(0x514只是任意随机存储器地址)
平台:我在x86上.
PS:我知道类型转换不是建议的代码方式.但我正在做内核编码,因此我必须做类型转换!
在互联网上,我看到声称用便携式C++编写的库,好像它是一个(可能是非官方的)标准.
什么是可移植的C++有一个精确的定义,如果有,它是什么?
我不是要求编写可移植代码的常用做法,但如果真的有什么我们称之为"可移植的c ++".
在2011年之前有一个类似的问题:标准委员会关心的异域架构
现在,我想问一个非常相似的问题,但这一次,我是从程序员的角度和C++ 11的角度来看问题.
目前存在哪些硬件,它有一个C++ 11编译器,可以被认为是异国情调?
我认为异国情调?
所以我们在x86/ARM世界看到的任何不是标准的东西,我们在那里:
注意:我想得到答案,其中硬件存在符合C++ 11标准的编译器,而不存在C++编译器,但不完全符合.
我问这个,因为很多时候,我得到的答案就像"你不能依赖它,它是实现定义的",而且我想知道,实际上,在现实世界中,我可以依赖多少在标准上.举个例子:每当我写作时std::uint16_t,我可能会担心(因为这个功能是可选的),在平台上,这种类型是不存在的.但是,是否存在这种类型不存在的实际平台?
POSIX定义EOF为扩展为负值的宏:
标头应定义以下宏,该宏将扩展为具有int类型和负值的整数常量表达式:
EOF
文件结束返回值.
在每一个我能找到的实现,EOF是始终定义为-1.
虽然标准确实允许不同的值,但我找不到任何特定的实现,并且我想找到一个用于测试目的.1
1 我可以自己实现,但我的真正目的是"在野外找到它",由于不可能证明它不存在,这是我能想到的下一个最好的事情.
已经提出了一个几乎相同的问题,但最后提出了两个问题,接受的答案只回答了第二个问题(约WEOF).一个不同的用户回答了第一个问题,但由于问题仅限于普通的C环境,否则可以说是正确的:-1可能用于任何具有小字符类型的合理实现.
由于我的问题是关于存在,实际回答它的唯一方法是提供一个例子,所以我将重新说明它:请提供一个现有实现的例子EOF != -1.无论是newlib还是musl,PDP或VAX,Plan 9或Hurd,libc /硬件/操作系统与POSIX兼容或ISO C兼容的libc的任何组合都是有效的.
我想知道是否允许 C++ 实现以不同方式表示指向不同类型的指针。例如,如果我们有 4 字节大小/对齐int和 8 字节大小/对齐long,是否可以将指向int/ 的指针表示long为对象地址分别右移 2/3 位?这将有效地禁止将指向指针转换为指向long指针int。
我问是因为[expr.reinterpret.cast/7]:
对象指针可以显式转换为不同类型的对象指针。当
v对象指针类型的纯右值转换为对象指针类型“指向cv 的 指针T”时,结果为static_cast<cv T*>(static_cast<cv void*>(v))。[注7:将指向
T1对象类型的“指向”类型的指针转换为“指向”T1类型的指针T2(其中T2是对象类型,对齐要求T2不比 更严格T1)并返回到其原始类型type 产生原始指针值。—尾注]
第一句暗示我们可以将指针转换为任意两种对象类型。但是,(非规范性)注释 7 中的移情文本表示对齐在这里也起到了一定的作用。(这就是为什么我想出了这个int-long上面的例子。)