繁体   English   中英

Memory 浪费? 如果 main() 应该只返回 0 或 1,为什么 main 声明为 int 而不是 short int 甚至 char?

[英]Memory waste? If main() should only return 0 or 1, why is main declared with int and not short int or even char?

例如:

#include <stdio.h> 
int main (void)                         /* Why int and not short int? - Waste of Memory */ 
{
     printf("Hello World!");
     return 0; 
}

为什么main()是常规定义为int类型,它在 32 位上分配 memory 中的 4 个字节,如果它通常只返回 0 或 1,而其他类型如short int (2 bytes,32-bit) 甚至char ( 1 字节,32 位)会更节省 memory 吗?

它正在浪费 memory 空间。

注意:这个问题不是给定线程的重复; 它的答案只对应于返回值本身,而不对应于其明确关注的数据类型。

问题是针对 C 和 C++。 如果这些之间的答案发生变化,请分享您的智慧,并提及特别关注哪种语言的上下文。

通常汇编器使用它们的寄存器来返回一个值(例如 Intel 处理器中的寄存器AX )。 int 类型对应于机器字,即不需要将例如char 类型对应的字节转换为机器字。

事实上, main 可以返回任何 integer 值。

这是因为一台有半个世纪历史的机器。

早在创建 C 的那一天, int是 PDP-11 上的机器字 - 16 位 - 拥有main返回是自然而有效的。

“机器字”是 B 语言中唯一的类型,它是 Ritchie 和 Thompson 较早开发的,并且是从 C 发展而来的。
当 C 添加类型时,不指定一个给你一个机器字 - 一个int
(当时节省空间非常重要,所以不需要拼出最常见的类型是一件非常好的事情。)

因此,由于 B 程序以

main()

程序员通常是语言保守的,C 做了同样的事情并返回了一个int

我不认为这是浪费的原因有两个:

1 4字节退出码的实际使用

如果要返回一个准确描述错误的退出代码,则需要超过 8 位。

例如,您可能希望对错误进行分组:第一个字节可以描述模糊的错误类型,第二个字节可以描述导致错误的 function,第三个字节可以提供有关错误原因的信息,第四个字节描述额外的调试信息。

2 填充

如果您传递单个short 或 char,它们仍将对齐以适合机器字,这通常是 4 字节/32 位,具体取决于架构。 这称为填充,意味着您很可能仍需要 32 位 memory 来返回单个短字符或字符。

大多数 shell 的老式约定是使用int的最低有效 8 位,而不仅仅是 0 或 1。16 位越来越普遍,因为这是标准允许的int的最小大小。

浪费空间会有什么问题? 空间真的浪费了吗? 您的计算机是否充满了“东西”,以至于剩余的sizeof(int) * CHAR_BIT - 8会有所作为? 该架构能否利用这一点并将剩余的部分用于其他用途? 我非常怀疑。

所以我不会说 memory 完全被浪费了,因为你在程序完成时从操作系统中取回它。 也许奢侈 有点像用一个大酒杯喝一小杯酒?

第一: if it usually returns only 0 or 1单独你的假设/陈述是错误的。

通常,如果没有发生错误,则返回代码应为0 ,否则它可以返回任何数字来表示不同的错误。 大多数(至少命令行程序)都这样做。 许多程序还 output 负数。

However there are a few common used codes https://www.tldp.org/LDP/abs/html/exitcodes.html also here another SO member points to a unix header that contains some codes https://stackoverflow.com/a /24121322/2331592

因此,毕竟它不仅仅是CC++类型的东西,而且还有大多数操作系统如何工作并期望程序运行的历史原因,因为语言必须支持这一点,所以至少C使用 an12F80B84D1 之类的语言这样做int main(...)

第二:你的结论It is wasting memory space是错误的。

  1. 与较短的类型相比,使用int不会造成任何浪费。 无论如何,Memory 通常以字长处理(这意味着可能取决于您的架构)
  2. 使用子字类型涉及某些架构上的计算开销(读取:加载,字,屏蔽无关位;存储:加载 memory,屏蔽变量位,或者使用新值,写回字)
  3. 除非您使用它,否则不会浪费 memory。 如果你写return 0; 此时从未使用过 memory。 如果您return myMemorySaving8bitVar; 您只使用了 1 个字节(最有可能在堆栈上(如果根本没有优化))

