读《C++ Primer》之返回值与缓冲区
工作以来,我用过不少的编程语言,它们分别用在不同的技术场景中,比如用在企业应用中后台逻辑的 Java,用于数据库存储过程的 PL/SQL。但一直遗憾的是,没有工作机会采用 C/C++。日子一久,在学校里积攒的那点儿三脚猫 C++ 功夫就荒废了。这些系统级编程语言使用经验的缺失,使得我在理解底层问题时感到非常困难。自2013年初以来,我在空闲时间通过重新阅读《C++ Primer》一书,弥补遗忘的 C++ 知识,希望能够补上这个短板。本篇博客即是我在阅读时的思考,既做为自己的读书笔记,也供其他人参考和批判。
关于 main 的返回值
在 Unix 系统中,通过echo $?
,获取 main 函数的返回值。习题1.2,在 main
函数中,返回-1。通过上述方法查看,发现结果是255。这是为什么?
int main() { return -1; } |
从 Wikipedia 的 Exti Status词条,可以看到如下说明:
SUS specifies that the low-order 8 bits of the status value contain the exit status;[4] this can be retrieved using the WEXITSTATUS macro in wait.h.[5] As such, on POSIX-compatible exit statuses are restricted to values 0-255, the range of an unsigned 8-bit integer.
也就是说,当return -1
时,-1不是有效的状态码,将会被转型为无符号的8位整数。
我还无法理解,从在终端输入程序名称并按下回车键的那一刻起,到程序执行完毕随后退出的整个过程中,shell 是如何创建一个进程,进程如何进入执行,-1又是如何被转换为255。
关于缓冲区
buffer(缓冲区)是一段用来存放数据的存储区域。IO 设备常存储输入(输出)到缓冲区,并独立于程序动作对缓冲区进行读写。输出缓冲区通常必须显式刷新以强制输出缓冲区内容。
标准库定义了4个 IO 对象,分别是 cin、cout、cerr、clog。cerr 是绑定到标准错误的 ostream 对象,通常是与标准输出相同的流。默认情况下,输出 cerr 不缓冲,用于输出警告和错误信息。cout 用于写入到标准输出的 ostream 对象,一般情况下用于程序输出。默认情况下,读 cin 会刷新 cout;当程序正常结束时,cout 也被刷新。
clog 是绑定到标准错误的 ostream 对象,默认情况下是带缓冲的,用于产生程序执行的一般信息。但是,经程序测试,Linux/Mac OS X 上均没有缓冲。
#include <iostream> int main() { std::clog << "clog without EOL"; std::clog << "clog with EOL" << std::endl; std::clog << "clog without EOL"; while(1) { ; } return 0; } |
上段程序先是输出一段文字,但没有输出换行,接着输出一段文字并换行,然后再输出文字,并不加换行,最后程序一直在死循环里,没有推出。执行后可以看到输出如下:
clog without EOLclog with EOL
clog without EOL
这和上文的说明是矛盾的,文字全部输出,证明了 clog 没有缓存。这是怎么回事?
同时,上文提到,cerr 和 clog 同是绑定到标准错误的 ostream 对象,那么为什么要重复定义两个对象呢?