| 
 ===============================   
■□ 第21节:特定系统的细节   
===============================   
   
Q125:GNU C++ (g++) 把小程式造出大大的执行档,为什麽?   
   
libg++(g++ 用到的程式库)可能在编译时带有除错的资讯(-g)。有些机器上,不   
带除错资讯地重新编译它,会省下很大的磁碟空间(~1 MB;缺点是:不能追踪到   
libg++ 的呼叫)。仅仅 "strip" 掉执行档,比不上先用 -g 重新编译,再 "strip"   
掉 a.out 档来得有效。   
   
用 "size a.out" 来看看执行码的程式与资料区段到底占了多大空间,而不要用   
"ls -s a.out" 这种包括了符号表格(symbol table)的方式。   
   
========================================   
   
Q126:有 YACC 的 C++ 文法吗?   
   
Jim Roskind 是 C++ 的 YACC 文法作者,它大体上和部份 USL cfront 2.0 所实作   
出来的语言相容(没有 template、例外、执行期型态识别功能)。这份文法有些地   
方和 C++有细小而微妙的差别。   
   
它可用 anonymous ftp 到下列地方取得:   
 * ics.uci.edu (128.195.1.1) in "gnu/c++grammar2.0.tar.Z".   
 * mach1.npac.syr.edu (128.230.7.14) in "pub/C++/c++grammar2.0.tar.Z".   
   
========================================   
   
Q127:什麽是 C++ 1.2?  2.0?  2.1?  3.0?   
   
这些不是“语言”的版本,而是 cfront 这个由 AT&T 做出来的、最早的 C++转译程   
式的版本编号。以这编号来“代表”C++ 语言的演进,已经是公认的惯例了。   
   
“非常”粗略地讲,主要的特徵有:   
 * 2.0 包含多重/虚拟继承,以及纯虚拟函数。   
 * 2.1 包含半巢状 (semi-nested) 类别,及 "delete [] 阵列指标"。   
 * 3.0 包含全巢状 (fully-nested) 类别、template 和 "i++" vs "++i"。   
 * 4.0 将包含例外处理。   
   
========================================   
   
Q128:如果签名编码标准化了,我能否将不同厂商编译器产生的程式码连结起来?   
   
简短的回答:可能不行。   
   
换句话说,有人希望标准化的签名编码规则能并入拟议中的 C++ ANSI 标准,避免还   
要为不同厂商的编译器购买不同版本的物件程式库。然而不同的系统实作中,签名编   
码的差异性只占一小部份而已,即使是在同一个基台(platform)上。这里列出一部   
份其他的差异处:   
   
1) 成员函数隐含的引数个数和型态。   
   1a) ’’this’’ 有被特殊处理吗?   
   1b) 传值的指标放在哪里?   
2) 假设有用到 vtable 虚拟表格的话:   
   2a) 它的内容及配置?   
   2b) 多重继承时,’’this’’ 在何处/如何调整?   
3) 类别如何配置,包含:   
   3a) 基底类别的位置?   
   3b) 虚拟基底类别的处理?   
   3c) 虚拟表格指标的位置,如果有用虚拟表格的话?   
4) 函数的呼叫惯例,包含:   
   4a) 呼叫者还是被呼叫者负责调整堆叠?   
   4b) 实际参数放到哪里?   
   4c) 实际参数传递之顺序?   
   4d) 暂存器如何存放?   
   4e) 传回值放到哪里?   
   4f) 对传入/传回 struct 或 double 有无特殊的规定?   
   4g) 呼叫末端函数(leaf function)有无特殊的暂存器存放规定?   
5) run-time-type-identification 如何配置?   
6) 当一个例外被 throw 时,执行期的例外处理系统如何得知哪一个区域物件该被解   
   构?   
   
   
=======================================   
■□ 第22节:其他的技术和环境的事项   
=======================================   
● 22A:其他的技术事项   
========================   
   
Q129:为什麽有 static 资料成员的物件类别产生了 linker 错误?   
   
Static 的资料成员必须外显地在唯一的模组中定义。   
                     ^^^^^^  ~~~~~~^^^^  ^^^^   
【译注】这句话要逐字细读。原文是:Static data members must be   
        explicitly defined in exactly one module.   
   
譬如:   
        class Fred {   
        public:   
          //...   
        private:   
          static int i_;  // 宣告 static 资料成员 "Fred::i_"   
          //...   
        };   
   
Linker 会告诉你 "Fred::i_ is not defined(未定义)" ,除非你在任何一个(且   
唯一)原始档中定义(而非宣告)了 "Fred::i_" :   
   
        int Fred::i_ = 某个会产生 int 的运算式;   
或是:   
        int Fred::i_;   
   
通常我们会在 "Fred.C" 档中定义 "Fred" 类别的 static 资料成员(或 "Fred.cpp"   
等等你使用的副档名)。   
   
========================================   
   
Q130:"struct" 和 "class" 关键字差别在哪?   
   
struct 的成员和基底类别, 都是预设为 public 的,而 class 则预设为 private。   
注意:你应该“明显地”把基底类别设为 public、private 或是 protected,而不   
要依赖预设值。   
   
除此之外,两者的功能是相等的。   
   
========================================   
   
Q131:为什麽不能以函数的传回值来多载(overload)它?   
   
如果你同时宣告了 "char f()" 及 "float f()" ,编译器会给你个错误讯息,因为   
呼叫 "f()" 会造成模拟两可的情况。   
   
========================================   
   
Q132:什麽是「持续性」?什麽是「持续性物件」?   
   
一个持续性物件 (persistent object),在创造它的程式执行结束後,仍可存活下来   
。它甚至可存活於不同的父程式,存活於磁碟系统、作业系统、甚至於作业系统所处   
的硬体上。   
   
持续性物件的困难在於:如何有效地在次储存体中,存放它们的运作行为(method)   
及资料位元(以及所有成员物件的资料和运作行为,及它们所有的成员物件、基底类   
别……等等)。这一切都得自己来做的话,可不是件容易的事。在 C++中,你就得自   
己来。C++/OO 的资料库系统,会替你把这些机制都隐藏起来。   
   
========================================   
   
Q133:为什麽浮点数 (floating point) 这麽不精确?为什麽这段程式不会印出 0.43?   
   
        #include   
   
        main()   
        {   
          float a = 1000.43;   
          float a = 1000.0;   
          cout << a - b << ’’\n’’;   
        }   
   
(附注,有些 C++ 环境下会印出 0.429993)   
   
声明:受进位/舍位/近似值之苦,其实并不是 C++ 的问题,而是电脑科学界的问   
题。不过还是一直有人在 comp.lang.c++ 里发问,所以我给你一个答案意思一下。   
   
答案:浮点数本来就是个近似值。在 IEEE 的 32 位元浮点数标准里,有 1 位元的   
正负号,8 位元的指数,23 位元的假数。因为正规化後的二进位假数都会变成像是   
1.xxxxx... 的型式,所以头一项的 1 不予计入,就能得到 24 位元的有效假数。   
1000.43(以及其他很多很多数字)都不是 float 或 double 的表示法,其实   
1000.43 的位元内容是这样子的(’’s’’ 代表正负号,’’e’’ 代表指数,’’m’’ 代表假数)   
:   
   
    seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm   
    01000100011110100001101110000101   
   
假数移位後变成 1111101000.01101110000101 或是 1000 + 7045/16384。   
分数部份为 0.429992675781。   
float 的假数占 24 位元,所以你只得到 16M 分之一的精确度。   
double 有较高的精确度(53 位元的假数)。   
   
==========================   
● 22B:其他环境下的琐事   
==========================   
   
Q134:有任何 TeX 或 LaTeX 的巨集,能处理 "C++" 的留白效果(spacing)吗?   
   
有的,底下列出两个:   
   
\def\CC{C\raise.22ex\hbox{{\footnotesize +}}\raise.22ex\hbox{\footnotesize +}}   
   
\def\CC{{C\hspace{-.05em}\raisebox{.4ex}{\tiny\bf ++}}}   
   
========================================   
   
Q135:在哪儿可拿到 C++2LaTeX 这个 C++原始码的 LaTeX 美编工具(pretty   
      printer)?   
   
这儿列出一些 ftp 地点:   
   
Host aix370.rrz.uni-koeln.de   (134.95.80.1) Last updated 15:41 26 Apr 1991   
    Location: /tex   
      FILE      rw-rw-r--     59855  May  5  1990   C++2LaTeX-1.1.tar.Z   
Host utsun.s.u-tokyo.ac.jp   (133.11.11.11) Last updated 05:06 20 Apr 1991   
    Location: /TeX/macros   
      FILE      rw-r--r--     59855  Mar  4 08:16   C++2LaTeX-1.1.tar.Z   
Host nuri.inria.fr   (128.93.1.26) Last updated 05:23  9 Apr 1991   
    Location: /TeX/tools   
      FILE      rw-rw-r--     59855  Oct 23 16:05   C++2LaTeX-1.1.tar.Z   
Host iamsun.unibe.ch   (130.92.64.10) Last updated 05:06  4 Apr 1991   
    Location: /TeX   
      FILE      rw-r--r--     59855  Apr 25  1990   C++2LaTeX-1.1.tar.Z   
Host iamsun.unibe.ch   (130.92.64.10) Last updated 05:06  4 Apr 1991   
    Location: /TeX   
      FILE      rw-r--r--     51737  Apr 30  1990   
      C++2LaTeX-1.1-PL1.tar.Z   
Host tupac-amaru.informatik.rwth-aachen.de   (192.35.229.9)   
Last updated 05:07 18 Apr 1991   
    Location: /pub/textproc/TeX   
      FILE      rw-r--r--     72957  Oct 25 13:51  C++2LaTeX-1.1-PL4.tar.Z   
Host wuarchive.wustl.edu   (128.252.135.4) Last updated 23:25 30 Apr 1991   
    Location: /packages/tex/tex/192.35.229.9/textproc/TeX   
      FILE      rw-rw-r--     49104  Apr 10  1990   C++2LaTeX-PL2.tar.Z   
      FILE      rw-rw-r--     25835  Apr 10  1990   C++2LaTeX.tar.Z   
