相关疑难解决方法(0)

*可能*未签名的字符等于EOF?

fgetc用于读取流的下一个字符时,通常会检查是否未达到文件结尾

if ((c = fgetc (stream)) != EOF)
Run Code Online (Sandbox Code Playgroud)

哪里cint类型.然后,文件结束已经达到并且条件将失败,或者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 unsigned char eof fgetc

10
推荐指数
1
解决办法
373
查看次数

C ++ 20的分支需要二进制补码

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并不要求补码。)

这是否只是委员会的优先事项?还是有理由不利用两国补编任务规定所提供的简化和确定性?

c++ undefined-behavior twos-complement c++20

10
推荐指数
1
解决办法
267
查看次数

如何测试是否支持类似uint64_t的类型?

如何测试编译器是否支持某种类型?像uint64_t一样说.有什么参考我可以用来学习如何测试任何给定的类型吗?

很难通过搜索引擎找到它.我尝试了"C测试数据类型"和许多其他的东西.

c

8
推荐指数
1
解决办法
1257
查看次数

为什么所有数据类型都是2的幂?

为什么所有数据类型大小总是2的幂?

我们举两个例子:

short int 16
char 8
Run Code Online (Sandbox Code Playgroud)

他们为什么不跟随?

short int 12
Run Code Online (Sandbox Code Playgroud)

c++ programming-languages

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

为什么int 1的最小值比正值更远离零?

我想知道为什么int,double等比正值多1个负值.

c c++ java math numbers

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

char*的大小是否与int*的大小相同?

我知道:char*是一个指向char的指针.和int*是指向int的指针.

所以,我想确认以下两件事:

  1. 所以现在假设我在32位机器上,那么这意味着内存地址是32位宽.这意味着char*和int*的大小都是32位(4字节),对吧?char**的大小也与int*的大小相同?

  2. 假设我有:int*ptr;

因此现在做*((char**)ptr)= 0x154与*((int*)ptr)= 0x514相同,对吧?(0x514只是任意随机存储器地址)

平台:我在x86上.

PS:我知道类型转换不是建议的代码方式.但我正在做内核编码,因此我必须做类型转换!

c assembly pointers dereference

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

什么是"Portable C++"?

在互联网上,我看到声称用便携式C++编写的库,好像它是一个(可能是非官方的)标准.

什么是可移植的C++有一个精确的定义,如果有,它是什么?

我不是要求编写可移植代码的常用做法,但如果真的有什么我们称之为"可移植的c ++".

c++

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

C++ 11在异国情调的硬件上

在2011年之前有一个类似的问题:标准委员会关心的异域架构

现在,我想问一个非常相似的问题,但这一次,我是从程序员的角度和C++ 11的角度来看问题.

目前存在哪些硬件,它有一个C++ 11编译器,可以被认为是异国情调?

我认为异国情调?

  • 其中char不是8位
  • 其中IEEE 754浮点数格式不可用
  • 其中整数不以两个补码编码
  • 其中编译器不支持8,16或32位类型
  • 内存模型不是线性的(所以你不能比较/减去任何指针)

所以我们在x86/ARM世界看到的任何不是标准的东西,我们在那里:

  • 有8/16/32位两个补码整数
  • IEEE754浮动,一些完全兼容,一些不,但使用IEEE754格式
  • 线性记忆模型

注意:我想得到答案,其中硬件存在符合C++ 11标准的编译器,而不存在C++编译器,但不完全符合.

我问这个,因为很多时候,我得到的答案就像"你不能依赖它,它是实现定义的",而且我想知道,实际上,在现实世界中,我可以依赖多少在标准上.举个例子:每当我写作时std::uint16_t,我可能会担心(因为这个功能是可选的),在平台上,这种类型是不存在的.但是,是否存在这种类型不存在的实际平台?

c++ c++11

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

EOF的实际实现不同于-1

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 posix eof language-lawyer

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

指向不同类型的指针可以有不同的二进制表示吗?

我想知道是否允许 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上面的例子。)

c++ pointers language-lawyer bit-representation

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