ボンジュール・マドモアゼル

本サイトの情報は自己責任にてご利用下さい。

[C++再考] 実行結果が異なるぞ

 
C++再考 [新装版] 第29章 アプリケータ、マニピュレータ、関数オブジェクト
P388
cout << to_hex(n) << " " << to_hex(m);
の文について
コンパイラはto_hex(n)を評価し、続いてto_hex(m) を評価するでしょう。
しかし、実際に実行してみたら、to_hex(m) が先に評価されている。(コンパイラはgcc version 3.4.4)

その理由は、次回に記す。

[C++再考] 配列の要素の次のアドレス

 
C++再考 [新装版] 第20章 反復子アダプタ
P270
CやC++では配列の要素の次のアドレスをつくることができるからです。つまり、a+10 は違法ではないのです。しかし、 a+11は違法です。また、a-1も違法なのです。

※int a[10]; とした場合
確認するため、「プログラミング言語C 第2版(訳書訂正版)ANSI規格準拠」を参照する。

A7.7 加法演算子
(中略)和が配列の限界の外を指すときには、終端の一つ先の最初の場所を除いて、結果は不定となる。

A7.9 関係演算子
演算子<(より小さい),>(より大きい),<=(小さいか等しい)>=(大きいか等しい)
(中略)一方、ポインタが配列の最後のメンバーを参照するときには、その比較は対応する添字の比較と同じである。Pが配列の最後のメンバーを指すときには、P+1がたとえ配列の外側を指すものであっても、P+1はPより高くなる。以上のいずれでもない場合には、ポインタの比較は定義されない。

付録A 参照マニュアルより



[C++再考] C++再考:誤植

 
C++再考 [新装版] 第2刷

誤植一覧(随時更新予定)

P78
UseCount::UseCount() : p(new int(1)) { {}


Handle::Handle() : p(new Point) { }

Handle::Handle(int x, int y) : p(new Point(x, y)) { }
Handle::Handle(const Point& p0) : p(new Point(p0)) { }
Handle::Handle(const Handle& h) : u(h.u),p(h.p) { }


P84
#include <iostream.h>


P87
class Binary_node: public Expr_node {

friend class Expr;

Ssting op;
Expr_node* left;
Expr_node* right;

UnaryBinary_node(const String& a,
Expr_node* b, Expr_node* c):


P89
Expr::Expr(const String& op, Expr left, ExprrightExpr right)


P88
friend ostream& operator<<(ostream&, const Expr&);


P122
P_Node::P_nodeP_Node(): use(1) { }

P127
int void Picture::display(ostream& o, int x, int y)

P127
ostream& operator<<(ostream& os, const Picture& picture)

{
int ht = picture.height();
for(int i = 0; i < ht; i++) {
picture.display(os, i, 0);
os << endl;
}
return os;
}

P133
void VCat_Pic::display(ostream& os, int row, int wd) const

{
if(row >= 0 && row < top.height())
top.display(os, row, wd);
else if(row < top.height + bottom.height())
bottom.display(os, row - top.height(), wd);
else
pad(os, 0, wd);
}

[C++再考] C++再考:1

 
C++再考 [新装版] 第4章 クラス製作者のためのチェックリスト P48〜P49

下記、本文が意味不明。

配列を delete する際に、delete [] と書きますが、この [] はCとC++の互
換性をよくするために生まれたものです。Cのプログラムはメモリを確保するの
にCの malloc を使い、これがC++の関数にそのメモリを渡す、というよう
なプログラムを書くかもしれません。この場合、C++の関数がそのメモリを開放
すると期待しているのです。もし、ここでC++プログラマがCの malloc を含
むコードを書き換えたくなければ、new を malloc を使って上書きする必要があり
ます。そのため、C++の組み込みの delete は、配列を開放するときに、その大き
さを知らずにやるように作られたのです。それは malloc を使うときに、確保され
るメモリのサイズは決められますが、そのサイズをいつもC++のライブラリが都
合良く見つけられるようには作れないからです。メモリサイズはCライブラリがプライベートな変数で管理しているため妥協として、C++は、delete の
際に、delete されるものが配列かどうかだけ記述するように作られたのです。こ
のような仕組みのために、配列の大きさが記録されオーバーヘッドができますが、
配列が使うメモリは概して大きいので、あまり問題にならないのです。
配列の要素が自明でないデストラクタを持つときだけ [] が有効なわけですが、
配列に対しては常に [] を使うようにしておくのが良いでしょう。
どう解釈しても意味が通らない。
原文からおかしいような感じがする。