答案是“因为它通常不会返回 0 或 1”。 我从软件工程社区找到了这个帖子,它至少部分回答了你的问题。 以下是两个亮点,首先来自已接受的答案:

integer 为报告错误提供了比一个字节更多的空间。 它可以被枚举(返回 1 表示 XYZ,返回 2 表示 ABC,返回 3,表示 DEF 等)或用作标志( 0x0001表示失败, 0x0002表示失败, 0x0003表示失败和失败)。 将其限制为仅一个字节很容易用完标志(只有 8 个),因此决定可能是使用 integer。

Keith Thompson还提出了一个有趣的观点:

例如,在Plan 9操作系统中使用的 C 的方言中, main通常声明为void function,但是通过将字符串指针传递给exits() ZC1C425268E68A47,将退出状态返回给调用环境。 空字符串表示成功,任何非空字符串表示某种失败。 可以通过让main返回一个char*结果来实现。

这是来自unix.com 论坛的另一个有趣的部分:

(以下一些可能是 x86 特定的。)

回到原来的问题:退出状态存储在哪里? kernel 内部。

当您调用 exit(n) 时,integer n 的最低有效 8 位被写入 cpu 寄存器。 然后 kernel 系统调用实现会将其复制到与流程相关的数据结构中。

如果你的代码没有调用exit()怎么办? 负责调用 main() 的 c 运行时库将代表您调用 exit() (或其一些变体)。 main() 的返回值在寄存器中传递给 c 运行时,用作 exit() 调用的参数。

与最后一个报价相关,这是来自cppreference.com的另一个报价

5) 执行返回(或到达 main 结束时的隐式返回)等价于先正常离开 function(这会破坏具有自动存储持续时间的对象),然后使用与参数相同的参数调用 std::exit的回报。 (std::exit 然后销毁 static 对象并终止程序)

最后,我在这里找到了这个非常酷的示例(尽管帖子的作者说返回的结果是返回值模 512 是错误的)。 编译并执行以下命令后:

int main() {
    return 42001;
}

符合 POSIX 的 my* 系统上, echo $? 返回 17。那是因为42001 % 256 == 17这表明实际使用了 8 位数据。 考虑到这一点,选择int可确保有足够的存储空间可用于传递程序的退出状态信息,因为根据此答案,符合 C++ 标准可确保int的大小(以位为单位)

不能小于8。这是因为它必须足够大以容纳“Unicode UTF-8编码形式的八位代码单元”。

编辑:

*正如Andrew Henle在评论中指出的那样:

完全符合 POSIX 的系统使整个int返回值可用,而不仅仅是 8 位。 请参阅pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html :“如果si_code等于CLD_EXITED ,则si_status保存进程的退出值;否则,它等于导致进程更改 state. si_status中的退出值应等于完整退出值(即传递给_exit()_Exit()exit()的值,或从main()返回的值);不受限制到该值的最低有效八位。”

我认为这为使用int而不是较小大小的数据类型提供了更强有力的论据。

您正在工作或学习 C,所以我认为您关心效率是一个真正的好主意。 但是,这里似乎有几件事需要澄清。

首先, int 数据类型并不是“32 位”的意思。 这个想法是 int 将是目标机器上最自然的二进制 integer 类型——通常是寄存器的大小。

其次,来自 main() 的返回值旨在适应不同操作系统上的各种实现。 POSIX 系统使用无符号的 8 位返回码。 Windows 使用由 CMD shell 解释为 2 的补码符号的 32 位。 另一个操作系统可能会选择其他东西。

最后,如果您担心 memory “浪费”,那么在这种情况下,这是一个实现问题,甚至不是问题。 来自 main 的返回码通常在机器寄存器中返回,而不是在 memory 中,因此不涉及成本或节省。 即使有,在运行一个重要程序时节省 2 个字节也不值得任何开发人员的时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM