I've just completed my customary year-end updates to all my publications'
errata lists. The revised lists are at the usual URLs; you'll find links
to them at http://www.aristeia.com/books.html#errataLinks
As a mailing-list exclusive, below you'll find summaries of the new
entries.
As always, I hope you find the errata useful, and I apologize for their
needing to exist. Sigh.
Scott
NEW ENTRIES FOR EFFECTIVE C++:
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ------- ----------------------------------------------------------
11/13/03 dfc 9, The code for the String class isn't exception safe. When
73 I wrote the book, I frankly wasn't concerned about
exception safety, but I should have been. When I write
the third edition of the book, I'll be careful to pay
attention to exception safety throughout.
12/10/03 sn Item 12 As Item 11 explains, bitwise copy is virtually always
incorrect for pointer data members, but it is often
simpler to "do the right thing" via assignment vis-a-vis
initialization for pointer data members. So it may make
sense to assign to pointer data members instead of
initializing them.
NEW ENTRIES FOR MORE EFFECTIVE C++:
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
12/18/03 sdm Item 31 Nat Goodspeed's article in the January 2004 DDJ, "Double
Dispatch Revisited", contributes an interesting new
approach to implementing support for double dispatch that
also supports inheritance.
NEW ENTRIES FOR EFFECTIVE STL:
DATE DATE
REPORTED WHO PAGES WHAT FIXED
-------- --- ----- ------------------------------------------------ --------
9/17/03 hs 99 The claim in the 3rd prose para that map nodes
could be put in write-only memory is dubious.
Among other things, the value part of the pair
is generally modifiable, and the node almost
certainly has pointers to its children, which
may change over time.
9/17/03 hs 163 In the middle of the page,
DoSomething::operator() should be declared
public.
12/22/03 mc 201 I should make clearer in my discussion of
multimap::find vs. multimap::lower_bound that
only lower_bound is guaranteed to locate the
*first* element with a given key value; find
is guaranteed only to locate *some* element
with the given key value. I may want to make
this clearer in the tables on pg. 200 and the
inside front cover, too.
7/28/03 jp 206 The problem would be in agreement with the
code, and clearer, if it said simply "get rid
of all the elements in the vector whose value
is less than x and that occur after the last
value at least as big as y".
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
11/04/03 sdm 67 According to my most recent tests, the last para on the
page continues to be true, but it's worth noting that
the vector that ships with VC7.1 (Visual C++ .NET 2003)
performs 17 reallocations. Instead of doubling the
capacity each time, it appears to grow at a rate of 1.5
instead.
NEW ENTRIES FOR THE EFFECTIVE C++ CD:
DATE DATE
REPORTED WHO WHAT FIXED
-------- --- ------------------------------------------------------- --------
3/12/02 ga In the final comment preceding P12 of M2 (Item
chunking), "hierarch" ==> "hierarchy".
3/12/02 ga In P2 of M4 (Item chunking), there is an extra space in
"( Item 28)".
Monday, December 29, 2003
Friday, December 26, 2003
Advice for Prospective Book Authors
Recently, I had my nth telephone call explaining the facts of publishing
life to a prospective book author, and it finally convinced me to do
something I've been threatening to do for years: write up some comments on
the topic. 12,000 words and several rounds of feedback from authors and
editors later, you can see the result at
http://www.aristeia.com/authorAdvice.html It's my hope that prospective
authors will find the information interesting and useful, while armchair
authors will at least find it interesting.
Happy New Year :-)
Scott
life to a prospective book author, and it finally convinced me to do
something I've been threatening to do for years: write up some comments on
the topic. 12,000 words and several rounds of feedback from authors and
editors later, you can see the result at
http://www.aristeia.com/authorAdvice.html It's my hope that prospective
authors will find the information interesting and useful, while armchair
authors will at least find it interesting.
Happy New Year :-)
Scott
Thursday, December 18, 2003
Fixing EC++ CD's Display Problems under IE6
In March of last year, I posted a message to this list explaining that my
Effective C++ CD doesn't display properly with version 6 browsers, and I
solicited patches to address the problems. I got a patched set of files
for IE6 from Attila Feher, but to my frustration and disappointment, they
disappeared into the Legal Department at Addsion-Wesley and never came out,
so I was unable to make them publicly available.
Earlier this month, however, I got a note from Ian Roberts explaining what
changes needed to be made to the CD's files, so I took the opportunity to
write a program to perform the edits automatically. This program, CDFix,
is now available at http://www.aristeia.com/BookErrata/CDFix.zip
I'm adopting a "Don't Ask, Don't Tell" policy with respect to AW's Legal
Department: I'm not telling them about the program, and I'm hoping they
don't tell me to stop distributing it :-)
I encourage you to give it a try if you'd like to use the CD with IE6. If
it works, great. If not, you can always delete the edited files and fall
back on the originals on the CD. And if you find ways to improve CDFix,
e.g., to make it also edit the CD's files so that they work better with
other browsers, please let me know.
Scott
Effective C++ CD doesn't display properly with version 6 browsers, and I
solicited patches to address the problems. I got a patched set of files
for IE6 from Attila Feher, but to my frustration and disappointment, they
disappeared into the Legal Department at Addsion-Wesley and never came out,
so I was unable to make them publicly available.
Earlier this month, however, I got a note from Ian Roberts explaining what
changes needed to be made to the CD's files, so I took the opportunity to
write a program to perform the edits automatically. This program, CDFix,
is now available at http://www.aristeia.com/BookErrata/CDFix.zip
I'm adopting a "Don't Ask, Don't Tell" policy with respect to AW's Legal
Department: I'm not telling them about the program, and I'm hoping they
don't tell me to stop distributing it :-)
I encourage you to give it a try if you'd like to use the CD with IE6. If
it works, great. If not, you can always delete the edited files and fall
back on the originals on the CD. And if you find ways to improve CDFix,
e.g., to make it also edit the CD's files so that they work better with
other browsers, please let me know.
Scott
Monday, December 8, 2003
Upcoming Talks
I've updated my "Upcoming Talks" page with new conference talks in February
and March. In February, I'll be giving a tutorial at the Embedded World
Exhibition & Conference in Nürnberg, Germany. In March, I'll be giving
several talks at the Software Development Conference in Santa Clara,
California. One of those talks (the one on double-checked locking) is
based on new work that Andrei Alexandrescu and I have been doing. For
links to the details on all these talks, consult
http://www.aristeia.com/seminars_frames.html
Also, this is a final reminder that next Monday I'll be giving a full-day
seminar at OGI in Beaverton, Oregon, on making effective use of C++ in
embedded systems. If you're interested in how compilers treat different
language constructs, the ins and outs of avoiding code bloat (especially as
regards templates), how to effectively model memory-mapped IO, or how to
make sure you don't run into trouble by confusing units like miles/hour
with different units like kilometers/second, you might want to consider
attending, because these topics and more are on the docket. You'll find a
link to details on this talk at the same page I mentioned above.
I hope to see you at one or more of these talks. In the meantime,
Happy Holidays :-)
Scott
and March. In February, I'll be giving a tutorial at the Embedded World
Exhibition & Conference in Nürnberg, Germany. In March, I'll be giving
several talks at the Software Development Conference in Santa Clara,
California. One of those talks (the one on double-checked locking) is
based on new work that Andrei Alexandrescu and I have been doing. For
links to the details on all these talks, consult
http://www.aristeia.com/seminars_frames.html
Also, this is a final reminder that next Monday I'll be giving a full-day
seminar at OGI in Beaverton, Oregon, on making effective use of C++ in
embedded systems. If you're interested in how compilers treat different
language constructs, the ins and outs of avoiding code bloat (especially as
regards templates), how to effectively model memory-mapped IO, or how to
make sure you don't run into trouble by confusing units like miles/hour
with different units like kilometers/second, you might want to consider
attending, because these topics and more are on the docket. You'll find a
link to details on this talk at the same page I mentioned above.
I hope to see you at one or more of these talks. In the meantime,
Happy Holidays :-)
Scott
Wednesday, October 22, 2003
Upcoming Seminar on using C++ in an Embedded Environment
During the course of the past year, my most popular C++ seminar has been my
new one on making effective use of C++ in an embedded environment. For
whatever reason, I've offered this as an open-enrollment course several
times in Europe, but never as an open-enrollment course in the USA. Until
now. On Monday, December 15, I'll be presenting this seminar in Beaverton,
Oregon, and if you're working with embedded systems and are interested in
how to use C++ in that environment or how to *better* use C++ in that
environment, I encourage you to consider attending.
For details on the seminar, consult the web page at
http://cpd.ogi.edu/courseSpecific.asp?pam=1399. I hope to see you in
December.
Scott
new one on making effective use of C++ in an embedded environment. For
whatever reason, I've offered this as an open-enrollment course several
times in Europe, but never as an open-enrollment course in the USA. Until
now. On Monday, December 15, I'll be presenting this seminar in Beaverton,
Oregon, and if you're working with embedded systems and are interested in
how to use C++ in that environment or how to *better* use C++ in that
environment, I encourage you to consider attending.
For details on the seminar, consult the web page at
http://cpd.ogi.edu/courseSpecific.asp?pam=1399. I hope to see you in
December.
Scott
Tuesday, October 7, 2003
Updated Book Errata Lists
EC++ and MEC++ are up for new printings (the 15th and 17th, respectively,
on the off chance you care), so I took the opportunity to update the errata
lists for both them and ESTL. You'll find the updated errata lists at the
usual locations:
EC++: http://www.aristeia.com/BookErrata/ec++2e-errata_frames.html
MEC++: http://www.aristeia.com/BookErrata/mec++-errata_frames.html
ESTL: http://www.aristeia.com/BookErrata/estl1e-errata_frames.html
Below I've appended the new entries for each list. These are easier to
peruse to see if you care about any of the changes.
I haven't actually made the changes for the new printings yet, but when I
do, I'll update the EC++ and MEC++ errata lists to show the fix dates for
the changes that will appear in the next printings. That should be done by
next week, so check in with the errata lists then if you're interested in
how the new printings will differ from the current ones.
Scott
PS - Interested in a glimpse at new functionality being added to C++'s
standard library? Check out
http://std.dkuug.dk/jtc1/sc22/wg21/docs/library_technical_report.html
****************************************************
* NEW ENTRIES FOR EFFECTIVE C++ *
****************************************************
Errata:
DATE DATE
REPORTED WHO PAGES WHAT FIXED
-------- --- ----- ------------------------------------------------ --------
9/18/03 ss 99 The function returnStudent is dangerously
declared on this page, because it returns a
reference to what could be a temporary object.
For details, consult FAQ 32.08 of C++ Faqs by
Cline, Lomow, and Girou.
8/13/03 mc 222 There is more to the Singleton pattern than I
describe in this Item. In particular, I make no
mention of how to limit instantiation of a
singleton class to one. The technique is
clearly related to Singleton, but as mc notes,
"You can't spell 'singleton' without spelling
'single.'"
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
6/17/03 wk 77 There are pathological cases where pass by value is
accomplished by instantiations of "copying constructors"
rather than by the class' copy constructor. For details,
consult the
href="http://groups.google.com/groups?hl=en&lr=lang_en|lang_de&ie=UTF-8&oe=UTF-8\
&threadm=3eba7ee4%40news.microsoft.com&rnum=1&prev=/groups%3Fsourceid%3Dnavclien\
t%26ie%3DUTF-8%26oe%3DUTF-8%26q%3DI%2Bfound%2Bevidence%2Bto%2Byour%2Beducated%2B\
guess%2Bmostly%2Bin%2B12.8%252F8%2B(recursive"
target="_top">comp.lang.c++.moderated thread on the topic.
7/ 1/03 sv 108 The last sentence says you *must* use overloading, but if
you are willing to change the API, you have other choices,
e.g., you could pass a vector of values.
5/19/03 sdm Item 34 Because it's not possible to declare nested classes
without defining the class in which they are nested,
nested classes can lead to unnecessary compilation
dependencies. An alternative design is to unnest the
class and include both classes in the same namespace.
However, this is viable only when the nested class is
public, because namespaces offer no encapsulation.
6/11/03 sf Item 38 A drawback to the advice in this Item is that callers
going through the derived class interface must specify
all parameter values; the default parameter values
apply only via the base class interface. An
alternative design is to respecify the (same) default
value in each derived class, but then if the default is
changed in the base class, all derived classes must be
updated with the new value, too.
8/13/03 mc Item 43 Slightly edited, mc writes: "You are not completely
fair in this Item. The trick with auxillary classes is
needed in order to allow overloading of any
functionalities involved in the name clash, but the
clumsiness and the lack of virtual behavior are not
valid arguments. Explicit qualification is clumsy, but
so is explicit upcasting of pointers (it takes more
than one line, compare upper page 196 with middle page
197). So clumsiness is not the argument here. Moreover,
calling pls->draw(); on page 197 would still be an
error just as on page 196, so don't bad-mouth the first
approach on that account. Reversely, applying the
pointer upcast trick on page 196 instead would conserve
the virtual behavior. So the only argument left is that
only one of the methods can be overloaded, the other
will be lost (this is reason enough to apply the
technique you offer). In the end, there's no error in
your text, but I think that the code and the
formulation makes the reader focus on the wrong aspects
of the problem."
****************************************************
* NEW ENTRIES FOR MORE EFFECTIVE C++ *
****************************************************
Errata:
DATE DATE
REPORTED WHO PAGES WHAT FIXED
-------- --- ----- ------------------------------------------------ --------
! 4/30/03 mh 209 RCIPtr::init should test oldValue against NULL
before dereferencing it.
6/ 8/03 sdm 265 Bad line break: AbstractA-nimal ==> Abstract-
Animal
! 6/ 7/03 mh 266 2nd and 3rd paras discuss the assumption that
base classes have no data. The correct assumption
is that *derived* classes have no data.
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
6/ 3/03 sxb 202 The bug for these pages reported by ct on 9/16/98 is
206 incorrect, because when RCPTR::operator= is called with
a raw pointer as an argument (e.g., p->next), a
temporary RCPtr will be created from the raw pointer,
hence the reference count won't go to 0 when
removeReference is called. (I'll keep the code in the
book as is, because it behaves correctly, and I don't
want to mess with code in the book any more often than
I have to.)
****************************************************
* NEW ENTRIES FOR EFFECTIVE STL *
****************************************************
Errata:
DATE DATE
REPORTED WHO PAGES WHAT FIXED
-------- --- ----- ------------------------------------------------ --------
8/ 1/03 lfr 51 In 2nd-to-last para, "unsigned integral value"
==> "unsigned integral type"
5/19/03 drm 168 My claim that "Declaring operator() const in
predicate classes is necessary for correct
behavior, but it's not sufficient" is too strong.
E.g., it would be safe to modify data members that
don't affect the outcome of the predicate. Reword.
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
9/30/03 mp 188 In the operator() implementation at the top of the page, it
might be preferable to write the test this way,
return lowVal < val && val < highVal;
so that val is both numerically and *physically* between
the bottom of the range on the left and the top of the
range on the right. mp finds this clearer and also nearer
to the mathematical notation "lowVal < val < highVal." (mp
attributes this idea to either Steve Maguire's "Writing
Solid Code" or "Debugging the Development Process."
5/16/03 drm Item 26 "The advice of this Item seems kind of strong. Counting
in my last bit of code: 49 const_iterators, 3 iterators, 0
problems (so far). I think a better slant to the Item
might be: be careful, const_iterators have certain
restrictions. I don't see that those restrictions
necessarily lead to the recommendation to prefer iterator."
on the off chance you care), so I took the opportunity to update the errata
lists for both them and ESTL. You'll find the updated errata lists at the
usual locations:
EC++: http://www.aristeia.com/BookErrata/ec++2e-errata_frames.html
MEC++: http://www.aristeia.com/BookErrata/mec++-errata_frames.html
ESTL: http://www.aristeia.com/BookErrata/estl1e-errata_frames.html
Below I've appended the new entries for each list. These are easier to
peruse to see if you care about any of the changes.
I haven't actually made the changes for the new printings yet, but when I
do, I'll update the EC++ and MEC++ errata lists to show the fix dates for
the changes that will appear in the next printings. That should be done by
next week, so check in with the errata lists then if you're interested in
how the new printings will differ from the current ones.
Scott
PS - Interested in a glimpse at new functionality being added to C++'s
standard library? Check out
http://std.dkuug.dk/jtc1/sc22/wg21/docs/library_technical_report.html
****************************************************
* NEW ENTRIES FOR EFFECTIVE C++ *
****************************************************
Errata:
DATE DATE
REPORTED WHO PAGES WHAT FIXED
-------- --- ----- ------------------------------------------------ --------
9/18/03 ss 99 The function returnStudent is dangerously
declared on this page, because it returns a
reference to what could be a temporary object.
For details, consult FAQ 32.08 of C++ Faqs by
Cline, Lomow, and Girou.
8/13/03 mc 222 There is more to the Singleton pattern than I
describe in this Item. In particular, I make no
mention of how to limit instantiation of a
singleton class to one. The technique is
clearly related to Singleton, but as mc notes,
"You can't spell 'singleton' without spelling
'single.'"
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
6/17/03 wk 77 There are pathological cases where pass by value is
accomplished by instantiations of "copying constructors"
rather than by the class' copy constructor. For details,
consult the
href="http://groups.google.com/groups?hl=en&lr=lang_en|lang_de&ie=UTF-8&oe=UTF-8\
&threadm=3eba7ee4%40news.microsoft.com&rnum=1&prev=/groups%3Fsourceid%3Dnavclien\
t%26ie%3DUTF-8%26oe%3DUTF-8%26q%3DI%2Bfound%2Bevidence%2Bto%2Byour%2Beducated%2B\
guess%2Bmostly%2Bin%2B12.8%252F8%2B(recursive"
target="_top">comp.lang.c++.moderated thread on the topic.
7/ 1/03 sv 108 The last sentence says you *must* use overloading, but if
you are willing to change the API, you have other choices,
e.g., you could pass a vector of values.
5/19/03 sdm Item 34 Because it's not possible to declare nested classes
without defining the class in which they are nested,
nested classes can lead to unnecessary compilation
dependencies. An alternative design is to unnest the
class and include both classes in the same namespace.
However, this is viable only when the nested class is
public, because namespaces offer no encapsulation.
6/11/03 sf Item 38 A drawback to the advice in this Item is that callers
going through the derived class interface must specify
all parameter values; the default parameter values
apply only via the base class interface. An
alternative design is to respecify the (same) default
value in each derived class, but then if the default is
changed in the base class, all derived classes must be
updated with the new value, too.
8/13/03 mc Item 43 Slightly edited, mc writes: "You are not completely
fair in this Item. The trick with auxillary classes is
needed in order to allow overloading of any
functionalities involved in the name clash, but the
clumsiness and the lack of virtual behavior are not
valid arguments. Explicit qualification is clumsy, but
so is explicit upcasting of pointers (it takes more
than one line, compare upper page 196 with middle page
197). So clumsiness is not the argument here. Moreover,
calling pls->draw(); on page 197 would still be an
error just as on page 196, so don't bad-mouth the first
approach on that account. Reversely, applying the
pointer upcast trick on page 196 instead would conserve
the virtual behavior. So the only argument left is that
only one of the methods can be overloaded, the other
will be lost (this is reason enough to apply the
technique you offer). In the end, there's no error in
your text, but I think that the code and the
formulation makes the reader focus on the wrong aspects
of the problem."
****************************************************
* NEW ENTRIES FOR MORE EFFECTIVE C++ *
****************************************************
Errata:
DATE DATE
REPORTED WHO PAGES WHAT FIXED
-------- --- ----- ------------------------------------------------ --------
! 4/30/03 mh 209 RCIPtr
before dereferencing it.
6/ 8/03 sdm 265 Bad line break: AbstractA-nimal ==> Abstract-
Animal
! 6/ 7/03 mh 266 2nd and 3rd paras discuss the assumption that
base classes have no data. The correct assumption
is that *derived* classes have no data.
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
6/ 3/03 sxb 202 The bug for these pages reported by ct on 9/16/98 is
206 incorrect, because when RCPTR::operator= is called with
a raw pointer as an argument (e.g., p->next), a
temporary RCPtr will be created from the raw pointer,
hence the reference count won't go to 0 when
removeReference is called. (I'll keep the code in the
book as is, because it behaves correctly, and I don't
want to mess with code in the book any more often than
I have to.)
****************************************************
* NEW ENTRIES FOR EFFECTIVE STL *
****************************************************
Errata:
DATE DATE
REPORTED WHO PAGES WHAT FIXED
-------- --- ----- ------------------------------------------------ --------
8/ 1/03 lfr 51 In 2nd-to-last para, "unsigned integral value"
==> "unsigned integral type"
5/19/03 drm 168 My claim that "Declaring operator() const in
predicate classes is necessary for correct
behavior, but it's not sufficient" is too strong.
E.g., it would be safe to modify data members that
don't affect the outcome of the predicate. Reword.
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
9/30/03 mp 188 In the operator() implementation at the top of the page, it
might be preferable to write the test this way,
return lowVal < val && val < highVal;
so that val is both numerically and *physically* between
the bottom of the range on the left and the top of the
range on the right. mp finds this clearer and also nearer
to the mathematical notation "lowVal < val < highVal." (mp
attributes this idea to either Steve Maguire's "Writing
Solid Code" or "Debugging the Development Process."
5/16/03 drm Item 26 "The advice of this Item seems kind of strong. Counting
in my last bit of code: 49 const_iterators, 3 iterators, 0
problems (so far). I think a better slant to the Item
might be: be careful, const_iterators have certain
restrictions. I don't see that those restrictions
necessarily lead to the recommendation to prefer iterator."
Upcoming Talk at OGI next Thursday (Oct. 16)
The Oregon IEEE Computer and Communications societies asked me to be their
October speaker, so next Thursday (October 16) I'll be giving a talk on
"The Keyhole Problem" at OGI in Beaverton. You can find all the details at
http://www.ieee-or.org/events/EventDetails.asp?eventid=187 and
http://cpd.ogi.edu/class.asp?n=04-IEEE-1016
I hope to see you at OGI on Thursday evening!
Scott
October speaker, so next Thursday (October 16) I'll be giving a talk on
"The Keyhole Problem" at OGI in Beaverton. You can find all the details at
http://www.ieee-or.org/events/EventDetails.asp?eventid=187 and
http://cpd.ogi.edu/class.asp?n=04-IEEE-1016
I hope to see you at OGI on Thursday evening!
Scott
Thursday, October 2, 2003
"Effective XML" is now out
The second book in my Effective Software Development Series has just come
out, Elliotte Rusty Harold's "Effective XML." Many books have been
published that mimic the format of my "Effective" books, but this is the
first one to come out where I offered advice to the author on how to better
make the book "work." Rusty is an established author, so he knows how to
write, and his knowledge of XML is outstanding. I think you'll find that
"Effective XML" offers exactly what the subtitle promises: "50 Specific
Ways to Improve Your XML."
You can read more about the book at
http://www.awprofessional.com/catalog/product.asp?product_id={8E524FFF-F58B-4C5A\
-BBC8-6E02DC159996}&session_id={0994EFB6-20AC-468B-8C72-2603CCFD9EBF}
Scott
out, Elliotte Rusty Harold's "Effective XML." Many books have been
published that mimic the format of my "Effective" books, but this is the
first one to come out where I offered advice to the author on how to better
make the book "work." Rusty is an established author, so he knows how to
write, and his knowledge of XML is outstanding. I think you'll find that
"Effective XML" offers exactly what the subtitle promises: "50 Specific
Ways to Improve Your XML."
You can read more about the book at
http://www.awprofessional.com/catalog/product.asp?product_id={8E524FFF-F58B-4C5A\
-BBC8-6E02DC159996}&session_id={0994EFB6-20AC-468B-8C72-2603CCFD9EBF}
Scott
Tuesday, July 22, 2003
"The Keyhole Problem" and other books
For over a year now, I've been interested in what I call "keyholes" in
software: gratuitous restrictions on what can been seen or expressed.
Keyholes arise in software written in any language and for any domain; they
exist in both web-based and native applications. As a result, this
research is separate from my work on C++ programming.
I've decided that my next book will be about keyholes. In particular,
about why they are harmful and how programmers can avoid them. I've set up
a web site devoted to the project, "The Keyhole Problem." I'll post
chapter drafts there for people to offer feedback on. In addition,
Artima.com has graciously offered to host a mailing list devoted to
discussion of the book material in particular and keyholes in general.
If you're interested in learning more about this project and/or signing up
for the Keyholes Mailing List, please visit the project's web page,
http://www.aristeia.com/TKP/ There you'll find a draft paper from last
summer that gives a good overview of what I mean by keyholes, and you'll
also find a draft book chapter. If you're interested in reading the
chapter, I suggest you wait a few days, because I plan to post a revised
version of that chapter by the end of the week. (When the revised chapter
is available, I'll post to the Keyholes mailing list, not to this list.)
Speaking of writing books, you may recall that in March, I announced that I
was going to work on a new edition of Effective C++. That's happening,
too. When there's more to say on that front, members of my mailing list
will be the first to know, but for now, I'll just say that that project is
proceeding concurrently with my keyholes research.
Also on the writing front, the next book in my Effective Software
Development Series is nearing publication: Elliotte Rusty Harold's
"Effective XML." It's organized like my "Effective C++," and I think that
Rusty does a great job of applying that format to XML development. The
book is slated for publication in September. When it comes out, I'll let
you know. In the meantime, you can get a flavor for the book at
http://www.ibiblio.org/xml/books/effectivexml/
Scott
software: gratuitous restrictions on what can been seen or expressed.
Keyholes arise in software written in any language and for any domain; they
exist in both web-based and native applications. As a result, this
research is separate from my work on C++ programming.
I've decided that my next book will be about keyholes. In particular,
about why they are harmful and how programmers can avoid them. I've set up
a web site devoted to the project, "The Keyhole Problem." I'll post
chapter drafts there for people to offer feedback on. In addition,
Artima.com has graciously offered to host a mailing list devoted to
discussion of the book material in particular and keyholes in general.
If you're interested in learning more about this project and/or signing up
for the Keyholes Mailing List, please visit the project's web page,
http://www.aristeia.com/TKP/ There you'll find a draft paper from last
summer that gives a good overview of what I mean by keyholes, and you'll
also find a draft book chapter. If you're interested in reading the
chapter, I suggest you wait a few days, because I plan to post a revised
version of that chapter by the end of the week. (When the revised chapter
is available, I'll post to the Keyholes mailing list, not to this list.)
Speaking of writing books, you may recall that in March, I announced that I
was going to work on a new edition of Effective C++. That's happening,
too. When there's more to say on that front, members of my mailing list
will be the first to know, but for now, I'll just say that that project is
proceeding concurrently with my keyholes research.
Also on the writing front, the next book in my Effective Software
Development Series is nearing publication: Elliotte Rusty Harold's
"Effective XML." It's organized like my "Effective C++," and I think that
Rusty does a great job of applying that format to XML development. The
book is slated for publication in September. When it comes out, I'll let
you know. In the meantime, you can get a flavor for the book at
http://www.ibiblio.org/xml/books/effectivexml/
Scott
Saturday, June 7, 2003
First ESDS Book: "Code Reading"
A little over a year ago, I announced that I was working with Addison
Wesley on a new book series, the Effective Software Development Series.
Now I'm pleased to announce that the first book in the series has come out.
It's "Code Reading" by Diomidis Spinellis, and I think it's really good.
(Duh. It wouldn't be in the series if I didn't.)
The subtitle of the book is "The Open Source Perspective," and at one
point, I remarked to Diomidis that the most accurate title for the book
would actually be something like "Everything you need to know about
examining open source software projects."
Fundamentally, the book is about how to go about making enough sense of
unfamiliar software systems so that you can modify or extend them. All of
the examples are from Open Source projects, and the book ships with a CD
containing the full source of everything the book mentions. That's some 7
millions lines of code on the CD.
You can find more information about Code Reading at
http://www.awprofessional.com/catalog/product.asp?product_id={DE5EA6BB-1743-406B\
-A680-D1B335BA7EA2}
I hope you like this opening salvo in the Effective Software Development
Series.
Scott
Wesley on a new book series, the Effective Software Development Series.
Now I'm pleased to announce that the first book in the series has come out.
It's "Code Reading" by Diomidis Spinellis, and I think it's really good.
(Duh. It wouldn't be in the series if I didn't.)
The subtitle of the book is "The Open Source Perspective," and at one
point, I remarked to Diomidis that the most accurate title for the book
would actually be something like "Everything you need to know about
examining open source software projects."
Fundamentally, the book is about how to go about making enough sense of
unfamiliar software systems so that you can modify or extend them. All of
the examples are from Open Source projects, and the book ships with a CD
containing the full source of everything the book mentions. That's some 7
millions lines of code on the CD.
You can find more information about Code Reading at
http://www.awprofessional.com/catalog/product.asp?product_id={DE5EA6BB-1743-406B\
-A680-D1B335BA7EA2}
I hope you like this opening salvo in the Effective Software Development
Series.
Scott
Thursday, May 1, 2003
Talks in Germany September 22-26
I'll be in Germany giving talks on various aspects of C++ during the week of
September 22-26. For details (topics, locations, etc.), please consult my
Seminars page, http://www.aristeia.com/seminars_frames.html. All the talks will
be in English, but during breaks, etc., es ist moeglich, dass ich versuchen
werde, ein Bisschen auf Deutsch zu reden :-)
I hope to see you in Germany in September.
Scott
September 22-26. For details (topics, locations, etc.), please consult my
Seminars page, http://www.aristeia.com/seminars_frames.html. All the talks will
be in English, but during breaks, etc., es ist moeglich, dass ich versuchen
werde, ein Bisschen auf Deutsch zu reden :-)
I hope to see you in Germany in September.
Scott
Friday, April 25, 2003
Updated EC++ Errata; 11/02 CUJ Article now Available
Two things:
- Effective C++ Errata Updated
- My November 2002 CUJ Article is now Online
I just updated the errata list for Effective C++. As always, it's at
http://www.aristeia.com/BookErrata/ec++2e-errata_frames.html A detailed
list of changes (in the usual pseudo-HTML I use internally) is listed
below. In conjunction with the recent updates I made to the errata pages
for ESTL and MEC++, I'm pleased to report that all the problems I know
about in my books are now listed online.
Also, you can now find a PDF copy of my November 2002 CUJ article, "Class
Template, Member Template -- or Both?" at
http://www.aristeia.com/Papers/CUJ_Nov_2002.pdf
Enjoy!
Scott
[New EC++ Errata Entries]
DATE DATE
REPORTED WHO PAGES WHAT FIXED
-------- --- ----- ------------------------------------------------ --------
10/12/02 bj 12 Clarify whether the "ISO/ANSI sanctified version
of C" I refer to in the book is now C99, not C89.
4/10/03 wk 77 The final bullet point on the page is misleading.
C++ imposes constraints on how copy constructors
behave, so rather than writing that a copy
constructor defines what it means to pass by
value, I should say that it defines how an
object is passed by value.
10/20/02 kk 125 In final sentence of 2nd-to-last paragraph,
clarify that callers must use the array form of
delete.
9/26/02 mh 127 It would be better if someFamousAuthor returned
a const String instead of just a String. This
would be consistent with the advice of Item 21.
10/12/02 bj 135 In first para, note that the "C philosophy that
variables should be defined at the beginning of
a block" is for C prior to C99.
! 10/12/02 bj Item 41 The first design problem includes the ability to
create "stacks of stacks of strings," but the
given solution has a private copy constructor,
making it impossible to create a Stack of Stacks.
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
2/17/03 dyx Items "Our programming guidelines now recommend implementing
16-17 assignment operators like this:
T const& T::operator=( T other )
{
swap( other ); // non-throwing operation
return *this;
}
My reply:
This is fine (except for the const return type :-}), as
long as you make clear that this approach may be
needlessly expensive. For example, if all your data
members are of built in types, their assignments can't
throw, so doing swaps instead of assignments just burns
cycles needlessly. For large objects, you're talking
about duplicating an object's contents on the heap in
order to be able to perform the non-throwing swap.
There's nothing wrong with that, but my experience has
been that people advocating this approach to implementing
operator= often overlook the cost that it incurs. It's
exception safe, but it's often not cheap.
12/30/02 ma Item 19 It's true that virtual functions must be members, but one
can get virtual-acting behavior by having a non-virtual
function (possibly a non-member) call a virtual function.
This can be especially useful for functions like operator<<,
which must be non-members but can be made to act virtual by
internally calling a virtual function, e.g., one named
"print" or "write".
2/17/03 dys Item 19 Regarding the last bullet on page 88, dys writes:
The same rule should be used for other operators that
require a different class as a left-hand operand. For
example, CORBA uses "Any <<= Type", and for all classes
besides Any, operator<<=(T) is a non-member. I propose
the following change to your algorithm. Instead of
else if (f is operator>> or operator<<)
write
else if (f is an operator and needs another class as
its left-hand operand)
6/15/02 sdm Item 33 Randy Meyers (no relation) has a nice article on inlining
in C99, including an explanation of how the C99 rules differ
from those in C++, in the July 2002 issue of the
C/C++
Users Journal.
10/13/02 ya Item 36 ya writes: "Nonvirtual functions may call other functions
which are virtual. In that case, derived classes are indeed
presented with mandadory implementation, but only in the
highest, close-to-the-surface level. By overriding virtual
functions, the overall behavior of the nonvirtual function
can change in derived classes. Such usage of nonvirtuals is
very useful and is the basis for the 'template method'
design pattern."
This is true, but it's important to note that the
externally observable behavior of any function is defined by
its specification (i.e., it's interface), not by its
implementation. A nonvirtual implemented using template
method may behave differently for different derived classes,
but its behavior is still bounded by its specification.
Callers don't care whether the function is virtual or
nonvirtual. All they care about is that the function they
call exhibits the behavior its specification promises.
For implementers of derived classes, it's a different
story. They care very much about whether a base class
function is virtual or nonvirtual, because that affects what
they are allowed to vary. In Item 36, my remarks are
focused on the relationship between authors of base and
derived classes, not on the relationship between authors of
a class and clients of that class.
- Effective C++ Errata Updated
- My November 2002 CUJ Article is now Online
I just updated the errata list for Effective C++. As always, it's at
http://www.aristeia.com/BookErrata/ec++2e-errata_frames.html A detailed
list of changes (in the usual pseudo-HTML I use internally) is listed
below. In conjunction with the recent updates I made to the errata pages
for ESTL and MEC++, I'm pleased to report that all the problems I know
about in my books are now listed online.
Also, you can now find a PDF copy of my November 2002 CUJ article, "Class
Template, Member Template -- or Both?" at
http://www.aristeia.com/Papers/CUJ_Nov_2002.pdf
Enjoy!
Scott
[New EC++ Errata Entries]
DATE DATE
REPORTED WHO PAGES WHAT FIXED
-------- --- ----- ------------------------------------------------ --------
10/12/02 bj 12 Clarify whether the "ISO/ANSI sanctified version
of C" I refer to in the book is now C99, not C89.
4/10/03 wk 77 The final bullet point on the page is misleading.
C++ imposes constraints on how copy constructors
behave, so rather than writing that a copy
constructor defines what it means to pass by
value, I should say that it defines how an
object is passed by value.
10/20/02 kk 125 In final sentence of 2nd-to-last paragraph,
clarify that callers must use the array form of
delete.
9/26/02 mh 127 It would be better if someFamousAuthor returned
a const String instead of just a String. This
would be consistent with the advice of Item 21.
10/12/02 bj 135 In first para, note that the "C philosophy that
variables should be defined at the beginning of
a block" is for C prior to C99.
! 10/12/02 bj Item 41 The first design problem includes the ability to
create "stacks of stacks of strings," but the
given solution has a private copy constructor,
making it impossible to create a Stack of Stacks.
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
2/17/03 dyx Items "Our programming guidelines now recommend implementing
16-17 assignment operators like this:
T const& T::operator=( T other )
{
swap( other ); // non-throwing operation
return *this;
}
My reply:
This is fine (except for the const return type :-}), as
long as you make clear that this approach may be
needlessly expensive. For example, if all your data
members are of built in types, their assignments can't
throw, so doing swaps instead of assignments just burns
cycles needlessly. For large objects, you're talking
about duplicating an object's contents on the heap in
order to be able to perform the non-throwing swap.
There's nothing wrong with that, but my experience has
been that people advocating this approach to implementing
operator= often overlook the cost that it incurs. It's
exception safe, but it's often not cheap.
12/30/02 ma Item 19 It's true that virtual functions must be members, but one
can get virtual-acting behavior by having a non-virtual
function (possibly a non-member) call a virtual function.
This can be especially useful for functions like operator<<,
which must be non-members but can be made to act virtual by
internally calling a virtual function, e.g., one named
"print" or "write".
2/17/03 dys Item 19 Regarding the last bullet on page 88, dys writes:
The same rule should be used for other operators that
require a different class as a left-hand operand. For
example, CORBA uses "Any <<= Type", and for all classes
besides Any, operator<<=(T) is a non-member. I propose
the following change to your algorithm. Instead of
else if (f is operator>> or operator<<)
write
else if (f is an operator and needs another class as
its left-hand operand)
6/15/02 sdm Item 33 Randy Meyers (no relation) has a nice article on inlining
in C99, including an explanation of how the C99 rules differ
from those in C++, in the July 2002 issue of the
C/C++
Users Journal.
10/13/02 ya Item 36 ya writes: "Nonvirtual functions may call other functions
which are virtual. In that case, derived classes are indeed
presented with mandadory implementation, but only in the
highest, close-to-the-surface level. By overriding virtual
functions, the overall behavior of the nonvirtual function
can change in derived classes. Such usage of nonvirtuals is
very useful and is the basis for the 'template method'
design pattern."
This is true, but it's important to note that the
externally observable behavior of any function is defined by
its specification (i.e., it's interface), not by its
implementation. A nonvirtual implemented using template
method may behave differently for different derived classes,
but its behavior is still bounded by its specification.
Callers don't care whether the function is virtual or
nonvirtual. All they care about is that the function they
call exhibits the behavior its specification promises.
For implementers of derived classes, it's a different
story. They care very much about whether a base class
function is virtual or nonvirtual, because that affects what
they are allowed to vary. In Item 36, my remarks are
focused on the relationship between authors of base and
derived classes, not on the relationship between authors of
a class and clients of that class.
Saturday, April 19, 2003
ESTL and MEC++ Errata Pages Updated
I just updated the errata pages for Effective STL (ESTL) and for More
Effective C++ (MEC++). Here are links:
ESTL: http://www.aristeia.com/BookErrata/estl1e-errata.html
MEC++: http://www.aristeia.com/BookErrata/mec++-errata_frames.html
New entries for both books are below.
I hope to update the errata page for Effective C++ by the end of this
month. I'll let you know when I do.
Scott
----------------------------------------------------------------------
NEW ENTRIES FOR ESTL
----------------------------------------------------------------------
Bugs:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- ------------------------------------------------
2/ 1/03 fr 90 Missing colon at end of page. (The missing colon is
actually deliberate, but replacing "try" with "try
this:" will probably be clearer, so that's the change
I'll make.)
1/31/03 fr 91 Include an xref to Item 7 near the definition for
DereferenceLess for readers who are confused about
why DereferenceLess is a non-template struct
containing a templatized operator().
4/18/03 lz 157 In 1st line, "many elements" ==> "many elements
with a particular value"
2/26/03 shh 166 In the third bullet point on the page, "returns
true or false" ==> "returns true or false (or
something that can be implicitly converted to
true or false)."
2/26/03 shh 211 In line 5 of 4th prose para, "do this is with"
==> "do this with"
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
7/16/01 sdm Item 4 If you're interested in the technical and standardization
issues surrounding list::size, check out the July 2001
href="http://groups.google.com/groups?hl=en&lr=lang_en|lang_de&ie=UTF-8&oe=UTF-8\
&threadm=uZj47.33018%24WS4.5267300%40news6-win.server.ntlworld.com&rnum=1&prev=/\
groups%3Fhl%3Den%26lr%3Dlang_en%257Clang_de%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3Du\
Zj47.33018%2524WS4.5267300%2540news6-win.server.ntlworld.com"
target="_blank">comp.std.c++
thread discussing the matter.
12/ 2/02 jr 46 The code at the bottom of this page has two shortcomings:
(1) though it works when iterating over an entire container,
it's incorrect if given an arbitrary end iterator, because
the call to erase will invalidate the end iterator; and (2)
because each call to erase shifts all succeeding elements
down by one, the linear-looking loop really runs in
quadratic time.
Here's code that addresses both problems, where endIt is the
arbitrary end iterator to be used and, for consistency,
beginIt is an arbitrary begin iterator to be used:
vector::iterator i = beginIt;
while(i!=endIt && !badValue(*i)) ++i;
vector::iterator j = i;
while(i!=end){
if(badValue(*i)) {
logFile<<"Erasing "<<*i<<'\n';
} else {
*j=*i;
++j;
}
++i;
}
c.erase(j, end);
Note that the second while loop is essentially a variant of
remove_if (see Item 32).
jr reports that in simple tests he performed comparing the
performance of this code with that on the bottom of page 46,
he saw speed improvements of 2-3 orders of magnitude.
2/22/03 fr Item 34 When using an algorithm expecting a sorted range (e.g.,
includes, set_union, etc.) on a standard associative
container (especially a map or multimap), it's important to
pass the correct comparison function. The easiest way to do
this is to pass the result of the value_comp member
function:
typedef multimap map1, map2;
...
bool subMultiset = includes(map1.begin(), map1.end(),
map2.begin(), map2.end(),
map1.value_comp());
This works for sets and multisets, too, because for those
types, value_comp returns the same thing as key_comp.
However, as noted in Item 44, for operations like
lower_bound, etc., it's generally better to use member
functions instead of algorithms when both are applicable.
2/20/03 fr 156 Because postincrement is less efficient than
preincrement, the if statement may be better
implemented as follows:
if (p(*begin)) {
*destBegin = *begin;
++destBegin;
}
2/26/03 shh 159 In order to make sure that the initial summary value
passed to accumulate is of the appropriate type, shh
suggests using this form:
Y sum = accumulate (
begin, // acts like a T*
end, // acts like a T*
static_cast(initValue) // initValue need not be of type
Y
);
----------------------------------------------------------------------
NEW ENTRIES FOR MEC++
----------------------------------------------------------------------
Bugs:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- ------------------------------------------------
8/14/02 sdm 66-67 The inheritance-based conversions described on
these pages apply only to public inheritance.
For non-public inheritance, things get a bit more
complicated. For details, including a rationale
for the behavior, consult the July 2001 CUJ
column by Jim Hyslop and Herb Sutter,
target="_blank">"Baseless Exceptions."
1/ 6/03 ais 67 In the examples near the top of the page, it
would be good to note that catch-by-value can
lead to the slicing problem, a topic that is
discussed on page 70 in Item 13.
12/ 6/02 ddg 99 In last sentence "When countChar returns," ==>
"When the statement containing the call to
countChar finishes executing,"
Effective C++ (MEC++). Here are links:
ESTL: http://www.aristeia.com/BookErrata/estl1e-errata.html
MEC++: http://www.aristeia.com/BookErrata/mec++-errata_frames.html
New entries for both books are below.
I hope to update the errata page for Effective C++ by the end of this
month. I'll let you know when I do.
Scott
----------------------------------------------------------------------
NEW ENTRIES FOR ESTL
----------------------------------------------------------------------
Bugs:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- ------------------------------------------------
2/ 1/03 fr 90 Missing colon at end of page. (The missing colon is
actually deliberate, but replacing "try" with "try
this:" will probably be clearer, so that's the change
I'll make.)
1/31/03 fr 91 Include an xref to Item 7 near the definition for
DereferenceLess for readers who are confused about
why DereferenceLess is a non-template struct
containing a templatized operator().
4/18/03 lz 157 In 1st line, "many elements" ==> "many elements
with a particular value"
2/26/03 shh 166 In the third bullet point on the page, "returns
true or false" ==> "returns true or false (or
something that can be implicitly converted to
true or false)."
2/26/03 shh 211 In line 5 of 4th prose para, "do this is with"
==> "do this with"
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
7/16/01 sdm Item 4 If you're interested in the technical and standardization
issues surrounding list::size, check out the July 2001
href="http://groups.google.com/groups?hl=en&lr=lang_en|lang_de&ie=UTF-8&oe=UTF-8\
&threadm=uZj47.33018%24WS4.5267300%40news6-win.server.ntlworld.com&rnum=1&prev=/\
groups%3Fhl%3Den%26lr%3Dlang_en%257Clang_de%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3Du\
Zj47.33018%2524WS4.5267300%2540news6-win.server.ntlworld.com"
target="_blank">comp.std.c++
thread discussing the matter.
12/ 2/02 jr 46 The code at the bottom of this page has two shortcomings:
(1) though it works when iterating over an entire container,
it's incorrect if given an arbitrary end iterator, because
the call to erase will invalidate the end iterator; and (2)
because each call to erase shifts all succeeding elements
down by one, the linear-looking loop really runs in
quadratic time.
Here's code that addresses both problems, where endIt is the
arbitrary end iterator to be used and, for consistency,
beginIt is an arbitrary begin iterator to be used:
vector
while(i!=endIt && !badValue(*i)) ++i;
vector
while(i!=end){
if(badValue(*i)) {
logFile<<"Erasing "<<*i<<'\n';
} else {
*j=*i;
++j;
}
++i;
}
c.erase(j, end);
Note that the second while loop is essentially a variant of
remove_if (see Item 32).
jr reports that in simple tests he performed comparing the
performance of this code with that on the bottom of page 46,
he saw speed improvements of 2-3 orders of magnitude.
2/22/03 fr Item 34 When using an algorithm expecting a sorted range (e.g.,
includes, set_union, etc.) on a standard associative
container (especially a map or multimap), it's important to
pass the correct comparison function. The easiest way to do
this is to pass the result of the value_comp member
function:
typedef multimap
...
bool subMultiset = includes(map1.begin(), map1.end(),
map2.begin(), map2.end(),
map1.value_comp());
This works for sets and multisets, too, because for those
types, value_comp returns the same thing as key_comp.
However, as noted in Item 44, for operations like
lower_bound, etc., it's generally better to use member
functions instead of algorithms when both are applicable.
2/20/03 fr 156 Because postincrement is less efficient than
preincrement, the if statement may be better
implemented as follows:
if (p(*begin)) {
*destBegin = *begin;
++destBegin;
}
2/26/03 shh 159 In order to make sure that the initial summary value
passed to accumulate is of the appropriate type, shh
suggests using this form:
Y sum = accumulate (
begin, // acts like a T*
end, // acts like a T*
static_cast
Y
);
----------------------------------------------------------------------
NEW ENTRIES FOR MEC++
----------------------------------------------------------------------
Bugs:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- ------------------------------------------------
8/14/02 sdm 66-67 The inheritance-based conversions described on
these pages apply only to public inheritance.
For non-public inheritance, things get a bit more
complicated. For details, including a rationale
for the behavior, consult the July 2001 CUJ
column by Jim Hyslop and Herb Sutter,
target="_blank">"Baseless Exceptions."
1/ 6/03 ais 67 In the examples near the top of the page, it
would be good to note that catch-by-value can
lead to the slicing problem, a topic that is
discussed on page 70 in Item 13.
12/ 6/02 ddg 99 In last sentence "When countChar returns," ==>
"When the statement containing the call to
countChar finishes executing,"
Wednesday, March 19, 2003
The Next Edition of Effective C++
I'm beginning to work on the third edition of Effective C++. The second
edition was a fairy conservative sprucing up of the original, but for the
third edition, I expect to make more extensive changes.
I constrained the second edition to follow the Item breakdown of the first
edition fairly closely, but this time I plan to start with a reasonably
clean slate and ask myself, "What are the 50 most useful pieces of advice
for professional developers NOW?" Without a doubt, some of the current
Items will make the cut, but it's time to include new topics, almost
certainly including design and implementation in the presence of templates;
dealing with issues related to exception safety; the impact of threading,
etc. At the same time, I want to continue to avoid undue overlap among my
three books, so there's little chance I'll devote significant space to
topics I already treat in More Effective C++ or Effective STL.
I'll also maintain what I consider to be fundamental strengths of the book:
Items that are short, specific, to the point, and that take both the
Standard and real compilers/libraries into account.
I have plenty of ideas on what EC++/3E should contain, but I'm hoping
you'll offer suggestions, too. What Items or parts of Items are no longer
needed? What new topics should be addressed? What did I do right that I
should avoid breaking? What needs fixing? Are there any things I did or
didn't do in More Effective C++ or in Effective STL that I should be sure
to copy or be sure NOT to copy? Are there ideas from other books I should
steal? In short, how can I make EC++/3E the best EC++ ever?
I hope to receive a lot of email in response to this message, so please
don't be offended if all you get is a pro forma reply. I have only so much
time and energy, and I hope we agree that it's more important for me to
work on the book than to send everybody a personalized reply to each
suggestion. Actually, if you squint just right, you can think of the
revised book as a personalized reply to each of you, because I'll take all
your feedback into account as I work on it.
If would be most convenient for me if you'd send all suggestions to
EC++3E@....
Thanks in advance for all the help I know you'll offer.
Scott
edition was a fairy conservative sprucing up of the original, but for the
third edition, I expect to make more extensive changes.
I constrained the second edition to follow the Item breakdown of the first
edition fairly closely, but this time I plan to start with a reasonably
clean slate and ask myself, "What are the 50 most useful pieces of advice
for professional developers NOW?" Without a doubt, some of the current
Items will make the cut, but it's time to include new topics, almost
certainly including design and implementation in the presence of templates;
dealing with issues related to exception safety; the impact of threading,
etc. At the same time, I want to continue to avoid undue overlap among my
three books, so there's little chance I'll devote significant space to
topics I already treat in More Effective C++ or Effective STL.
I'll also maintain what I consider to be fundamental strengths of the book:
Items that are short, specific, to the point, and that take both the
Standard and real compilers/libraries into account.
I have plenty of ideas on what EC++/3E should contain, but I'm hoping
you'll offer suggestions, too. What Items or parts of Items are no longer
needed? What new topics should be addressed? What did I do right that I
should avoid breaking? What needs fixing? Are there any things I did or
didn't do in More Effective C++ or in Effective STL that I should be sure
to copy or be sure NOT to copy? Are there ideas from other books I should
steal? In short, how can I make EC++/3E the best EC++ ever?
I hope to receive a lot of email in response to this message, so please
don't be offended if all you get is a pro forma reply. I have only so much
time and energy, and I hope we agree that it's more important for me to
work on the book than to send everybody a personalized reply to each
suggestion. Actually, if you squint just right, you can think of the
revised book as a personalized reply to each of you, because I'll take all
your feedback into account as I work on it.
If would be most convenient for me if you'd send all suggestions to
EC++3E@....
Thanks in advance for all the help I know you'll offer.
Scott
Friday, February 7, 2003
New Seminars: Patterns & PBD; C++ in Embedded Systems
I've recently developed two new C++ seminars and added descriptions of them
to my web site. Currently, they are available only for on-site
presentations, though it would not surprise me if I end up presenting one
or both at open-enrollment seminars in Germany in September.
Here are brief descriptions. Please consult their respective web pages for
details.
PATTERNS AND POLICY-BASED DESIGN. I've been getting a lot of inquiries
about design patterns recently, but it seems that few people know that
C++ is uniquely capable of generating flexible and efficient pattern
implementations. This seminar is my way of covering the patterns
material people want to know along with the C++ design techniques they
need to know in order to really exploit patterns in C++. As far as I
know, there's no other course like this, and I'm very excited about it.
I taught it for the first time last week, and it was a big hit.
Full Description: http://www.aristeia.com/patterns-and-pbd_frames.html
EFFECTIVE C++ IN AN EMBEDDED ENVIRONMENT. I mentioned the imminent
arrival of this seminar in a mailing last September, and I'm pleased to
say that it's now fully here. I'm even more pleased to report that the
embedded programmers who've attended the seminar have found the material
to be well suited to the concerns they confront. Short on bytes, cycles,
or a conforming C++ compiler, yet still want to take advantage of C++'s
modeling power, flexibility, efficiency or availability of outside tools?
Ask me how!
Full Description: http://www.aristeia.com/c++-in-embedded_frames.html
I also have a bunch of new talks I need to add to my Short Courses page
(http://www.aristeia.com/short-courses_frames.html). When I get them
added, I'll let you know.
Scott
to my web site. Currently, they are available only for on-site
presentations, though it would not surprise me if I end up presenting one
or both at open-enrollment seminars in Germany in September.
Here are brief descriptions. Please consult their respective web pages for
details.
PATTERNS AND POLICY-BASED DESIGN. I've been getting a lot of inquiries
about design patterns recently, but it seems that few people know that
C++ is uniquely capable of generating flexible and efficient pattern
implementations. This seminar is my way of covering the patterns
material people want to know along with the C++ design techniques they
need to know in order to really exploit patterns in C++. As far as I
know, there's no other course like this, and I'm very excited about it.
I taught it for the first time last week, and it was a big hit.
Full Description: http://www.aristeia.com/patterns-and-pbd_frames.html
EFFECTIVE C++ IN AN EMBEDDED ENVIRONMENT. I mentioned the imminent
arrival of this seminar in a mailing last September, and I'm pleased to
say that it's now fully here. I'm even more pleased to report that the
embedded programmers who've attended the seminar have found the material
to be well suited to the concerns they confront. Short on bytes, cycles,
or a conforming C++ compiler, yet still want to take advantage of C++'s
modeling power, flexibility, efficiency or availability of outside tools?
Ask me how!
Full Description: http://www.aristeia.com/c++-in-embedded_frames.html
I also have a bunch of new talks I need to add to my Short Courses page
(http://www.aristeia.com/short-courses_frames.html). When I get them
added, I'll let you know.
Scott
Tuesday, February 4, 2003
Impending Effective STL Errata List Update
Later today, I'll update the online errata list for Effective STL. As a
mailing list exclusive, here are the changes I'll be making. By the time
these make it to the web site, they may have been massaged somewhat, but
this is what I'll be working from.
Please note in particular the entry for page 91, because it seems to have
been confusing a lot of people recently.
Thanks,
Scott
DATE DATE
REPORTED WHO PAGES WHAT FIXED
-------- --- ----- ------------------------------------------------ --------
11/29/02 gm 44 Regarding the paragraph after the first code
example, the call to erase can't take
logarithmic time in general, because a multi
container might consist entirely of elements
with the value to be removed. gm notes that
"The correct statement, guaranteed true by the
Standard, is: it takes time O(log(n)+k) where n
is the size of the container and k is the number
of items to be erased."
9/ 4/02 ga 46 In the for loop in the first code example,
"AssocContainer" should be entirely in italics.
11/ 6/02 wb 57 In the second code example, the
SpecificHeapAllocator template is missing the
word "class" at the beginning of the template
definition.
7/13/02 ckl 91 In first code example, ssp's type should be
declared to be set.
1/12/03 as 108 Regarding the second-to-last paragraph on the
page, as points out that "only the assigment
operator is 'unnecessary', a temporary Widget is
going to be constructed anyhow, so you have in
balance a (useless) construction/destruction
plus an assigment OVER a (useful)
construction/destruction.'
9/ 4/02 ga 141 At end of second prose paragraph, "...you should
probably be calling partition..." ==> "...you
should probably be calling partition or
stable_partition..."
9/25/02 pn 171-172 Some examples here fail to explicitly state that
inheritance from e.g., std::binary_function is
public. This is inconsistent with what I do
elsewhere in the book, e.g., on pp. 178-179. I
should check all the examples to make sure I'm
consistent.
11/ 2/02 cb 253 In column 1, the entry for istream_iterators
mentioning operator<< should mention operator>>.
11/ 2/02 cb 255 In column 2, the entry for operator<< should
mention operator>>.
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
7/15/01 sdm Item 1 For another discussion of the pros and cons of different
containers, check out Andrew Koenig's and Barbara Moo's
column, "Which Container Should I Use?," in the August 2001
C/C++ Users Journal
8/26/02 sdm Item 7 Several people have written to ask about why
DeleteObject::operator() takes a pointer to const, even
thought it's going to delete the pointer. The answer is
that if I did not, it wouldn't be possible to use
DeleteObject on containers such as vector.
There has been much debate in the C++ community over
whether deleting pointers-to-const should be legal, but it
is and it can be useful, so it's important to me that
DeleteObject support it.
8/18/02 apl 69 apl argues that credit for notion that "God is in the
details" should go to Mies Van Der Rohe, not Einstein. He
points to href="http://www.theatlantic.com/issues/2000/01/001wordcourt.htm"
target="_blank">a column in The Atlantic online to bolser his
argument.
9/ 4/02 ga 117 Five lines from the bottom, "const" should be
capitalized, because it is the first word in a sentence.
8/27/02 jcj Item 28 When using the range form of erase, there is no need to
adjust a reverse_iterator's base if it marks the end of the
erase range. Consider:
vector v;
... // Put 1-5 in v
// Remove 2-4 from vector in example [1, 2, 3, 4, 5]
vector::iterator ifirst = // ifirst points
find(v.begin(), v.end(), 2); // to the 2
vector::reverse_iterator rilast = // rilast points
find(v.rbegin(), v.rend(), 4); // to the 4
v.erase(ifirst, rilast.base()); // erase 2-4,
// inclusive
9/ 4/02 ga 133 Writes ga, "Another variation: reserve, move away/copy the
elements that would be moved one by one in one chunk and
then transform on the gap that we are left with." I
believe that in some cases, this will be more efficient
than resize/copy.
9/ 4/02 ga 161 for_each is also faster.
I'm also going to update some of the "Interesting comments" about Item 37,
but those updates are not shown here, sorry.
mailing list exclusive, here are the changes I'll be making. By the time
these make it to the web site, they may have been massaged somewhat, but
this is what I'll be working from.
Please note in particular the entry for page 91, because it seems to have
been confusing a lot of people recently.
Thanks,
Scott
DATE DATE
REPORTED WHO PAGES WHAT FIXED
-------- --- ----- ------------------------------------------------ --------
11/29/02 gm 44 Regarding the paragraph after the first code
example, the call to erase can't take
logarithmic time in general, because a multi
container might consist entirely of elements
with the value to be removed. gm notes that
"The correct statement, guaranteed true by the
Standard, is: it takes time O(log(n)+k) where n
is the size of the container and k is the number
of items to be erased."
9/ 4/02 ga 46 In the for loop in the first code example,
"AssocContainer" should be entirely in italics.
11/ 6/02 wb 57 In the second code example, the
SpecificHeapAllocator template is missing the
word "class" at the beginning of the template
definition.
7/13/02 ckl 91 In first code example, ssp's type should be
declared to be set
1/12/03 as 108 Regarding the second-to-last paragraph on the
page, as points out that "only the assigment
operator is 'unnecessary', a temporary Widget is
going to be constructed anyhow, so you have in
balance a (useless) construction/destruction
plus an assigment OVER a (useful)
construction/destruction.'
9/ 4/02 ga 141 At end of second prose paragraph, "...you should
probably be calling partition..." ==> "...you
should probably be calling partition or
stable_partition..."
9/25/02 pn 171-172 Some examples here fail to explicitly state that
inheritance from e.g., std::binary_function is
public. This is inconsistent with what I do
elsewhere in the book, e.g., on pp. 178-179. I
should check all the examples to make sure I'm
consistent.
11/ 2/02 cb 253 In column 1, the entry for istream_iterators
mentioning operator<< should mention operator>>.
11/ 2/02 cb 255 In column 2, the entry for operator<< should
mention operator>>.
Interesting Comments:
DATE
REPORTED WHO PAGES WHAT
-------- --- ----- -----------------------------------------------------------
7/15/01 sdm Item 1 For another discussion of the pros and cons of different
containers, check out Andrew Koenig's and Barbara Moo's
column, "Which Container Should I Use?," in the August 2001
C/C++ Users Journal
8/26/02 sdm Item 7 Several people have written to ask about why
DeleteObject::operator() takes a pointer to const, even
thought it's going to delete the pointer. The answer is
that if I did not, it wouldn't be possible to use
DeleteObject on containers such as vector
There has been much debate in the C++ community over
whether deleting pointers-to-const should be legal, but it
is and it can be useful, so it's important to me that
DeleteObject support it.
8/18/02 apl 69 apl argues that credit for notion that "God is in the
details" should go to Mies Van Der Rohe, not Einstein. He
points to href="http://www.theatlantic.com/issues/2000/01/001wordcourt.htm"
target="_blank">a column in The Atlantic online to bolser his
argument.
9/ 4/02 ga 117 Five lines from the bottom, "const" should be
capitalized, because it is the first word in a sentence.
8/27/02 jcj Item 28 When using the range form of erase, there is no need to
adjust a reverse_iterator's base if it marks the end of the
erase range. Consider:
vector
... // Put 1-5 in v
// Remove 2-4 from vector in example [1, 2, 3, 4, 5]
vector
find(v.begin(), v.end(), 2); // to the 2
vector
find(v.rbegin(), v.rend(), 4); // to the 4
v.erase(ifirst, rilast.base()); // erase 2-4,
// inclusive
9/ 4/02 ga 133 Writes ga, "Another variation: reserve, move away/copy the
elements that would be moved one by one in one chunk and
then transform on the gap that we are left with." I
believe that in some cases, this will be more efficient
than resize/copy.
9/ 4/02 ga 161 for_each is also faster.
I'm also going to update some of the "Interesting comments" about Item 37,
but those updates are not shown here, sorry.