读《C++ Primer》之返回值与缓冲区

C++ Primer

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 对象,那么为什么要重复定义两个对象呢?

Leave a comment

Your comment