Host tupac-amaru.informatik.rwth-aachen.de   (192.35.229.9)   
Last updated 05:07 18 Apr 1991   
    Location: /pub/textproc/TeX   
      FILE rw-r--r-- 74015  Mar 22 16:23 C++2LaTeX-1.1-PL5.tar.Z   
    Location: /pub   
      FILE rw-r--r-- 74015  Mar 22 16:23 C++2LaTeX-1.1-PL5.tar.Z   
Host sol.cs.ruu.nl   (131.211.80.5) Last updated 05:10 15 Apr 1991   
    Location: /TEX/TOOLS   
      FILE      rw-r--r--     74015  Apr  4 21:02x   C++2LaTeX-1.1-PL5.tar.Z   
Host tupac-amaru.informatik.rwth-aachen.de (192.35.229.9)   
Last updated 05:07 18 Apr 1991   
    Location: /pub/textproc/TeX   
      FILE      rw-r--r--      4792  Sep 11  1990 C++2LaTeX-1.1-patch#1   
      FILE      rw-r--r--      2385  Sep 11  1990 C++2LaTeX-1.1-patch#2   
      FILE      rw-r--r--      5069  Sep 11  1990 C++2LaTeX-1.1-patch#3   
      FILE      rw-r--r--      1587  Oct 25 13:58 C++2LaTeX-1.1-patch#4   
      FILE      rw-r--r--      8869  Mar 22 16:23 C++2LaTeX-1.1-patch#5   
      FILE      rw-r--r--      1869  Mar 22 16:23 C++2LaTeX.README   
Host rusmv1.rus.uni-stuttgart.de   (129.69.1.12)   
Last updated 05:13 13 Apr 1991   
    Location: /soft/tex/utilities   
      FILE      rw-rw-r--    163840  Jul 16  1990   C++2LaTeX-1.1.tar   
   
========================================   
   
Q136:该到哪里取得 "tgrind" 这个 C++/C/etc 的原始码美编工具?   
   
"tgrind" 读入 C++ 原始档案,并输出能让 Unix 印表机印出美观文件的东西。它常   
会伴随在 TeX 和 LaTeX 的套件里;请找找这个目录:   
 "...tex82/contrib/van/tgrind" 。 由 Jerry Leichter 所做更新的版本,可在   
venus.ycc.yale.edu in [.TGRIND] 里找到。   
   
========================================   
   
Q137:有给 GNU emacs 编辑器用的 C++-mode 吗?有的话,该怎麽拿?   
   
Yes,有一个给 GNU emacs 用的 C++-mode。   
   
最新、最好的 C++-mode(以及 c-mode)版本是 cc-mode.el 档,是 Detlef &   
Clamen 版本的延伸。Emacs 里头有一个了,较新的则在 elisp 里面。   
   
========================================   
   
Q138:我要到哪儿得到和作业系统相关的 FAQs( 譬如:BC++、DOS、Windows 等等   
      )?   
   
请参考:   
 * comp.os.msdos.programmer   
 * comp.windows.ms.programmer   
 * comp.unix.programmer   
   
[如果您有 BC++、VC++ 的 email address,或是 Semantic C++ 的臭□清单或可供   
讨论的 mailing list,请告诉我该如何加入,我会在这儿提出的。]   
   
========================================   
   
Q139:为什麽我的 DOS C++ 程式说 "Sorry: floating point code not linked"   
      “抱歉,浮点运算程式码未连结进来”?   
   
编译器会试著节省执行档的大小,所以除非必要,否则不引入浮点数→字串格式转换   
的副程式,可是有时候它会猜错,就会产生上述的错误讯息了。解决法:(1) 使用   
 而不要用 ,或是 (2) 在您程式的某个地方,置入如下的函   
数(但是不要真的去呼叫它!):   
   
        static void dummyfloat(float *x) { float y; dummyfloat(&y); }   
   
请参考关於 stream I/O 的 FAQ项目,有提到更多使用  vs    
的理由。   
   
========================================   
   
Q140:为什麽当我没执行 BC45 IDE 的话,BC++ 做出来的 Windows 应用程式就不能   
      用?   
   
用 BC++ 写 Windows 应用程式,如果当 BC45 IDE 正在执行时,你的程式很正常;   
待会儿当 BC45 IDE 关掉了,而你的程式却在建立视窗时产生了个 exception 的话   
,就把底下这行程式加到你的应用程式类别 ("YourApp::InitMainWindow()") 里头   
的 InitMainWindow() 内:   
   
        EnableBWCC(TRUE);   
   
【译注】这是因为你用 BC++ 写的应用程式,可能会自动用到 bwcc*.dll,刚好   
        BC++ 的 IDE 也会用到它,所以两者并存的话,BWCC 已先被 IDE 载入了。   
        若是 IDE 未执行,则 BWCC 未被载入,你就得用上面那一行程式来通知   
        OWL 去载入它。  |