Full Code of yosefk/cpp-fqa for AI

master 1b2a1a70526e cached
41 files
566.7 KB
132.6k tokens
9 symbols
1 requests
Download .txt
Showing preview only (586K chars total). Download the full file or copy to clipboard to get everything.
Repository: yosefk/cpp-fqa
Branch: master
Commit: 1b2a1a70526e
Files: 41
Total size: 566.7 KB

Directory structure:
gitextract_io2u6nst/

├── .gitignore
├── LICENSE
├── assign.fqa
├── changelog.fqa
├── class.fqa
├── const.fqa
├── ctors.fqa
├── defective.fqa
├── disclaimers.fqa
├── dtor.fqa
├── exceptions.fqa
├── faq.fqa
├── fqa2html.py
├── friend.fqa
├── function.fqa
├── ga.js
├── heap.fqa
├── index.fqa
├── inheritance-abstract.fqa
├── inheritance-basics.fqa
├── inheritance-mother.fqa
├── inheritance-multiple.fqa
├── inheritance-proper.fqa
├── inheritance-virtual.fqa
├── inline.fqa
├── io.fqa
├── linkimages.py
├── linking.fqa
├── mixing.fqa
├── operator.fqa
├── picture.fqa
├── readme.txt
├── ref.fqa
├── refresh.py
├── templates.fqa
├── tidy.py
├── toc.py
├── upload.py
├── web-vs-c++.fqa
├── web-vs-fqa.fqa
└── why.fqa

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.pyc
*.html
*.exe
_out_.txt
*~
.*.swp


================================================
FILE: LICENSE
================================================
Copyright (c) 2015, Yossi Kreinin
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



================================================
FILE: assign.fqa
================================================
Assignment operators
{'section':12,'faq-page':'assignment-operators.html'}
This section is about |operator=|. It's rather strange that of all possible things, people only "frequently ask" about self assignment, but those are the only questions listed in the FAQ.

What is "self assignment"?

FAQ: It's assigning the object to itself, directly or indirectly. For example:

@
void f(C& x, C& y) { x=y; }
void g(C& x) { f(x,x); }
@

FQA: The tricky part is that the assignment operator may be overloaded, and you are expected to overload it in the
classes that "own" resources (most frequently memory obtained with |new|). Incidentally, these are exactly
the cases when self assignment may lead to trouble, which is why we have the next question. Which will also show
that the FAQ's definition of "self assignment" is unfortunately too conservative, as "self" is a vague concept.

-END

Why should I worry about "self assignment"?

FAQ: If you don't, your |operator=| will probably misbehave severely upon self-assignment:

@
YetAnotherSoCalledSmartPointer& YetAnotherSoCalledSmartPointer::operator=(const YetAnotherSoCalledSmartPointer& p)
{
  delete _p;
  _p = new TheThingPointedByTheSmartPointer(*p._p);
  return *this;
}
@

Self assignment will first delete |_p|, and then dereference it, which is nasty. And it is all /your/ fault - you
should have handled self assignment!

FQA: Oh, so it's my fault, isn't it? Then why isn't this question listed in any other programming language FAQ on the planet?
I mean, it's the same me all the time, it's the languages that are different. So why don't we lose the feelings of guilt
and check what it is about C++ that causes the problem?

Most languages daring to call themselves "object-oriented" have garbage collection, so you don't spend your
time writing stupid functions for deallocating stuff, then copying stuff. These functions are all alike, but
with C++ you get to write this kind of code over and over again.

C++ doesn't have garbage collection, so a problem arises - if people are creating all those objects,
how are they going to dispose them, especially if they [13.1 overload operators] and do things like |a+b+c|, without
even keeping the pointers to the temporary objects created when sub-expressions are evaluated? The C++ answer is to have an "owner" object for
each chunk of allocated memory, and let |operator=| and the destructor worry about freeing the memory.
The most common manifestation of this quite unique language design decision is [16.1 unnecessary copying],
which happens when objects are passed to functions or returned by value or "cut out" from larger
data structures.

The self assignment problem is another manifestation of this same thing. If objects were passed by pointers\/references
and garbage-collected automatically, self assignment (setting the pointer to the value of itself) would be harmless.
And the worst part is that there are actually more cases of self assignment than |x=x|. For example, consider
|std::vector::push_back()|. What if someone passes an object from the vector itself, as in |v.push_back(v.back())|?
|push_back| may need to allocate more memory, which may cause it to free the buffer it already uses, destroying
its argument. [18.2 Where] does the "self" of an object end?

You have to be really smart to get all those smart pointer and container classes right. Too bad it's still worse
than good containers [6.2 built into a language].

-END
                                                                                                        
OK, OK, already; I'll handle self-assignment. How do I do it?                                                         

FAQ: By adding a test like |if(this==&that) { return *this; }| or by copying the members of the input object before deallocating members
of |this|.

FQA: This avoids the destruction of your function argument via self-destruction in |operator=|.
However, there are [12.2 other cases when that can happen] - consider |std::vector::push_back()|.

When performance is more important to you than simplicity & generality, one way to deal with this family of
problems is to document them and pass them on to the user of your code
("it is illegal to push an element of a vector into that vector, if you need to do it, copy the element explicitly").

When simplicity & generality are more important than performance, you can use a language automatically tracking
references to objects, guaranteeing that used objects won't get destroyed.

-END


================================================
FILE: changelog.fqa
================================================
Change log
{}
This is a list of changes in the FQA part of the site done after October 28, 2007. It only mentions "real" changes to the contents,
not typo fixes and such.

The Q&A sections of the FQA and Defective C++ are probably not going to change much; mostly, I plan to add links
to corrections on a separate page.

/2009-10-17/

Added a correction about conversions between code and data pointers,
and a reader's submission regarding a truly mind-numbing error message.

/2008-06-28/

Added a single page version (Defective C++, Q&A, FQA errors, everything else
left out). Linked to it from the index page. Deleted a sentence from the FQA
errors page, added a sentence to the FQA FAQ. That kind of stuff.

/2008-05-08/

Added two C++ corrections (regarding |#define private public| and
multi-dimensional arrays). Slight editing of the FAQ (most notably,
added a correction about the flat Earth issue). All pages should now
be [http://tidy.sourceforge.net/ tidy].

The outburst of activity is the result of finally taking control over
my hateful world-class FQA publishing software, which was, at last, merged,
fixed,
and put on a single machine. From now on, fixes should appear instantaneously
(as opposed to being deferred until I take control over my hateful publishing
software).

/2008-01-02/

Added the Cat++ link face, at the end of a day of C++ debugging.
I wonder if it shows in the so-called art.

/2007-11-03/

Added an FQA correction - C++ has |bool|.

Linked to the |comp.lang.c++.moderated| thread from the FQA FAQ.

Added an image with |operator<<| to the link faces page.

/2007-10-31/

Added an item about iostream and internationalization to others' criticism page.

Renamed the "Web vs *" pages since the names started to look annoying to me.
What was I thinking?

Edited in a correction about EDG selling Java and Fortran front-ends,
and then removed the whole thing.

/2007-10-30/

Added the Web vs C++ page and the first three issues (implicit conversions and parsing C++ x 2).

Updated the FQA FAQ to mention the corrections page in the present tense, since it now exists,
and added three braindead, but genuinely frequently asked questions.

/2007-10-29/

Added the Web vs C++ FQA page and the first correction (virtual inheritance).

Gave up on Web 2.0 and asked people to e-mail me if they want to talk about the FQA.
Updated the FAQ and the main page.


================================================
FILE: class.fqa
================================================
Classes and objects
{'section':7,'faq-page':'classes-and-objects.html'}
One of the stated goals of C++ is support for object-oriented programming. This page introduces C++ classes and outlines the tactics they use to defeat their purpose.

What is a class?

FAQ: In OO software, "the fundamental building block".

A class is a type - a representation for a set of states (much like a C |struct|) and a set of operations for
changing the state (moving from one state to another). Classes are similar to built-in types in this sense
(for example, an |int| holds a bunch of bits and provides operations like + and *).

FQA: That's a correct theoretical definition. It's equally applicable to all OO languages, but they
are different when it comes to more specific, practical aspects of their particular implementation of classes.

How do I create objects? And [16.1 what happens] when they are no longer needed? Is it /my/ job to figure out which ones
are unused and deallocate them? Bad.

[7.2 What happens] if I have bugs? If I have a pointer to an object, can it be invalid (be a random bit pattern, point to a dead object)?
It can? The program will /crash/ or worse?
What about arrays of objects and out-of-bounds indexes? Crash or a modification of some other random object?
You call that encapsulation? Bad.

[7.4 What happens] if I change\/add\/remove a private value, without changing the interface?
All code using the class has to be /recompiled/? I bet you call that encapsulation, too. Bad.

I don't like C++ classes.

-END

What is an object?

FAQ: A chunk of memory with certain semantics. The semantics are defined by the class of the object.

FQA: They are also defined by the bugs which cause the code to overwrite data of these objects without bothering
to use the interface defined by the class. People who think that real programmers write code without bugs need
to upgrade to a human brain.

Still, it sounds interesting: the memory of our C++ program is apparently broken into chunks storing
objects of various classes, with "defined semantics". Looks very promising, that.
For example, we could ask a debugger about the kind of object located at such a chunk and inspect its data
(as in "this is a Point with x=5 and y=6"). We could even take this one step further and implement things like
garbage collectors, which can check whether an object is used by looking for pointers to it in the places which
are /supposed/ to store pointers.

Unfortunately, you can't tell the class of a C++ object given a pointer to it at run time. So if you debug
a crashed C++ program and find a pointer somewhere in its guts, and you don't know its type, you'll have
to guess that "0000000600000005" is a Point. Which is completely obvious, because that's the way a pair of
adjacent integers looks like in hexadecimal memory listings of a little endian 32 bit machine. And two adjacent integers might be a Point.
Or some other two-integer structure. Or a part of a three-integer-and-a-float structure.
Or they might be two unrelated numbers which just happen to be adjacent.

Which is why you can't automatically collect the garbage of C++ programs.

-END

When is an interface "good"?

FAQ: It is good when it hides details, so that the users see a simpler picture. It should also speak the language
of the user (a developer, not the customer).

FQA: Um, sometimes you want the interface to expose the many details and speak the language of the machine,
although it's probably not very common. The generic answer is something like "an interface is good if it gets the user somewhere".

For example, using [http://www.opengl.org OpenGL] you can render nifty 3D stuff at real time frame rates.
[http://www.fftw.org FFTW] delivers, well, the Fastest Fourier Transform in the West.
With [http://trolltech.com/products/qt Qt], you can develop cross-platform GUI, and "cross-platform" won't mean
"looking like an abandoned student project".
Writing that stuff from scratch is lots of work; using the libraries can save lots of work.
Apparently learning the interfaces of these libraries is going to pay off
for many people.

For a negative example, consider |<algorithm>|. Does |std::for_each| get us anywhere compared to a bare |for| loop,
except that now we need to define a [33.10 functor] class? That's a bad interface, because learning it
doesn't make it easier to achieve anything useful.

-END

What is encapsulation?

FAQ: The prevention of "unauthorized access" to stuff.

The idea is to separate the implementation (which may be changed) from the interface (which is supposed to be stable).
Encapsulation will force users to rely on the interface rather than the implementation. That will make changing
the implementation cheaper, since the code of the users won't need to be changed.

FQA: That's a nice theoretical definition. Let's talk about practice - the properties of the C++ keywords |private|
and |protected|, which actually implement encapsulation.

These keywords will cause the compiler to produce an error message upon access to a non-public member outside
of the class. However, they will not cause the compiler to prevent "unauthorized access" by buggy code,
for example upon buffer overflow. If you debug a crashed or misbehaving C++ program, forget about encapsulation.
There's just one object now: the memory.

As to the cost of changes to the the private parts - they trigger recompilation of all code that |#include|s your class
definition. That's typically an order of magnitude more than "code actually using your class", because everything ends
up including everything.
"The key money-saving insight", as the business-friendly-looking FAQ puts it, is that /every time you change a class definition,
you are recompiling the programs using it/. Here's another simple observation: C++ compiles slowly. And what do we get
now when we put two and two together? That's right, kids - with C++ classes, the developers get paid primarily to wait for
recompilation.

If you want software that is "easy to change", [7.5 stay away] from C++ classes.

-END

How does C++ help with the tradeoff of safety vs. usability?

FAQ: In C, stuff is either stored in |struct|s (safety problem - no encapsulation), or it is declared |static| at the file
implementing an interface (usability problem - there is no way to have many instances of that data).

With C++ classes, you can have many instances of the data (many objects) /and/ encapsulation (non-|public| members).

FQA: This is /wildly wrong/, and the chances that the FAQ author didn't know it are /extremely low/.
That's because you can't use |FILE*| from |<stdio.h>| or |HWND| from |<windows.h>| or in fact any widely used and\/or decent C library
without noticing that the FAQ's claim is wrong.

When you need multiple instances and encapsulation
in C, you use a forward declaration of a |struct| in the header file, and define it in the implementation file.
That's actually /better/ encapsulation than C++ classes - there's still no /run-time/ encapsulation (memory can be accidentally\/maliciously overwritten),
but at least there's /compile-time/ encapsulation (you don't have to recompile the code using the interface when you change the implementation).

The fact that a crude C technique for approximating classes is better than the support for classes built into the C++ language is really
/shameful/. Apparently so shameful that the FAQ had to distort the facts in an attempt to save face
(or else the readers would wonder whether there's any point to C++ classes at all). The FQA hereby declares that it will
not go down this path. Therefore, we have to mention this: the forward declaration basically makes it impossible for the
calling code to reserve space for the object at compile time. This means that a |struct| declared in a header file
or a C++ class can sometimes be allocated more efficiently than a forward-declared |struct|. However, this is really
 about a /different/ tradeoff - safety vs. /efficiency/, and there's no escape from this tradeoff. Either the caller knows
 about the details such as the size of an object at compile time - which /breaks/ compile-time encapsulation - or it doesn't,
 so it can't handle the allocation.

Anyway, here's the real answer to the original question: C++ helps with the tradeoff of safety vs. usability by eliminating both.

C++ is extremely unsafe because every pointer can be used to modify every piece of memory from any point in code.
C++ is extremely unusable due to cryptic syntax, incomprehensible semantics and endless rebuild cycles.
Where's your tradeoff now, silly C programmers?

-END
 
How can I prevent other programmers from violating encapsulation by seeing the |private| parts of my class?

FAQ: Don't bother. The fact that a programmer knows about the inner workings of your class isn't a problem. It's
 a problem if /code/ is written to depend on these inner workings.

FQA: That's right. Besides, people can always access the code if a machine can. Preventing people from "seeing" the code
 in the sense that they can access it, but not understand it is obfuscation, not encapsulation.

-END

Is Encapsulation a Security device?

FAQ: No. Encapsulation is about error prevention. Security is about preventing purposeful attacks.

FQA: Depends on the kind of "encapsulation". Some managed environments rely on their support for run time encapsulation,
 which makes it technically impossible for code to access private parts of objects, to implement security mechanisms.
C++ encapsulation evaporates at run time, and is almost non-existent even at compile time
 - use |#define private public| before including a header file and there's no more encapsulation /[corr.3 (correction)]/. [7.4 It's hardly
  "encapsulation" at all], so of course it has no security applications - security is harder than encapsulation.

The capital E and S in the question are very amusing. I wonder whether they are a manifestation of Deep Respect for
  Business Values or Software Engineering; both options are equally hilarious.

-END

What's the difference between the keywords |struct| and |class|?

FAQ: By default, |struct| members and base classes are |public|. With |class|, the default is |private|. Never rely
  on these defaults! Otherwise, |class| and |struct| behave identically.

But the important thing is how developers /feel/ about these keywords. |struct| conveys the feeling that its members
  are supposed to be read and modified by the code using it, and |class| feels like one should use the class
  methods and not mess with the state directly. This difference is the important one when you decide which keyword to use.

FQA: |struct| is a C keyword. |class| was added to C++ because it is easier than actually making the language object-oriented.
  And it does a good job when it comes to the /feeling/ of a newbie who heard that "OO is good".

Check out the emotional discussion about which keyword should be used in the FAQ. The more similar two duplicate C++
  features are, the more heated the argument about the best option to use in each case becomes. Pointers\/references,
  arrays\/vectors... Yawn.

By the way, [7.5 the forward-declaration-of-struct thing] works in C++, and it's better than a |class| without |virtual|
  functions most of the time.
  
-END


================================================
FILE: const.fqa
================================================
Const correctness
{'section':18,'faq-page':'const-correctness.html'}
This is about the |const| keyword, which makes you write your program twice (or more, depending on your luck).

What is "|const| correctness"?

FAQ: Oh, that's a great thing. You declare an object as |const| and prevent it from being modified.

For example, if you pass a |std::string| object to a function by |const| pointer or reference, the function
won't modify it and it won't be copied the way it happens when the object is passed by value.

FQA: Interesting. What about vector of pointers to objects? Let's see. If the vector itself is declared
|const| (as in |const std::vector<T*>|), then you can't modify the vector, but you can modify the objects.
If the pointers are declared |const| (as in |std::vector<const T*>|), then you can modify the vector,
but not the objects. Now suppose you have a vector of non-|const| objects, and you want to pass them to a function
that accepts a |const| vector of |const| objects. Oops, can't do that - the vectors are two different unrelated types
as far as the compiler is concerned (no, C++ weenies, it actually [18.17 doesn't] make sense, think again). You'll have to create a temporary vector of the right type and copy
the pointers (which will compile just fine since |T*| is silently convertible to |const T*|).

That's what |const| correctness is all about: increasing the readability of your program and protecting
you from errors without any performance penalties.

By the way, not using |const| in C++ is quite likely /not/ a very good idea. Of all questionable C++ features, |const| probably
does the most visible damage when avoided. Any piece of code using |const| forces every other piece touching it to use
|const|, or else you won't be able to work with the objects it gives you. And here's the funny part: every
piece of code /not/ using |const| forces every other piece touching it /to not use it, either/ - or else you
won't be able to pass objects to it. So if you have one |const| particle and one anti-|const| particle,
there's a big shiny explosion of |const_cast| in your code. Since |const| is hard-wired into the
language (no way to pass a temporary to a function that gets a non-const reference, for example) and the standard library
(|iterator| and |const_iterator|), using |const| is usually a safer bet than avoiding it.

-END

How is "|const| correctness" related to ordinary type safety?

FAQ: It's one form of type safety. You can think about |const std::string| as an /almost/ separate type that lacks
certain operations of a string, like assignment. If you find type safety useful, you'll also like |const| correctness.

FQA: It's related to ordinary type safety in a pretty complicated way. |const| and |volatile| are special cases
in the type system - they are "type qualifiers". The relation between a qualified type and a non-qualified type
is different from any other relation between types in the language. This is one of the very many complications
in the implicit conversion and overload resolution rules.

It works smoothly for the simple cases, especially if there are no other complications. It breaks pretty hard
whenever you have a pointer-like object. Pointers can get /two/ const qualifiers, one for the pointer and one for the pointed values.
This is awkward and unreadable and when you have pointers to pointers and three const qualifiers, you may need
cryptic explicit casts, but at least there's syntax for all the levels of constness. With "smart pointers" (the
things you should stuff into [17.4 every possible hole] because pointers are [6.15 evil]), there's no such syntax. That's why
we have |iterator| and |const_iterator| - saying |const iterator| says that the iterator is immutable, but not
what it points to. Exercise: implement a vector-like class that can get the storage pointer from the user,
in a const-correct way that supports attaching both to constant and mutable storage areas.

And of course a vector of |const| pointers is compiled to a different bulk of (identical) assembly code
than a vector of mutable pointers. At least here the compiler is writing the same program twice, which is
better than having to do this yourself. Which also happens - |const_iterator| is one family of examples.

-END

Should I try to get things |const| correct "sooner" or "later"?

FAQ: As soon as possible, because when you add |const| to a piece of code, it triggers changes in every place
related to it.

FQA: That's right. Since you can't get out of the tar pit, the best strategy is to climb right into the middle
and make yourself comfortable from the beginning. No kidding, I actually agree with the FAQ.
See also the advice [18.1 above] about /not/ avoiding |const|.

-END

What does "|const Fred* p|" mean?

FAQ: A pointer to a |const Fred| object. The object can't be changed, for example, you can't call methods not qualified
as |const|.

FQA: Right. But don't count on it when you debug code. |const| can be cast away in a snap (pretty much like everything
else in C++), and there's the |mutable| keyword for creating members that can be modified by methods qualified as |const|.
And of course someone can have /another/, non-const pointer to the same |Fred| object. /And/ the |const|-qualified methods may modify
data pointed by its member pointers and references or by pointers kept in things pointed by its member pointers, etc.

The pointer aliasing issue is one reason that the compiler /can't/ really optimize code because it sees a pointer declared
as |const|. And when it /can/ figure out there are no aliases, it /doesn't need/ your const declarations to help it. You
can explain the difference between data flow analysis and type qualification to the next [10.9 pseudo-performance-aware]
person who advocates declaring every local integer as |const|. See also a [18.14 correct FAQ answer] to this question below.

-END

What's the difference between "|const Fred* p|", "|Fred* const p|" and "|const Fred* const p|"?

FAQ: In the first example, the object is immutable. In the second example, the pointer is immutable. In the third example,
both are immutable.

FQA: Um, right. Remember: |const| makes your programs readable.

-END

What does "|const Fred& x|" mean?

FAQ: It's a reference to an immutable Fred object.

FQA: Which is similar to a pointer to an immutable Fred object. However, the FAQ holds the [8.6 "references are NOT pointers"]
religion (specifically, it belongs to the "pointers are [6.15 evil]" faction), so it dutifully replicates the explanation given
in the [18.4 answer] about the pointer case, replacing "pointer" with "reference".

-END

Does "|Fred& const x|" make any sense?

FAQ: No. It says that you can change the object, but not the reference. But you can never change a reference anyway, it will
always refer to a single object.

Don't write such declarations, it confuses people.

FQA: So [25.13 why does this compile]? Wait, I don't really want to know. Whether it's because they didn't bother to disallow it,
or because some special case of template instantiation (like when you add a |const| to a parameter type which is in fact a reference)
would fail or anything like that - that's just another lame excuse as far as a language user is concerned.

-END

What does "|Fred const& x|" mean?

FAQ: It's equivalent to "|const Fred& x|". The question is - which form should you use? Nobody can answer this for /your/
organization without understanding /your/ needs. The are lots of business scenarios, some producing the need for one
form, others for the other. The discussion takes a full screen of text.

FQA: Yawn. Another [7.8 stupid duplication] in C++.

Come /on/. What "business scenarios" can "produce needs" for a form of a |const| declaration? If your organization employs
people who can't memorize both forms or check what a declaration means, you have to admit they will drown in
C++ even if you somehow know for sure that in general they can program. C++ has /megatons/ of syntax.

-END

What does "|Fred const* x|" mean?

FAQ: The FAQ replicates the previous answer, replacing "reference" with "pointer". Probably the same [8.6 religion] thing again.

FQA: Yawn. Another [18.6 stupid duplication] in the C++ FAQ.

-END

What is a "|const| member function"?

FAQ: It's declared by appending |const| to the prototype of a class member function. Only this kind of methods may be
called when you have a |const| object. Errors are caught at compile time, without any speed or space penalty.

FQA: As discussed above, this [18.2 breaks into little pieces] when your class is similar to a pointer in the sense that
a user can change both the state of your object and use your object to change some other state. As to the speed
and space penalty, you may check the symbol table of your program if you want to know how many functions were
[35.10 generated twice from a single template] because of |const| and non-|const| template parameters. Then you can count
the functions having identical code except for extra |const| qualifiers in some versions, but not others.

-END

What's the relationship between a return-by-reference and a |const| member function?

FAQ: |const| member functions returning references to class members should use a |const| reference. Many times the compiler
will catch you when you violate this rule. Sometimes it won't. You have to think.

FQA: /Of course/ you have to think about this complete and utter nonsense! Somebody has to, and the C++ designers didn't.

As usual with |const|, the compiler becomes [18.2 dumb] when levels of indirection appear. For instance, if you keep a member
reference, the thing it points to is not considered part of the object. It's up to you to decide whether you want
to return this reference as |const| or non-|const| from your |const| member accessor. Both choices may eventually
lead to |const_cast|.

-END

What's the deal with "|const|-overloading"?

FAQ: You can have two member functions with a single difference in the prototype - the trailing |const|. The compiler
will select the function based on whether the |this| argument is |const| or not. For instance, a class with a subscript
operator may have two versions: one returning mutable objects and one returning |const| objects - in the latter version,
|this| is also qualified as |const|.

FQA: /Please try to avoid this feature/. In particular, get and set functions having the same name (|const|-overloaded)
are not a very good idea.

Having to replicate the code of a subscript operator just to add two |const| qualifiers - for the return value and
the |this| argument - is yet another example of |const| forcing you to write your program twice. Well, most likely
there are more problems where this one came from. A class with a subscript operator is a "smart array",
probably not unlike |std::vector|, so you'll end up with much more replicated code - an |iterator| and a
|const_iterator| or some such.

-END

What do I do if I want a |const| member function to make an "invisible" change to a data member?

FAQ: There are legitimate use cases for this - that would be when a user doesn't see the change using the interface
of the class. For example, a set class may cache the last look-up to possibly speed up the next look-up.

Use the |mutable| keyword when you declare the members you want to change this way. If your compiler doesn't have
|mutable|, use |const_cast<Set*>(this)| or the like. However, try to avoid this because it can lead to undefined behavior
if the object was originally declared as |const|.

FQA: Most compilers probably support |mutable| today, but you may still need |const_cast| because the tweaks to the
type system supporting |const| [18.2 break in many cases]. Which may be a problem combined with the fact that
|const_cast| is not designed to work with objects declared as |const| (as opposed to those declared non-constant but passed to a function by |const| reference or pointer).

There are numerous reasons making |const_cast| safer in practice than in theory. People rarely declare objects as |const|.
Compiler writers are unlikely to add special cases to their compiler to support |const| objects of C++ classes because it's hard work
that is unlikely to pay off. For example, allocating a global |const| C-style structure with an aggregate initializer in read-only
memory is easy. Doing the same for a C++ class with a constructor is hard because the constructor must be able to
write to the object upon initialization. So you'd have to use writable memory you later make read-only, which is not
typically supported by object file formats and operating systems. Or you could translate C++ code to a C-style aggregate
initializer, spending lots of effort to only handle the cases when the compiler can [9.1 inline] the code of the constructors.

However, there is no simple rule making it "very close to impossible" for a compiler writer to use the opportunity
provided by the standard and implement |const| objects differently from other objects. In the case of [18.4 optimizing]
the dereferencing of |const| pointers, such a rule does exist (there might be other, non-|const| pointers to the same location).
But in the case of objects declared |const|, there /should/ be no such pointers.

The fact that the compiler is allowed
to work under this assumption could be great if it were more likely to actually yield performance benefits, and
if |const| worked to an extent making the use of |const_cast| unnecessary. The current state of affairs just
creates another source of uncertainty for the programmer.

-END

Does |const_cast| mean lost optimization opportunities?

FAQ: Theoretically, yes. In practice, no. If a compiler knows that a value used in a piece of code
is not modified, it can optimize the access to that value, for example, fetch it to a machine register.
However, the compiler can't be sure that a value pointed by a |const| pointer is not modified because
of the aliasing problem: there can be other pointers to the same object, not necessarily constant.
Proving the opposite is almost always impossible.

And when the compiler can't prove it, it can't speed up the access to the value. For example, if it
uses the value it fetched to a register after someone modified it in the original memory location,
the compiler changes the meaning of the program because it uses an outdated value.

FQA: Three cheers to the FAQ! No, really, this time the answer describes the actual state of affairs.
You understand why I'm so deeply touched if you met some of [18.4 the many C++ users] who
give a different answer to this question, and know their [10.9 ways] to reason about performance.

I think the answer is "no" in theory, too, because basically the compiler has to figure out which parts of
the code modify the data, and if it knows the data won't get modified while this piece of code is running, it can use
this fact, and otherwise it can't, so what difference do your |const|-qualifications make? But let's
say I'm not really sure, and anyway, it's not the time to argue about the exact phrasing when once in
a lifetime a realistic statement appears about the performance of C++ code.

The thing that is worth noting is that aliasing problems impede the performance of "generic" libraries, not just compilers.
For example, consider |vector<T>::push_back()|. The vector will try to append the object to its storage.
If there's no free space left, it will allocate a larger chunk, copy the old objects, and then append the
new one. The new object is thus copied once (from wherever it was into the vector storage), right?

But what if the object [12.2 is itself located in the old chunk], and |vector| tries to be efficient and use |realloc|, which
may or may not free the old memory? The object may be wiped out by |realloc|. Very good, then, |vector|
creates /another/ copy. Hop 1 - from the parameter to a temporary, hop 2 - from a temporary to the vector storage
and everyone is happy - after a certain amount of clock cycles.

"Theoretically, yes. In practice, no." Quite a nice summary of C++.

-END

Why does the compiler allow me to change an |int| after I've pointed at it with a |const int*|?

FAQ: Because when you point to something with a |const| pointer, this only means that you can't
use that pointer to change the object. It doesn't mean the object can't be changed at
all, because it can be accessible in other ways, not only through this pointer.

FQA: Exactly; it's related to the previous FAQ. Surprisingly for C++, it even makes sense.
After all, when the object is /declared/, it seems like the right place to say what can be done with it.
But if anyone can take an existing object
and point to it and thus redefine what can be done with it, it's just weird, and can't really
work, because it could be done from many places in incompatible ways.

-END

Does "|const Fred* p|" mean that |*p| can't change?

FAQ: No, for example, it could change through a non-constant |Fred* q| pointing to the same object.

FQA: This question is just like the previous one.

-END

Why am I getting an error converting a |Foo**| to |const Foo**|?

FAQ: It would be "invalid and dangerous"! Suppose |Foo**| points to an array of pointers, which
can be used to modify the pointed objects. Suppose C++ would allow to pass this array to a function
which expects |const Foo**| - an array of pointers which /can't/ be used to modify the pointed objects.

Now suppose that this function fills the array with a bunch of pointers to /constant/ objects.
This looks perfectly good in that context, because that's what the function was passed - an
array of pointers to constant objects. But what we've got now is an array of pointers which can be used to modify those |const| objects,
because the declaration of the array does allow such modifications!

It's a good thing we get a compile time error instead. Don't use casts to work around this!

FQA: Wonderful. But why are we discussing evil built-in pointers anyway? Let's talk about the smart
C++ array classes. Why can't I pass |std::vector<T*>&| to a function expecting
|const std::vector<const T*>&|? The function clearly says that it's not going to modify /anything/:
neither the vector nor the pointed objects. Why can't I pass my mutable vector of mutable objects
to a function that promises not to modify either of those?

-END


================================================
FILE: ctors.fqa
================================================
Constructors
{'section': 10, 'faq-page': 'ctors.html'}
This section is about constructors, which create C++ objects, as well as a large number of problems.

What's the deal with constructors?

FAQ: A constructor initializes an object given a chunk of memory having arbitrary (undefined) state, the way "init functions" do. It may acquire resource like memory, files, etc. "Ctor" is a common abbreviation.

FQA: That's right - constructors /initialize/ objects. In particular, constructors /don't/ allocate the chunk of memory used for storing the object. This is done by the code calling a constructor.

The compiler thus has to know the size of a memory chunk needed to store an object of a class
(this is the value substituted for |sizeof(MyClass)|) at each point where the class is used.
That means knowing all members (public & private). This is a key reason why changing the /private/ parts of a C++ class
definition requires [7.5 recompilation of all calling code], effectively making the private members a part of the public
interface.

This design of C++ constructors is extremely impractical because the smallest change can trigger the largest
recompilation cycle. This would be less of a problem if C++ compiled fast, and if there was an automatic way to
detect that code was compiled with an outdated class definition - but it doesn't, and there isn't.

This is one of the many examples where C++ ignores [6.1 practical] considerations in an attempt to achieve
theoretical [6.2 perfection] ("language features should /never, ever/ impose any performance penalty!"). Compare this to the approach taken in most object-oriented languages, which normally choose
true decoupling of interface, sacrificing the efficiency of allocation. Some of these languages provide ways to
optimize the allocation of /public/ data. This lets you improve performance when you actually need it,
but without the illusion of [7.4 "encapsulation"], and have real encapsulation in the rest of your system.

-END

Is there any difference between |List x;| and |List x();|?

FAQ: Yes, and it's a /big/ one. The first statement declares an object of type |List|, the second declares a function returning an object of type |List|.

FQA: There sure is quite a semantic difference. Too bad it's not accompanied by an equally noticeable syntactic difference. Which is why the question became a frequently asked one.

The problem is that it's hard to tell C++ constructor calls from C\/C++ function declarations. The cases discussed here - constructors without arguments - are a relatively moderate manifestation of this problem. All you have to do is memorize a stupid special case: constructor calls look like function calls except when there are no arguments, in which case parentheses must be omitted. There are tons of weird rules in the C++ grammar, and another one doesn't make much difference.

But when there /are/ arguments, things get /really/ [10.19 hairy]. Consider the statement |A f(B,C);| - this ought to be a function declaration. Why? B and C are surely classes, look at the capital letters. Um, wait, it's just a naming convention. What if they are objects? That makes the statement a constructor call. Let's look up the definition of B and C, that should give us the answer to our question.

Have you ever looked up C++ definitions (manually or using tools such as IDEs)? Check it out, it's fun. You can be sure of one thing: template specialization on integer parameters when the instantiation uses the size of a class defined using multiple inheritance and virtual functions as a parameter value doesn't make definition look-up easy.

When you get an incomprehensible error message from your C++ compiler, be sympathetic. Parsing C++ is a full-blown, industrial strength nightmare.

-END

Can one constructor of a class call another constructor of the same class to initialize the |this| object?

FAQ: No. But you can factor out the common code into a private function. In some cases you can use default parameters to "merge" constructors. Calling placement |new| inside a constructor is very bad, although it can "seem" to do the job in some cases.

FQA: You can't - one of the many good reasons to avoid constructors. And anyway, having more than one constructor may be problematic for another reason: they must all have the same name (that of the class), so in fact you're dealing with overloading, and C++ overload resolution is a huge can of worms.

If you're OK with that, you can surely use the FAQ's advice to factor out common code, unless you follow /another/ [10.6 FAQ's advice] - the one suggesting to use the ugly colon syntax for initializing member variables. You can't move these things to a function.

If you're in a mood for breaking rules and doing clever tricks, this may be the right time to look for a real problem where such skills are really needed. Breaking C++ rules by calling placement |new| is probably a bad idea - not because C++ rules are any /good/, but because they are pretty /bad/ (astonishingly and inconsistently complicated). This is not the kind of rules you can get away with breaking - your maze of hacks is doomed to collapse, and there's enough weight in C++ to bury your entire project when this happens. And anyway, why invest energy into an artificial syntactic problem when there are so many real ones out there?

-END

Is the default constructor for |Fred| always |Fred::Fred()|?

FAQ: No, the default constructor is the one that can be called without arguments - either because it takes none or because it defines default values for them.

FQA: Yep, the rule is that the default constructor is the one that can be called "by default" - that is, when the user of a class didn't specify any parameters.

Another neat thing about default constructors is that they get /generated/ "by default". For example, if the author of class |Fred| didn't write any constructors for it, a C++ compiler will automatically generate a default constructor for it. You don't see a |Fred::Fred|, but it still exists - invisible C++ functions are great for readability and debugging. The same will happen with other things, for example the /copy constructor/. If you think you can use C++ and simply avoid the features you don't like, you're in for a rude awakening: the invisible compiler-generated stuff is lethal when your class acquires resources (most frequently memory). In for a penny - in for a pound: if you want to write C++ classes, you have to learn pretty much everything about them, and there's plenty.

Where's all this code generated? At the caller's side, of course. To generate it near the rest of the class definition, the C++ compiler would have to know where that definition is, and there's no good way to tell (it may be scattered across as many source files as the author damn pleases). C++ is just like C in this respect - there's no way to narrow the search range for a definition of an entity based on its name and\/or namespace; it can be anywhere in the program. In particular, this means that the default constructor will be automatically generated at all points where a class is used, from scratch - yet another reason why C++ code compiles slowly.

And what's needed in order to generate this code? The default constructor generated by default (I hope you follow) calls the default constructors of all class members (which in turn may take auto-generation). Add a private member, and all default constructors generated at the calling code must be regenerated - yet another reason why C++ code must be [7.5 recompiled frequently].

-END

Which constructor gets called when I create an array of |Fred| objects?

FAQ: The default constructor. If there isn't any, your code won't compile. But if you use |std::vector|, you can call any constructor. And you should use |std::vector| anyway since arrays are [6.15 evil]. But sometimes you [6.16 need] them. In that case, you can initialize each element as in |Fred arr[2] = {Fred(3,4), Fred(3,4)};| if you need to call constructors other than the default. And finally you can use placement new - it will take ugly declarations and casts, you should be careful to align the storage right (which can't be done portably), and it's hard to make this exception-safe. See how evil those arrays are? Use |std::vector| - it gets all this complicated stuff right.

FQA: And all you did was asking a simple question! OK, let's start making our way through the pile of rules, exceptions, amendments and excuses.

Given syntax like |MyClass arr[5];| the compiler will generate a loop calling the default constructor of |MyClass|. Pick some time when you have a barf bag handy and look at the generated assembly code. There are two nice things: sometimes compilers will emit a loop even when it's clear that the default constructor has nothing to do; and for automatically generated default constructors, you'll get inline calls to the constructor of each member (for the latter thing you don't really need an array, a single object will do). Bottom line: your program gets bigger and bigger and you don't know why - /you/ didn't do anything.

Syntax like |std::vector<Fred> arr(5,Fred(3,4));| gets translated to 5 calls to the copy constructor (in practice - in theory other things could happen; in general, C++ is excellent in theory). This is functionally equivalent to calling |Fred(3,4)| 5 times. The FAQ doesn't mention that it's normally slower though - typically the numbers 3 and 4 must be fetched from the memory allocated for the copied object instead of being passed in registers or inlined into the assembly code.

Of course |std::vector| of a fixed size known at compile time is less efficient than a built-in array anyway. Which is one reason to prefer a built-in array. Initializing such an array with multiple |Fred(3,4)| objects will force you to replicate the initializer, and will produce the biggest possible initialization code. No, the compiler is not likely to notice that you're doing the same thing over and over again, it will repeat the same code N times. On the other hand, if your class does nothing in the constructor but has an "init function", you can call it in a loop. Another reason to avoid constructors.

The horror stories the FAQ tells you about placement new are all true. However, it doesn't mention that |std::vector| always allocates memory on the free store. And there's no standard container you can use for allocating memory on the stack, for example, so if you want one, you'll have to write it yourself. And placement new is necessary to make such containers work with C++ classes without default constructors. Yet another reason to avoid constructors.

Anyway, saying "use |std::vector| because it gets that horrible placement new stuff right" is a little strange if you consider the following assumptions, one of which must apparently hold:

`<ul>`
`<li>`C++ guys want people to build their own container classes - then why is placement new, which is required to do this right, so hard to use?`</li>`
`<li>`C++ guys don't want people to build their own container classes - then why isn't |std::vector| built into the language, so that things like aggregate initialization could work with it, and maybe we could get rid of those oh-so-evil arrays?`</li>`
`</ul>`

Maybe you can't expect more consistency from the promoters of a language than there is in that language itself.

-END

Should my constructors use "initialization lists" or "assignment"?

FAQ: Initialization lists - that's more efficient, except for built-in types (with initializers, you avoid the construction of an "empty" object and the overhead of cleaning it up at the assignment). And some things can't be initialized using assignment, like member references and const members and things without default constructors. So it's best to always use initialization lists even if you don't have to for the sake of "symmetry". There are exceptions to this rule. There's no need for an exhaustive list of them - search your feelings.

FQA: There are good reasons to avoid initialization lists:

`<ul>`
`<li>`You can't write most kinds of code in the initialization lists - no local variables to reuse results of computations, no loops... Basically there's C++ and there's this initializer land, where you must speak a crippled dialect without any reward for the effort.`</li>`
`<li>`You can't [10.3 move initializers to a common function] to reuse initialization code.`</li>`
`<li>`If you want to pass a pointer to one member to the constructor of another member, you must make sure its constructor is called first, and these constraints can get complicated.`</li>`
`<li>`To help you manage those constraints, some compilers produce annoying warnings when the order of your initializers differs from the order in which you declare the class members, even when it doesn't matter.`</li>`
`<li>`The efficiency argument is wrong for a very common case when the default constructor of a member does nothing.`</li>`
`<li>`Typically compilers attribute all code in initializer lists to the same source code line - for example, the one with the opening brace of the constructor body. When a program crashes inside an initializer, you can't easily tell which one it is using a symbolic debugger.
`<li>`Not that it's very different from the rest of C++, but the colon syntax is just plain ugly.`</li>`
`</ul>`

The trouble with initialization lists, like with any duplicate language feature, is that you /can't/ really avoid using it. For example, there are classes without default constructors, or with relatively heavy ones. So "never use initialization lists" is not a very useful rule, and the best answer, as usual, is that there's no good answer.

However, initialization lists are really less than useful, so it's probably good to avoid them unless you can't. In particular, avoiding reference and const members and having lightweight default constructors in your classes may help.

-END

Should you use the |this| pointer in the constructor?

FAQ: Some people think you can't since the object is not fully initialized, but you can if you know the rules. For example, you can always access members inside the constructor body (after the opening brace). But you can never access members of a derived class by calling virtual functions (the function call will [23.5 invoke the implementation of the class defining the constructor], not that of the derived class). Sometimes you can use a member to initialize another member in an initializer list and sometimes you can't - you must know the order in which members are initialized.

FQA: That's right - all problems and questionable scenarios come from tricky C++ things, like initialization lists and virtual function calls from constructors. If you avoid initialization lists and use plain old assignment or initialization function calls in the constructor body, you can be sure all members can be used - you have one problem solved. Use init functions instead of constructors and virtual function calls will [23.6 invoke functions of the derived class] - another problem solved.

An alternative to avoiding the dark corners of C++ is to spend time learning them. For example, you can memorize the rules defining the order of initialization, and rely on them heavily in your code. That way people who need to understand and\/or maintain your code will have to get pretty good at these things, too, so you won't end up being the only one around knowing tons of useless obscure stuff. Or they will have to ask you, which increases your weight in the organization. You win big either way, at least as long as nobody chooses the path of physical aggression to deal with the problems you create.

-END

What is the "Named Constructor Idiom"?

FAQ: It's when you have static functions ("named constructors") returning objects in your class. For example, this way you can have two "constructors" returning 2D point objects: one getting rectangular coordinates (2 |float|s), and another getting polar coordinates (also 2 |float|s). With C++ constructors you couldn't do it because they all have the same name, so that would be ambiguous overloading. And this can be as /fast/ as regular constructors! And you can use a similar technique to enforce an allocation policy, like having all objects allocated with |new|.

FQA: Three cheers! This is almost like C init functions - a step in the right direction. Namely, this way we don't have overloading problems, and we can get rid of the pesky [10.1 separation of allocation from initialization] - client code doesn't really have to [7.5 know about our private members] anymore.

The only thing left to do is to ditch the whole class thing, and use C pointers to incomplete types as object handles - that way we can actually modify private members without recompiling the calling code. Or we can use a real object-oriented language, where the problem doesn't exist in the first place.

-END

Does return-by-value mean extra copies and extra overhead?

FAQ: "Not necessarily". A truly exhausting, though not necessarily exhaustive list of examples follows, with many stories about "virtually all commercial-grade compilers" doing clever things.

FQA: Let's enumerate the possibilities using boring binary logic:

`<ul>`
`<li>`You care about performance.`</li>`
`<li>`You don't care about performance.`</li>`
`</ul>`

In the first case, "not necessarily" is not a good answer for you. You don't want your code to be littered with things like return-by-value and later wonder why your "commercial-grade" compiler emits huge and slow code in some of the performance-critical places. If performance is one of your goals, you're better off writing code in ways making it as easy as possible to predict performance, without knowing an infinite amount of details specific for each of the compilers you use for production code. And if you have experience with optimization, you've probably noticed another thing - most C++ compilers work hard on optimizing the C subset, but are pretty dumb when it comes to C++-specific parts. Compiler writers are probably happy if they can correctly /parse/ C++ code and somehow lower it to C and have the back-end optimize stuff at the C level. Basically to get performance you need C, because that's what today's optimizers are best at, and you're wasting time with C++.

If you don't care about performance, you are /also/ wasting time using C++. There are hordes of programming languages designed for managed environments, so you won't have problems coming from undefined behavior of all kinds. And the vast majority of languages are way simpler and more consistent than C++, so you'll get another huge burden off your back.

Of course our boring binary logic fails to represent the [35.10 developers] who /think/ they care about performance, although they have a very vague idea about the actual performance of their programs. Those are the people who use the von Neumann model ("you access memory using pointers which are actually indexes of individual bytes") to think about computers, and call this "the low level". They are typically less aware of things like instruction caches (which make /big/ programs /slow/), SIMD instruction sets (which can give performance gains /way beyond/ "generic" template implementations of numerical algorithms), assembly language and optimizers in general (for example, how |restrict| helps optimization but |const| [18.14 doesn't]). These people engage in lengthy discussions about complicated high-level optimizations, their ultimate goal being very generic code which can be compiled to a very efficient program by a very smart compiler, which will never exist. These people are welcome to waste as much time thinking about return-by-value optimizations as they wish, as long as it prevents them from causing actual damage.

-END

Why can't I initialize my |static| member data in my constructor's initialization list?

FAQ: Because you must define such data explicitly as in |static MyClass::g_myNum = 5;|.

FQA: Because it's meaningless. |static| members are global variables with respect to allocation and life cycle, the only difference is in the name look-up and access control. So they are instantiated and initialized once per program run. Initialization lists initialize the members of objects which are instantiated with each object, which can happen more or less times than once per program run.

One possible reason making this question frequently asked is that you can /assign/ to static variables in the body of a constructor, as in |g_numObjs++|. People trying to follow the [10.6 advice] to use the crippled C++ subset available in the initialization lists might attempt to translate this statement to initializer-like |g_numObjs(g_numObjs + 1)| or something, which doesn't work.

You can probably look at it both ways - "initializers are used to initialize things instantiated per object" and "the subset of C++ available in initialization lists makes it impossible to do almost anything".

-END

Why are classes with |static| data members getting linker errors?

FAQ: Because you must define such data explicitly as in |static MyClass::g_myNum = 5;|.

FQA: Beyond being annoying, this is quite weird. At the first glance it looks reasonable: after all, C++ is just a thick layer of syntax on top of C, but the basic simpleton mechanisms are the same. For instance, definition look-up is still done using header files holding random declarations and object files holding arbitrary definitions - each function can be declared anywhere (N times) and defined anywhere (1 time).

So the compiler can't let you define something which becomes a global variable at the C\/assembly level in a header file as in |static int g_myNum = 5;| - that way, you'd get multiple definitions (at each file where the class definition is included). Consequently, the C++ syntax is defined in a way forcing you to solve the compiler's problem by choosing a source file and stuffing the definition there (most frequently the choice is trivial since a class is implemented in a single source file, but this is a /convention/, not a rule the compiler can use to simplify definition look-up).

While this explanation doesn't make the syntax and the weird "undefined external" errors any nicer, at least it seems to make sense. Until you realize that there are /tons/ of definitions compiled to C\/assembly globals in C++ that /must/ be placed at header files. Consider [23.10 virtual function tables] and template classes. These definitions are compiled over and over again each time a header file gets included, and then the linker must throw away N-1 copies and keep one (if the copies are different because of different compiler settings and\/or preprocessor flags, it's your problem - it won't bother to check).

It turns out that C++ /can't/ be implemented on top of any linker that supports C - the linker must support the "generate N times and throw away N-1 copies" feature (or is it a documented bug?), instead of issuing a "multiple definition" error. In GNU linkers this is called "linkonce" or something. To support C++, you must add features to the linker. Too bad they didn't think of adding type-safe linkage (checking the consistency of definitions used in different object files) while they were at it.

The conclusion is that there is no technical reason whatsoever, even inside the twisted C++ universe, to make the syntax harder for the user in this case. On the other hand, there's no reason to make the syntax /easier/ either. That would just introduce inconsistency with the rest of the language.

-END

What's the "static initialization order fiasco"?

FAQ: A subtle, frequently misunderstood source of errors, which are hard to catch because they occur before |main| is called. The errors can happen when the constructor of a global object defined in |x.cpp| accesses (directly or indirectly) a global object defined in |y.cpp|. The order of initialization of these objects is undefined, so you'll see the problem in 50% of the cases (an error may be triggered by a rebuild). "It's that simple".

FQA: And it's /that/ stupid. Just look at this:

`<ul>`
`<li>`C++ doesn't define the order of initialization of global objects.`</li>`
`<li>`C++ lets you write code that depends on the order of initialization of global objects.`</li>`
`<li>`C++ doesn't have a mechanism to automatically detect these errors, neither at compile time nor at run time.`</li>`
`<li>`C++ doesn't make the slightest effort to help you debug the problem (for example, go figure in which actual order the objects were initialized).`</li>`
`</ul>`

With most duplicate language features, one can't simply say "avoid the new broken C++ features" because the language [10.6 works so hard] to get you in trouble if you do. But in this particular case it's probably a good rule. Consider the reasons to avoid instantiating global objects with non-trivial constructors (ones that do more than nothing), and instead use plain old C aggregate initialization:

`<ul>`
`<li>`You have to worry about this "fiasco" business, which is quite nasty. With C initializers, once you passed compilation and linkage, there are no problems - the linker creates a snapshot of the initial state of your global variables, and there are no failure modes.`</li>`
`<li>`You have all this initialization code before |main|, with corresponding clean-up code called after |main|. What if you want to clean up and re-initialize things /without/ exiting |main|? People calling |getenv| or accessing the command line using platform-specific tricks in code called before |main| further improve the life of other people working on the project.`</li>`
`<li>`Your program contains a huge bulk of slow initialization code. A C statement like |Point p={4,5};| gets translated to 8 bytes representing the integers 4 and 5 in the executable. A C++ statement like |Point p(4,5);| gets translated to /code/ storing 4 and 5 to |p|. What are the benefits except for getting large programs starting up slowly?`</li>`
`</ul>`

Some people believe that you need non-trivial global constructors, or else you'll have to make your user call an initialization function to work with your module. The fact is that the experienced users /prefer/ to initialize modules explicitly rather than having them autonomously kicking in, possibly crashing the program because of dependency issues, not to mention printing messages and popping up configuration dialogs. All of these implicit things tend to become quite /explicit/ on the day when you least need them to. Quoting the FAQ's favorite expression, just say no.

-END

How do I prevent the "static initialization order fiasco"?

FAQ: By using the "Construct On First Use" idiom, as in

`<pre>`
MyClass& getMyObj()
{
  static MyClass* p = new MyClass;
  return *p;
}
`</pre>`

This solution may "leak". There's another solution working around this problem, but it creates other problems.

FQA: By not instantiating global objects with constructors doing more than nothing. That prevents this and other kinds of "fiasco". The technique in the FAQ, frequently referred to as an implementation of "the singleton design pattern" (BTW, you can put quotes wherever you like in that one, for example the "singleton" "design" "pattern"), has the following problems:

`<ul>`
`<li>`As mentioned by the FAQ, it leaks memory /and possibly other resources/ (C++ people love to talk about how memory is "just one kind of resource", overlooking the fact that it accounts for 99% of "resources" actually used by a program, so special, "non-generic" things like [16.1 garbage collection] may be appropriate to manage it - but they suddenly forget all about it when it comes to this "construct on first use" business). Practitioners may find it intolerable to have these memory leaks reported by tools designed to detect leaks, even if their platform is capable of disposing the garbage left by a program automatically. People interested in a more theoretical discussion may enjoy the recommendation to violate the C++ rules regarding memory management found in a "standard practice".`</li>`
`<li>`It is slow, not to mention thread safety. When you have a plain C global initialized by a plain C explicit initialization function, accessing it is quite easy (function arguments may be faster to fetch, or they may be not). In this case, you call a function (which can be inlined - that doesn't necessarily help though) that contains a hidden |if| statement. You don't see it? Well, how do you think the clever function manages to only call |new| once? There's a global boolean (sometimes called "guard variable") which it checks each time. To access a global, you now need to access two globals. If you find it interesting, you can list the symbols of your program (using a program like |nm|), and then filter the output using a C++ name demangler (like |c++filt|). You may find lots of "guard variable of something" kind of names there.`</li>`
`</ul>`

The C++ global initialization and destruction support is broken. As usual, the "idiom" in the FAQ "solves" the problem by creating worse problems.

-END

Why doesn't the construct-on-first-use idiom use a static object instead of a static pointer?

FAQ: It solves one problem and creates another problem. Namely, you avoid the resource leak, but your program can crash because now you achieved "construct-on-first-use", but not "destroy-after-last-use", so someone can access a dead object (using |new| means "never destroy", which is at least guaranteed to be /after/ last use).

Actually there's a /third/ approach solving /both/ problems (initialization and destruction order), having "non-trivial cost". The FAQ author feels "too lazy and busy" to explain - go buy his "C++ FAQ Book" to read about it.

FQA: The FAQ is right - this variant, known as "the Meyers' singleton", is also broken. And it's probably the hardest to work around, too. At least with the |new| variant you /can/ delete the object with |delete &getMyObj();| - increasingly ugly, but it may yield a working (though unmaintainable) program. With the static variable technique, C++ records a pointer to the destructor in some global array, so you won't be able to control the order of destruction (it's always the order of construction, reversed - and you /didn't/ want to control the order of construction, you wanted it to "just work", right?).

As to other approaches - I do have enough energy and spare time to repeat a /free/ advice: use explicit initialization and clean-up functions, and realize that the initialization and destruction sequences are part of the /design/ of your modules and your program.

If it's hard to get out of the state of mind where you think initialization should somehow work out by itself, as opposed to the really interesting things your program does afterwards (the "steady state"), maybe an analogy with hardware can help. In a simplified model of synchronous hardware design, you have two "trees" of signals (basically wires) reaching almost every place in your system: the /clock/ (which synchronizes things done at the steady state), and the /reset/ (upon which all the initialization is conditioned). A common milestone in hardware design is getting the reset right. When you buy hardware, a large portion of it is devoted to initialization (which is why you can /reboot/ it and it enters a reasonable state - you can't do that with biological "computers" like the human brain).

By the way, I didn't read the C++ FAQ book (I really don't have time for a C++ FQA book at the moment, so why bother?). But I did read "Modern C++ Design", which also offers a solution. So if you buy the FAQ book and find the third "solution" and it involves having your singletons instantiated from a hairy template with a global data structure keeping "priorities" or some such and registering |atexit| callbacks which can in turn call |atexit| which detects dark areas in the C and C++ standards because nobody thought anyone would ever do that - if that's the third way, be sure that the cost is /really/ "non-trivial".

-END

How do I prevent the "|static| initialization order fiasco" for my |static| data members?

FAQ: Using the same techniques [10.14 just described], except for using static member functions instead of global functions. For some reason a long list of examples follows, as well as a discussion on performance.

FQA: There's no difference between static data members and global variables except for name look-up and access control. So you can either use the broken & slow techniques from the FAQ, or you can avoid non-trivial constructors and live happily ever after.

There's no point in having separate discussions on static data members and plain global variables. Well, except for mentioning that static data members are a brand new C++ feature, and it's particularly nice that C++ recommends to wrap its own syntax with another layer of its syntax for "safety". An alternative approach to safety is to use zero layers of C++ syntax.

-END

Do I need to worry about the "|static| initialization order fiasco" for variables of built-in\/intrinsic types?

FAQ: Yes, if you use function calls to initialize them as in |int g = f();| - that way |f| can access |g|, or you can have other dependency problems.

FQA: Exactly - and this code doesn't compile in C. We seem to have a [10.7 pretty clear picture] here, don't we? As a rule of thumb, the answer to the more general version of the question - "Do I need to worry when I use a C++ feature not available in C?" - is also "Yes".

Not that plain C is very safe, mind you. If you [10.9 don't need the performance], you can always switch to a safer, higher-level language. But at least C doesn't pretend to be very high-level, and makes less promises it can't keep (like "go ahead, use whatever code you like to initialize global variables - see how high-level our language is?").

-END

How can I handle a constructor that fails?

FAQ: Throw an exception.

FQA: Right.

Q: What do you do when a ship is on fire?`<br>`
A: Drown it. The fire will stop immediately.

Seriously, [17.10 C++ exceptions] are a leading candidate for the title "the worst way to handle run time errors ever invented". But constructors can't return values. Even though they /don't/ technically return an object - they merely initialize a chunk of memory they are passed. So they /could/ return status information despite the C\/C++ limitation of at most one return value per function. Which itself has no technical justification. This is [10.5 yet another] reason to avoid constructors that do more than nothing. It's also [10.12 yet another] illustration how [10.6 hard] it is to use only some of C++ features and avoid others ("we want classes, but we don't need exceptions" - until you want to handle an error in a constructor).

It is also notable that the C++ standard library /doesn't/ handle errors in constructors (or overloaded operators, which pose the same problem) using exceptions (for example, consider |ifstream| and |ofstream|).

-END

What is the "Named Parameter Idiom"?

FAQ: A useful application of method chaining. It works around the fact that C & C++ don't have keyword arguments, and it does that better than combining the parameters in a string or a bit mask. It works like this:

`<pre>`
File f = OpenFile("language-abuse.txt")
         .useWeirdLineBreakRules(true)
         .writeLotsOfGoryDetails(true)
         .averageNumberOfExcuses(ZILLION);
\/* a sizable implementation with two classes and friends
   and methods returning *this and what-not omitted *\/
`</pre>`

And if method calls are inlined, there's no speed overhead (but the code size may "slightly" increase - but that's a long story).

FQA: Let's have a closer look at this Named Parameter Idiocy.

`<ul>`
`<li>`The implementation in the FAQ pushes these parameters into a temporary structure, which is normally slower than argument passing.`</li>`
`<li>`And the multiple method calls, inlined or not, are no picnic either. Compare assembly code generated by |printf| and |iostream| calls if you doubt. This way you can compare your notion of "slightly" with that used by the designers of C++.`</li>`
`<li>`All ways to implement this require the author of the class to write a lot of code ultimately doing nothing. Which is OK because in theory, [13.4 each class is written once and used thousands of times]. In practice most classes keep changing forever and are used in a couple of places. Which doesn't matter as long as you only use C++ in theory where it belongs.`</li>`
`<li>`But that would be justified to an extent if it made things easier for the user. But it doesn't. Try reading the header file with the |class OpenFile| and figuring out how to open files.`</li>`
`<li>`And now that we have this |OpenFile| class, people will start storing objects of this class and passing them around. Which could be a good idea in some cases, except that the class has a stupid function-like name, further enhancing readability.`</li>`
`<li>`Or we could use a different implementation, chaining the methods of |class File| and avoiding the second class. But this way, we can't detect errors easily, because there's no point where we see all of the parameters at once, we get them one by one.`</li>`
`</ul>`

This syntactic sugar of the bitter kind raises two questions. First, why don't we have keyword arguments in C++? They are much easier to implement in a compiler than virtually any feature C++ added to C, and are way more useful, too. And second, if for some reason you have to work in C++, what's the problem with accepting the fact that it doesn't have keyword arguments, and using a structure of parameters in way at least making it /clear/ that you use a structure of parameters? For example:

`<pre>`
OpenFileParams params;
params.useNormalLineBreaks(true);
params.quitFiddlingWithSyntax(true);
File file; \/\/trivial constructor
if(!file.open("grow-up.txt",params)) {
  \/\/handle errors without the "help" of C++ exceptions
}
`</pre>`

This doesn't solve the problems with code speed & size, but at least the code of the class and the code using the class are reasonably readable and writable. And there seem to be no new problems, unless someone considers the fact that our code is now pretty close to C and we no longer rely on C++ method chaining a problem.

Abusing C++ syntax in order to cover up deficiencies of C++ syntax, thus creating real problems in attempts to solve non-problems, is a popular hobby among C++ professionals. Let's check if it makes sense by imagining that someone spent the better part of the day writing all this wrapper code doing trivial things. Let's try to help that someone explain what was accomplished to someone else, and further assume that the other someone has a mind not entirely buried in C++ quirks. "I was writing this... Um, you see, I was opening a file... I wrote this interface of 2 screens of code... And then..." Sheesh, that's embarrassing.

-END

Why am I getting an error after declaring a |Foo| object via |Foo x(Bar())|?

FAQ: This /hurts/. /Sit down/.

The "simple" explanation: this doesn't really declare an object; |Foo x = Foo(Bar());| does. The complete explanation for "those caring about their professional future": this actually declares a function named |x| returning a |Foo|; the single argument of this |x| function is of type "a function with no argument returning a |Bar|".

Don't get all excited about it. Don't "extrapolate from the obscure to the common". Don't "worship consistency". That's not "wise". The FAQ actually says all these quoted things.

FQA: Those who use computers to do any useful work are probably immune to brain-crippled syntax, because there are more painful things, like brain-crippled semantics. So sitting down is only necessary if you find it comfortable. For similar reasons, don't worry about your professional future too much if this looks boring and stupid and you don't feel like understanding it. It really is what you think it is, and programming is not supposed to be about this kind of thing. If someone rejects you in an [6.14 interview] because you don't know the answer to a question like this, you are lucky - you've just escaped a horrible working environment.

Anyway, if for some reason you /are/ curious to find out why this happens, it turns out the FAQ has no answers, it just presents it as an arbitrary rule. It doesn't help to understand anything. The statement is ambiguous - you can read it both as a constructor call and a declaration of a peculiar function. How does the compiler know? Let's try to see.

Apparently the key problem is that in order to tell a function declaration from a constructor call, you need to know whether the things in the parentheses are objects or types. This makes parsing |A f(B);| [10.2 non-trivial]. In our example, things are complicated by the fact that |Bar()| itself presents /the very same problem/ - is it a function declaration or a constructor call? Worse, this time the darn thing accepts no arguments, so you can't use them to figure it out. Well, C++ has an arbitrary rule to help the compiler (but not necessarily the user): things with empty parentheses are function declarations, unless that's entirely impossible (list of special cases follows). That's why |A x();| declares a function but |A x;| defines an object. And that's why |Bar()| is interpreted as a function declaration, which means that it's an argument type, not an object, so the whole statement is actually a function declaration. I think.

The problem with |Foo| and |Bar| is that the C++ grammar is FUBAR. In a language designed in a more orderly way (which is most of them), there are no such ambiguities. A relatively simple way to make sure there are none is to use a formal grammar specification and feed it to a program that generates a parser for the language, checking the consistency of the grammar on the way. |yacc\/bison| is one mature program of this kind; there are newer ones with more features, which can represent more complicated grammars (but AFAIK no generic tool is capable of representing the extremely complicated, inconsistent and actually undecidable C++ grammar).

It could help the users if the people promoting C++ realized that the consistency of a grammar is not something you "worship", but a technical property which is far easier to achieve than it is to deal with the consequences of not having it. This example is just one drop in the ocean of such problems. The complexity of the C++ grammar guarantees that compiler error messages will remain cryptic, debuggers will stay ignorant, and IDEs will be unhelpful compared to those available for other languages forever.

-END


================================================
FILE: defective.fqa
================================================
Defective C++
{}
This page summarizes the major defects of the C++ programming language
(listing all minor quirks would take eternity). To be fair, some of the items /by themselves/
could be design choices, not bugs. For example, a programming language doesn't have to provide garbage collection.
It's the /combination/ of the things that makes them /all/ problematic.
For example, the lack of garbage collection makes C++ exceptions and operator overloading inherently defective. Therefore, the problems are not listed in the order of "importance"
(which is subjective anyway - different people are hit the hardest by different problems).
Instead, most defects are followed by one of their complementary defects, so that when a defect causes
a problem, the next defect in the list makes it worse.
`<!-- h2toc -->`

`<h2>No compile time encapsulation</h2>`

In naturally written C++ code, changing the private members of a class requires [7.4 recompilation] of
the code using the class. When the class is used to instantiate member objects of other classes,
the rule is of course applied recursively.

This makes C++ interfaces very unstable - a change
invisible at the interface level still requires to rebuild the calling code, which can be
very problematic when that code is not controlled by whoever makes the change.
So shipping C++ interfaces to customers can be [6.3 a bad idea].

Well, at least when all relevant code is controlled by the same team of people, the only problem is the frequent
rebuilds of large parts of it. This wouldn't be too bad by itself with almost any language,
but C++ has...

`<h2>Outstandingly complicated grammar</h2>`

"Outstandingly" should be interpreted literally, because /all popular languages/ have [http://en.wikipedia.org/wiki/Context-free_grammar context-free]
(or "nearly" context-free) grammars, while C++ has [http://en.wikipedia.org/wiki/Undecidability undecidable] grammar.
If you like compilers
and parsers, you probably know what this means. If you're not into this kind of thing, there's a
[10.19 simple example] showing the problem with parsing C++: is |AA BB(CC);| an object definition
or a function declaration? It turns out that the answer depends heavily on the code /before/ the statement -
the "context". This shows (on an intuitive level) that the C++ grammar is quite context-sensitive.

In practice, this means three things. First, C++ compiles slowly
(the complexity takes time to deal with). Second, when it doesn't compile,
the error messages are frequently incomprehensible
(the smallest error which a human reader wouldn't notice completely confuses the compiler).
 And three, parsing C++ right is very hard, so different compilers will interpret
 it differently, and tools like debuggers and IDEs periodically get awfully confused.

And /slow compilation/ interacts badly with /frequent recompilation/. The latter is caused
 by the lack of encapsulation mentioned above, and the problem is amplified by the fact
 that C++ has...

`<h2>No way to locate definitions</h2>`

OK, so before we can parse |AA BB(CC);|, we need to find out whether |CC| is defined as an object or a type.
 So let's locate the definition of |CC| and move on, right?

This would work in most modern languages, in which |CC| is either defined in the same module
(so we've already compiled it), or it is imported from another module (so either we've already compiled it, too,
 or this must be the first time we bump into that module - so let's compile it now, /once/, but of course /not/
 the next time we'll need it). So to compile a program, we need to compile each module, once,
no matter how many times each module is used.

In C++, things are [23.10 different] - there are no modules. There are /files/, each of which can contain many
 different definitions or just small parts of definitions, and there's /no way/ to tell in which
 files |CC| is defined, or which files must be parsed in order to "understand" its definition.
 So who is responsible to arrange all those files into a sensible string of C++ code?
 /You/, of course! In each compiled file, you |#include| a bunch of header files
 (which themselves include other files); the |#include| directive basically issues
 a copy-and-paste operation to the C preprocessor, inherited by C++ without changes.
 The compiler then parses the result of all those copy-and-paste operations. So to compile a program,
 we need to compile each file /the number of times it is used in other files/.

This causes two problems. First, it multiplies the long time it takes to compile C++ code
 by the number of times it's used in a program. Second, the only way to figure out what /should/ be recompiled after a change to the code is to
 check which of the |#include| files have been changed since the last build. The set of files to rebuild generated by this
 inspection is usually a superset of the files that /really/ must be recompiled according to the
 C++ rules of dependencies between definitions. That's because most files |#include| definitions
 they don't really need, since people can't spend all their time removing redundant inclusions.

Some compilers support "precompiled headers" - saving the result of the parsing of "popular"
 header files to some binary file and quickly loading it instead of recompiling from scratch.
 However, this only works well with definitions that almost never change, typically third-party libraries.

And now that you've waited all that time until your code base recompiles, it's time to run and test the program,
 which is when the next problem kicks in.

`<h2>No run time encapsulation</h2>`

Programming languages have rules defining "valid" programs - for example, a valid program shouldn't
 divide by zero or access the 7th element of an array of length 5. A valid program isn't necessarily correct
 (for example, it can delete a file when all you asked was to move it). However, an invalid program is necessarily
 incorrect (there is no 7th element in the 5-element array). The question is, what happens when an
 invalid program demonstrates its invalidity by performing a meaningless operation?

 If the answer is something like "an exception is raised", your program runs in a managed environment.
 If the answer is "anything can happen", your program runs somewhere else. In particular, C and C++
 are not designed to run in managed environments (think about pointer casts), and while in theory
 they could run there, in practice all of them run elsewhere.

So what happens in a C++ program with the 5-element array? Most frequently, you access something
 at the address that /would/ contain the 7th element, but since there isn't any, it contains something
 else, which just happens to be located there. Sometimes you can tell from the source code what that is,
 and sometimes you can't. Anyway, you're /really/ lucky if the program crashes; because if it keeps
 running, you'll have hard time understanding why it ends up crashing or misbehaving /later/.
 If it doesn't scare you (you debugged a couple of buffer overflows and feel confident), wait until you get to many megabytes
 of machine code and many months of execution time. That's when the real fun starts.

Now, the ability of a piece of code to modify a random object when in fact it tries to access
 an unrelated array indicates that [7.2 C++ has no run time encapsulation]. Since it doesn't
 have compile time encapsulation, either, one can wonder why it calls itself object-oriented. Two
 possible answers are warped perspective and marketing
 (these aren't mutually exclusive).

But if we leave the claims about being object-oriented aside, the fact that a language runs
  in unmanaged environments can't really be called a "bug". That's because managed environments
  check things at run time to prevent illegal operations, which translates to a certain (though frequently overestimated)
  performance penalty. So when performance isn't that important, a managed environment is the way to go.
  But when it's critical, you just have to deal
  with the difficulties in debugging. However, C++ (compared to C, for example) makes /that/ much harder that it already has to be, because there are...

`<h2>No binary implementation rules</h2>`

When an invalid program finally crashes (or enters an infinite loop, or goes to sleep forever), what you're left
  with is basically the binary snapshot of its state (a common name for it is a "core dump"). You have to make sense of it in order to find the
  bug. Sometimes a debugger will show you the call stack at the point of crash; frequently that information is
  overwritten by garbage. Other things which can help the debugger figure things out may
  be overwritten, too.

Now, figuring out the meaning of partially corrupted memory snapshots is definitely not the most pleasant way to spend one's
  time. But with unmanaged environments you /have/ to do it and it /can/ be done, /if/ you know how your
  source code maps to binary objects and code. Too bad that with C++, there's a ton of these rules and
  each compiler uses different ones. Think about exception handling or various kinds of inheritance or
  virtual functions or the layout of standard library containers. In C, there's no standard binary
  language implementation rules, either, but it's an order of magnitude simpler and in practice compilers
  use the same rules. Another reason making C++ code hard to debug is the above-mentioned complicated grammar,
  since debuggers frequently can't deal with many language features
  (place breakpoints in templates, parse pointer casting commands in data display windows, etc.).

The lack of a standard ABI (application binary interface) has another consequence - it makes shipping
  C++ interfaces to other teams \/ customers impractical since the user code won't work unless it's compiled
  with the same tools and build options. We've already seen another source of this problem - the instability
  of binary interfaces due to the lack of compile time encapsulation.

The two problems - with debugging C++ code and with using C++ interfaces - don't show up until your project
  grows complicated in terms of code and \/ or human interactions, that is, until it's too late.
  But wait, couldn't you deal with both problems programmatically? You could generate C or other
  wrappers for C++ interfaces /and/ write programs automatically shoveling through core dumps and deciphering
  the non-corrupted parts, using something called reflection.
  Well, actually, you couldn't, not in a reasonable amount of time - there's...

`<h2>No reflection</h2>`

It is impossible to programmatically iterate over the methods or the attributes or the base classes of a class in a
  portable way defined by the C++ standard. Likewise, it is impossible to programmatically determine the type of an object
  (for dynamically allocated objects, this can be justified to an extent by performance penalties of RTTI, but
   not for statically allocated globals, and if you could /start/ at the globals, you could decipher lots
   of memory pointed by them). Features of this sort - when a program can access the structure of programs,
in particular, its own structure - are collectively called reflection, and C++ doesn't have it.

As mentioned above, this makes generating wrappers for C++ classes and shoveling through memory snapshots a pain,
  but that's a small fraction of the things C++ programmers are missing due to this single issue.
Wrappers can be useful not only to work around the problem of shipping C++ interfaces - you could automatically handle things
  like remote procedure calls, logging method invocations, etc. A very common application of reflection is
  [15.14 serialization] - converting objects to byte sequences and vice versa. With reflection, you can
  handle it for all types of objects with the same code - you just iterate over the attributes of compound objects,
  and only need special cases for the basic types. In C++, you must maintain serialization-related code
  and\/or data structures for every class involved.

But perhaps we could deal with /this/ problem programmatically then? After all, debuggers do manage
  to display objects somehow - the debug information, emitted in the format supported by your tool chain,
  describes the members of classes and their offsets from the object base pointer and all that sort of meta-data.
  If we're stuck with C++, perhaps we could parse this information and thus have non-standard, but working reflection?
  Several things make this pretty hard - not all compilers can produce debug information /and/
  optimize the program aggressively enough for a release build, 
  not all debug information formats are documented, and then in C++, we have a...

`<h2>Very complicated type system</h2>`

In C++, we have standard and compiler-specific built-in types, structures, enumerations, unions, classes with single,
  multiple, virtual and non-virtual inheritance, |const| and |volatile| qualifiers, pointers, references and arrays,
  |typedef|s, global and member functions and function pointers, and /templates/, which can have specializations on (again) /types/ (or integral constants),
  and you can "partially specialize" templates by /pattern matching their type structure/
  (for example, have a specialization for |std::vector<MySillyTemplate<T> >| for arbitrary values of |T|), and each template can have base classes
  (in particular, it can be /derived from its own instantiations recursively/, which is a /well-known practice documented
   in books/), and inner |typedef|s, and... We have lots of kinds of types.

Naturally, representing the types used in a C++ program, say, in debug information, is not an easy task.
  A trivial yet annoying manifestation of this problem is the expansion of |typedef|s done by debuggers when they show
  objects (and compilers when they produce error messages - another reason why these are so cryptic). You may think it's a
|StringToStringMap|, but only until the tools enlighten you - it's actually more of a...

@
\/\/ don't read this, it's impossible. just count the lines
std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> >
  >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > > > >
@

But wait, there's more! C++ supports a wide variety of explicit and implicit /type conversions/, so now we
   have a nice set of rules describing the cartesian product of all those types, specifically, how conversion should
   be handled for each pair of types. For example, if your function accepts |const std::vector<const char*>&|
   (which is supposed to mean "a reference to an immutable vector of pointers to immutable built-in strings"), and I have
   a |std::vector<char*>| object ("a mutable vector of mutable built-in strings"), then
   [18.1 I can't pass it to your function] because the types aren't convertible.
    You /have/ to admit that it /doesn't make any sense/, because your function guarantees
    that it won't change anything, and I guarantee that I don't even mind having anything changed,
    and still the C++ type system gets in the way and the only sane workaround is to /copy the vector/.
    And this is an /extremely simple/ example - no [25.13 virtual inheritance], no user-defined conversion operators, etc.

But conversion rules by themselves are still not the worst problem with the complicated type system. The worst problem is the...

`<h2>Very complicated type-based binding rules</h2>`

Types lie at the core of the C++ /binding rules/. "Binding" means "finding the program entity
    corresponding to a name mentioned in the code".
When the C++ compiler compiles something like |f(a,b)| (or even |a+b|), it relies on the
   argument types to figure out which version of |f| (or |operator+|) to call. This includes
    overload resolution (is it |f(int,int)| or |f(int,double)|?), the handling of function template specializations
    (is it |template<class T> void f(vector<T>&,int)| or |template<class T> void f(T,double)|?),
    and the argument-dependent lookup (ADL) in order to figure out the namespace
    (is it |A::f| or |B::f|?).

When the compiler "succeeds" (translates source code to object code), it doesn't mean that /you/ are equally successful
    (that is, you think |a+b| called what the compiler thought it called). When the compiler "fails"
    (translates source code to error messages), most humans also fail
    (to understand these error messages; multiple screens listing all available overloads
     of things like |operator<<| are [15.1 less than helpful]). By the way, the C++ FAQ 
    has very few items related to the [35.11 unbelievably complicated
     static binding], like
  overload resolution or ADL or template specialization. Presumably people get too depressed to ask any questions
and silently give up.

In short, the complicated type system interacts very badly with /overloading/ - having multiple
    functions with the same name and having the compiler figure out which of them to use
    based on the argument types
(don't confuse it with /overriding/ - |virtual| functions, though very far from perfect, do follow rules
 [20.1 quite sane] by C++ standards). And probably the worst kind of overloading is...

`<h2>Defective operator overloading</h2>`                 

C++ [13.1 operator overloading] has all the problems of C++ function overloading (incomprehensible overload resolution rules),
and then some. For example, overloaded operators have to return their results by value - naively returning references
to objects allocated with |new| would cause temporary objects to "leak" when code like |a+b+c| is evaluated. That's
     because C++ doesn't have [16.1 garbage collection], since that, folks, is inefficient. Much better to have
     your code copy massive temporary objects and hope to have them optimized out by our friend the clever compiler.
     Which, of course,
[10.9 won't happen] any time soon.

Like several other features in C++, operator overloading is not necessarily a bad thing /by itself/ - it just happens to interact really badly
 with other things C++. The lack of automatic memory management is one thing making operator overloading less than useful. Another such thing is...
                        
`<h2>Defective exceptions</h2>`
                        
Consider error handling in an overloaded operator or a [17.2 constructor]. You can't use the return value, and setting\/reading error
 flags may be quite cumbersome. How about throwing an exception?

This could be a good idea in some cases if [17.1 C++ exceptions] were any good. They aren't, and can't be - as usual, because of another
 C++ "feature", the oh-so-efficient manual memory management. If we use exceptions, we have to write exception-safe code
 - code which frees all resources when the control is transferred from the point of failure (|throw|) to the point
 where explicit error handling is done (|catch|). And the vast majority of "resources" happens to be /memory/,
 which is managed manually in C++. To solve this, you are supposed to use [17.4 RAII], meaning that all pointers have to be "smart"
 (be wrapped in classes freeing the memory in the destructor, and then you have to design their copying semantics, and...).
 Exception safe C++ code is almost infeasible to achieve in a non-trivial program.

 Of course, C++ exceptions have other flaws, following from /still other/ C++ misfeatures. For example, the above-mentioned lack
 of reflection in the special case of exceptions means that when you catch an exception, you
 [17.7 can't] get the call stack
 describing the context where it was thrown. This means that debugging illegal pointer dereferencing may be easier
 than figuring out why an exception was thrown, since a debugger /will/ list the call stack in many cases of the former.

At the bottom line, |throw\/catch| are about as useful as |longjmp\/setjmp|
(BTW, the former typically runs faster, but it's mere /existence/ makes /the rest of the code/ run slower, which is almost [17.1 never] acknowledged by C++ aficionados).
So we have two features, each with its own flaws, and no interoperability between them. This is true
 for the vast majority of C++ features - most are...

`<h2>Duplicate facilities</h2>`

If you need an [10.5 array] in C++, you can use a C-like |T arr[]| or a C++ |std::vector<T>| or any of the array classes written
 before |std::vector| appeared in the C++ standard. If you need a [13.6 string], use |char*| or |std::string| or
 any of the pre-standard string classes. If you need to take [8.6 the address of an object],
 you can use a C-like pointer, |T*|, or a C++ reference, |T&|. If you need to [10.12 initialize] an object,
 use C-like aggregate initialization or C++ constructors. If you need to [15.1 print] something, you can
 use a C-like |printf| call or a C++ |iostream| call. If you need to [35.1 generate] many similar definitions
 with some parameters specifying the differences between them, you can use C-like macros or C++ templates. And so on.

Of course you can do the same thing in many ways in almost any language. But the C++ feature duplication is quite special.
 First, the many ways to do the same thing are usually not purely syntactic options directly supported by the compiler -
 you can compute |a+b| with |a-b*-1|, but that's different from having |T*| and |T&| in the same language. Second,
 you probably noticed a pattern - C++ adds features duplicating functionality already in C. This is bad by itself,
 because the features don't interoperate well
 (you can't |printf| to an |iostream| and vice versa, code mixing |std::string| and |char*| is [13.3 littered] with casts
  and calls to |std::string::c_str|, etc.). This is made even worse by the /pretty amazing/ fact that the new C++
 features are actually /inferior/ to the old C ones in many aspects.

And the best part is that C++ devotees /dare/ to refer to the C features as
 [6.15 evil], and frequently will actually resort to finger pointing and name calling when someone uses them in C++ code
 (not to mention using plain C)! And /at the same time/ they ([6.11 falsely]) claim that C++ is compatible with C and
 it's one of its strengths (why, if C is so evil?). The [6.2 real] reason to leave the C syntax in C++ was
 of course marketing - there's absolutely NO technical reason to /parse C-like syntax/ in order to
 /work with existing C code/ since that code can be compiled separately. For example, mixing C and [http://www.digitalmars.com/d/ the
 D programming language] isn't harder than [32.1 mixing C and C++]. D is a good example since its stated goals are similar
 to those of C++, but almost all other popular languages have ways to work with C code.

So IMO all that old syntax was kept for strictly commercial purposes - to market the language to non-technical
 managers or programmers who should have known better and didn't understand the difference between "syntax" and "compatibility with existing code" and
 simply asked whether the old code will compile with this new compiler. Or maybe they thought it would be easier
 to learn a pile of new syntax when you also have the (smaller) pile of old syntax than when you have just the new syntax.
Either way, C++ got wide-spread by exploiting misconceptions.
 
Well, it doesn't matter anymore why they kept the old stuff. What matters is that the new stuff isn't really new, either - it's obsessively
 built in ways exposing the C infrastructure underneath it. And /that/ is purely a wrong design decision, made
 without an axe to grind. For example, in C++ there's...

`<h2>No high-level built-in types</h2>`

C is a pretty low-level language. Its atomic types are supposed to fit into machine registers
 (usually one, sometimes two of them). The compound types are designed to occupy a flat chunk of memory
 with of a size known at compile time.

 This design has its virtues. It makes it relatively easy to estimate the performance & resource consumption of code.
 And when you have hard-to-catch low-level bugs, which sooner or later happens in unmanaged environments, having
 a relatively simple correspondence between source code definitions and machine memory helps to debug the problem.
 However, in a high-level language, which is supposed to be used when the development-time-cost \/ execution-time-cost ratio
 is high, you need things like resizable arrays, key-value mappings, integers that don't overflow and other
 such gadgets. Emulating these in a low-level language is possible, but is invariably painful since the tools
 don't understand the core types of your program.

C++ doesn't add any built-in types to C /[corr.2 (correction)]/. All higher-level types must be implemented as user-defined classes and templates,
 and this is when the defects of C++ classes and templates manifest themselves in their full glory.
 The lack of syntactic support for higher-level types
 (you can't initialize |std::vector| with |{1,2,3}| or initialize an |std::map| with something like |{"a":1,"b":2}|
  or have large integer constants like |3453485348545459347376|) is the small part of the problem.
 Cryptic multi-line or /multi-screen/ [35.17 compiler error messages],
 debuggers that can't display the standard C++ types and [35.12 slow build times] unheard of anywhere outside of the C++ world
 are the larger part of the problem. For example, here's a simple piece of code using the C++ standard library followed by an error message
 produced from it by gcc 4.2.0. Quiz: what's the problem?

@
\/\/ the code
typedef std::map<std::string,std::string> StringToStringMap;
void print(const StringToStringMap& dict) {
  for(StringToStringMap::iterator p=dict.begin(); p!=dict.end(); ++p) {
    std::cout << p->first << " -> " << p->second << std::endl;
  }
}
\/\/ the error message
test.cpp: In function 'void print(const StringToStringMap&)':
test.cpp:8: error: conversion from
'std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > >' to non-scalar type
'std::_Rb_tree_iterator<std::pair<const std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > >' requested
@

The decision to avoid new built-in types yields other problems, such as the [17.6 ability] to throw anything, but
 without the ability to /catch/ it later. |class Exception|, a built-in base class for all exception classes treated specially by the compiler,
 could solve this problem with C++ exceptions (but not others). However, the most costly problem with having no
 new high-level built-in types is probably the lack of easy-to-use containers. But to have those, we need more
 than just new built-in types and syntax in the C++ compiler. Complicated data structures can't be manipulated
 easily when you only have...

`<h2>Manual memory management</h2>`

Similarly to low-level built-in types, C++ manual memory management is inherited from C without changes
 (but with the mandatory addition of duplicate syntax - |new\/delete|, which normally call |malloc\/free|
  but don't [16.5 have to] do that, and of course can be [11.10 overloaded]).

Similarly to the case with low-level built-in types, what makes sense for a low-level language doesn't work
  when you add higher-level features. Manual memory management is incompatible with features such as [17.1 exceptions] & [13.1 operator overloading],
  and makes working with non-trivial data structures very hard, since you have to worry about the life cycles
  of objects so they won't leak or die while someone still needs them.

  The most common solution is [11.1 copying] -
  since it's dangerous to point to an object which can die before we're done with it, make yourself a copy
  and become an "owner" of that copy to control its life cycle. An "owner" is a C++ concept not represented
  in its syntax; an "owner" is the object that is responsible to deallocate a dynamically allocated chunk
  of memory or some other resource. The standard practice in C++ is to assign each "resource" (a fancy name for memory, most of the time)
to an owner object, which is supposed to prevent resource leaks.
  What it doesn't prevent is access to dead objects; we have copying for that.
Which is slow and doesn't work when you need many pointers to /the same/ object
  (for example, when you want other modules to see your modifications to the object).

An alternative solution to copying is using "smart" pointer classes, which could [16.26 emulate] automatic memory management
   by maintaining [16.22 reference counts] or what-not. To implement the pointer classes for the many different types
  in your program, you're encouraged to use...

`<h2>Defective metaprogramming facilities</h2>`

There are roughly two kinds of metaprogramming: code that generates other code and code that processes other code.
  The second kind is practically impossible to do with C++ code - you can't reliably process source code due to the extremely
  complicated grammar and you can't portably process compiled code because there's no reflection. So this section
  is about the first kind - code generation.

You can generate C++ code from within a C++ program using C macros and C++ templates. If you use macros, you risk
  getting [6.15 clubbed to death] by C++ fanatics. Their irrational behavior left aside, these people do have a point -
  C macros are pretty lame. Too bad templates are probably even worse. They are
  [35.1 limited in ways macros aren't] (however, the opposite is also true). They [35.12 compile forever].
   Being the only way to do metaprogramming, they are routinely [35.2 abused] to do things they weren't designed for.
   And they are a
   [35.16 rats' nest] of bizarre syntactic problems.

That wouldn't necessarily be so bad if C++ didn't /rely/ on metaprogramming for doing essential programming tasks.
One reason C++ has to do so is that in C++, the common practice is to use static binding (overload resolution, etc.)
    to implement polymorphism, not dynamic binding. So you can't take an arbitrary object at run time and print it,
    but in many programs you /can/ take an arbitrary /type/ at compile time and print objects of this type. Here's
    one common (and broken) application of metaprogramming - the ultimate purpose is to be able to print arbitrary
    object /at run time/:

@
\/\/ an abstract base class wrapping objects of arbitrary types.
\/\/ there can be several such classes in one large project
struct Obj {
  virtual void print(std::ostream&) const = 0;
};
template<class T> struct ObjImpl : Obj {
  T wrapped;
  virtual void print(std::ostream& out) const { out << wrapped; }
};
\/\/ now we can wrap int objects with ObjImpl<int> and string objects
\/\/ with ObjImpl<std::string>, store them in the same collection of Obj*
\/\/ and print the entire collection using dynamic polymorphism:
void print_them(const std::vector<Obj*>& objects) {
  for(int i=0; i<(int)objects.size(); ++i) {
    objects[i]->print(std::cout); \/\/ prints wrapped ints, strings, etc.
    std::cout << std::endl;
  }
}
@

Typically there are 10 more layers of syntax involved, but you get the idea. This sort of code doesn't really work
    because it requires all relevant overloads of |operator<<| to be visible /before/ the point where |ObjImpl|
    is defined, and that doesn't happen unless you routinely sort your |#include| directives according to that rule.
    Some compilers will compile the code correctly with the rule violated, some will complain, some will silently generate
    wrong code.
    
But the most basic reason to rely on the poor C++ metaprogramming features for everyday tasks
    is the above-mentioned ideological decision to avoid adding high-level built-in types. For example, templates
    are at the core of the...

`<h2>Unhelpful standard library</h2>`

Most things defined by the C++ standard library are templates, and relatively sophisticated ones, causing
    the users to deal with quite sophisticated manifestations of the problems with templates, discussed above.
    In particular, a special program called [http://www.bdsoft.com/tools/stlfilt.html STLFilt] exists
    for /decrypting the error messages/ related to the C++ standard library.
    Too bad it doesn't patch the debug information in a similar way.

Another problem with the standard library is all the functionality that's not there.
   A large part of the library duplicates the functionality from the C standard library (which is itself available to C++ programs, too).
The main new thing is containers
("algorithms" like |max| and |adjacent_difference| don't count as [7.3 "functionality"] in my book). The standard library
 doesn't support listing directories, opening GUI windows or network sockets. You may think that's because these things
 are non-portable. Well, the standard library doesn't have matrices or regular expressions, either.

And when you use the standard library in your code, one reason it compiles slowly to a large binary image is
 that the library extensively uses the...

`<h2>Defective inlining</h2>`

First, let's define the terms.

"Inlining" in the context of compilers refers to a technique for /implementing/ function calls
 (instead of generating a sequence calling the implementation of the function, the compiler integrates that implementation
  at the point where the call is made). [9.1 "Inlining" in the context of C++] refers to a way to /define/ functions in order to /enable/
 (as opposed to "force") such implementation of the calls to the function (the decision whether to actually use the opportunity is made by the compiler).

Now, the major problem with this C++ way to enable inlining is that you have to place the definition of the function
 in header files, and have it recompiled over and over again from source. This doesn't have to be that way - the
 recompilation from source can be avoided by having higher-level object file formats
 (the way it's done in [http://llvm.org LLVM] and [http://gcc.gnu.org gcc starting from version 4]). This approach -
  link-time inlining - is one aspect of "whole program optimization" supported by modern compilers. But the recompilation
  from source could also be avoided in simpler ways if C++ had a way to locate definitions instead of recompiling them, which,
  as we've seen, it hasn't.

The crude support for inlining, designed with a traditional implementation of a C tool chain in mind,
  wouldn't be as bad if it wasn't /used all the time/. People define large functions inline for two reasons.
  [10.9 Some] of them "care" (emotionally) about performance, but never actually measure it, and someone told them
  that inlining speeds things up, and forgot to [9.3 tell] them how it can slow them down. Another reason is that
  it's simply /annoying/ to define functions non-inline, since that way, you place the full function definition
  in a |.cpp| file and its prototype in a |.h| file. So you write the prototype twice, /with small changes/
  (for example, if a class method returns an object of a type itself defined in the class, you'll need an extra namespace
   qualification in the |.cpp| file since you're now /outside of the namespace of the class/). Much easier
   to just have the body written right in the |.h| file, making the code compile more slowly and recompile
   more frequently (changing the function body will trigger a recompilation).

And you don't even need to actually /write/ any inline functions to get most of their benefits! A large subset
   of the inline functions of a program are...

`<h2>`Implicitly called & generated functions`</h2>`

Here's a common "design pattern" in C++ code. You have a huge class.
   Sometimes there's a single pseudo-global object of this class.
   In that case, you get all the /drawbacks/ of global variables because everybody has a pointer to the
 thing and modifies it and expects others to see the changes. But you get no /benefits /of global variables since
 the thing is allocated on the stack and when your program crashes with a buffer overflow, you can't
 find the object in a debugger. And at other times there are many of these objects,
   typically kept in a pseudo-global collection.

Anyway, this huge class has no constructors, no destructor and no |operator=|. Of course people create
   and destroy the objects, and sometimes even assign to them. How is this handled by the compiler?

This is handled by the compiler by generating a /gigantic/ pile of code at the point where it would
   call the user-defined functions with magic names (such as |operator=|) if there were any. When you /crash/ somewhere
   at that point, you get to see /kilobytes/ of assembly code in the debugger, all generated
   from /the same source code line/. You can then try and figure out which variable didn't like
   being assigned to, by guessing where the class member offsets are in the assembly listing and looking
   for symbolic names of the members corresponding to them. Or you can try and guess who forgot
   all about the fact that these objects were assigned to using the "default" |operator=|
   and added something like built-in pointer members to the class. Because that wouldn't work,
   and could have caused the problem.

Implicit generation of functions is problematic because it slows compilation down, inflates
   the program binaries and gets in the way when you debug. But the problem with /implicitly calling/ functions
   (whether or not they were /implicitly generated/) is arguably even worse.

When you see code like |a=f(b,c)| (or even |a=b+c|, thanks to operator overloading), you don't
   know whether the objects are passed by reference or by value (see [8.6 "information hiding"]). In the latter case, the objects are
   copied with implicitly called functions; in the former case, that's possible, too, if implicit type
   conversions were involved. Which means that you don't really understand what the program does
   unless you know the relevant information about the relevant overloads and types.
   And by the way, the fact that you can't see whether the object is passed by reference or by value
   at the point of call is /another/ example of implicit stuff happening in C++.

One more problem with automatically generated functions (such as constructors and destructors)
   is that they must be /regenerated/ when you add private members to a class, so changing
   the private parts of a class triggers recompilation... Which brings us back to square 1.
   


================================================
FILE: disclaimers.fqa
================================================
Disclaimers and excuses
{}
This page lists a bunch of disclaimers and excuses, in no particular order.

I know C++ better than it deserves, but I could make errors. If you find some, I'd be grateful if you told me.

The same goes for English, except for the "better than it deserves" part.

It is technically possible to write "good" code in C++, for many reasonable definitions of "good".
Choosing [25.3 not to work on a project] just because it uses C++ may be a dumb decision.
Criticizing software just because it's written in C++ is not very bright, either.

Throughout the FQA, there are [6.2 places] where the text [7.5 passionately argues] with people
vaguely defined as "C++ promoters" or the like. This is supposed to be purely rhetorical.
I can't and shouldn't judge the intentions, the competence or any other personal traits of real people somehow
related to C++.

It's the same with the criticism of "C++ users". For the record,
some of my knowledge of C++ was obtained through rather time consuming experimentation, performed
under the wrong assumption that it /has/ to pay off when I finally plug all the holes.
The purpose of this confession is to
show one reason I have to avoid personally offending people desperately trying to make C++ do something useful.

The FQA's answers to the "frequently asked questions" typically argue with the FAQ's answers.
This only has a chance to be interesting when the FAQ's position represents the opinions
of a large subset of the C++ devotees out there. Which is probably not always true.

I couldn't directly quote
the FAQ's answers in order to argue with them (Marshall Cline, the FAQ author, didn't respond to my request regarding this).
So I summarized the answers instead.
My summaries had to be biased no matter what I did, so I made the bias fairly explicit.
I hope the links to
the original compensate for the loss of information, although I did try to make most
of my summaries informative, not just biased. I also recommend to check out the original
answers - some of them can be quite entertaining, and some may do a great job convincing
you that /something is deeply wrong with the C++ community/.
I quoted the questions themselves verbatim, under the assumption that they are not
copyrighted work of any specific person, since they are, after all, asked frequently.

The FQA doesn't show examples of code written in programming languages other than C and C++.
I believe that for any new project, there's a much better language than C++. Moreover,
that language can be virtually any of the languages popular today if it's compatible with
the basic requirements imposed by the problem domain. I didn't want to put any emphasis
on a particular alternative to C++, because choosing one is largely a matter of taste;
writing and testing examples in many languages felt like too much work.
I singled out C as the single explicitly mentioned alternative to C++ because I find
that its superiority to C++ is pretty funny considering the circumstances.
However, in many cases I mention "other languages" which have things C doesn't have
(safe execution, reflection, etc.);
typically, I refer to Python\/Ruby\/..., Java\/C#\/..., and Lisp\/Scheme\/... families
of languages in those places. All these languages run in managed environments; if you
choose to sacrifice safety for performance, check out the D language.

Several FAQ sections are omitted. Some of those don't talk about C++ features, some repeat stuff mentioned
in other sections, and some deal with things discussing which wouldn't add anything new to the FQA
(for example, |private| inheritance - the FQA talks quite a lot about [7.4 C++ access control] already).
On the other hand, the FQA does repeat itself in many places.

The opinions in the FQA are my own, and are not supposed to represent the opinions of
anybody else.

Finally, the following sentence is only here to attract a certain set of search engine
users interested in our subject, and should not be interpreted as the summary of my point of view
on the complicated issues discussed:

C++ SUCKS


================================================
FILE: dtor.fqa
================================================
Destructors
{'section':11,'faq-page':'dtors.html'}
Destructors are one of the many pieces of the puzzle that is the C++ [16.1 memory management].

What's the deal with destructors?

FAQ: A destructor, abbreviated "dtor", is a "you're about to die" member function. It is used to release
resources, for example, semaphores. Most frequently the resource is memory allocated by |new|;
the destructor frees it with |delete|.

FQA: Yep, [16.1 C++ has no garbage collection], which makes "memory" a manually managed "resource". Die-hard C++ programmers
firmly believe that [17.4 RAII] - acquiring resources in constructors and releasing them in destructors - is the silver
bullet for resource management. The problem with this approach is that many objects can point to the same piece of data,
but only one of them is the "owner", and when the owner dies, its destructor promptly blows the piece of data
to even smaller little pieces.

The most common way around this is /copying/. For example, you load a large file representing a 3D object model
or an XML document or something. You find an interesting leaf on the 3D tree model or in the XML tree or whatever.
Now you want to release the memory of the whole model so that you can free some space for processing the part.
You need to either convince the model object that it doesn't own the stuff in your leaf, or you have to copy
that stuff. The latter is way easier
(try to convince an owner such as |std::list| to let a couple of nodes go out of its jurisdiction).

Which is one reason that can cause garbage collection to outperform manual memory management. But of course with garbage
 collection you'll never master your debugging tools to an extent anywhere near the expertise you'll reach with
 manual memory management
(you'll have 10 times less bugs to practice on). It's up to you to choose the right tradeoff.

There are two common counter arguments: not all resources are memory, and not all systems can afford garbage collection.
 Well, surely more than 95% of resources /are/ memory, and surely more than 95% of C++ code runs in systems which /can/ afford garbage collection.
These arguments are yet another evidence that [6.2 C++ is about theory, not practice]. And the resources which are not memory
and must be released deterministically usually aren't handled very well be C++ destructors anyway. That's because a C++
 destructor can't handle errors (it has no return value and [11.13 it can't throw exceptions]).

-END
 
What's the order that local objects are destructed?

FAQ: In reverse order of construction - the stuff declared last is destroyed first.

FQA: Which makes sense, but are you sure you want to write code that depends on this?

-END

What's the order that objects in an array are destructed?

FAQ: In reverse order of construction - the last element is destroyed first.

FQA: Which sort of makes sense, but you /surely/ don't want to write code that depends on that one, do you?

 By the way, don't forget to use |delete[]|, not just |delete|, to free arrays allocated with |new[]|, otherwise the stupid thing
 [16.12 will not bother] to check the number of elements pointed by your pointer and some of your destructors won't get called
 (actually, in theory it could be worse - the behavior is undefined).

-END

Can I overload the destructor for my class?

FAQ: No. Destructors never have parameters or return values. And you're not supposed to call destructors explicitly,
so you couldn't use parameters or return values anyway.

FQA: Why do you want to overload destructors? Do you like C++ overloading? Are you sure? But the lack of return values
 /is/ a pity - [11.13 no way to handle errors]. Let's hope they won't happen, shall we?

-END

Should I explicitly call a destructor on a local variable?

FAQ: Don't do that! The destructor will be called again at the end of scope. And the second call will do nasty things,
 like crashing your program or something.

FQA: There are standard questions to ask in these cases, like "if this syntax is never useful, why does it compile"? Anyway, you /can/ call a destructor
 on a local variable, but you have to make sure you call a constructor after that and before the object goes out of scope.
 For example:

@
AMiserableFileClass file("f1.txt");
\/\/use file... now we want to close it, but there's no close() method, so:
file.~AMiserableFileClass();
\/\/open another file
new (&file) AMiserableFileClass("f2.txt");
@

|AMiserableFileClass| is a miserable file class because it has no |close| method, so you might feel the need to close it
 in the ugly way above. Try to avoid this, because most people won't understand it, and they shouldn't, because [6.4 there
 are better things to do] than [10.19 fiddling with the many ugly bits of C++].

-END

What if I want a local to "die" before the close |}| of the scope in which it was created? Can I call a destructor on a local if I /really/ want to?

FAQ: No, no, no! See the next FAQ for a simple solution. But don't call the destructor!

FQA: If you ever get into the situation of promoting an especially disgusting product, such as the C++ programming language, there are better ways to handle it
than get all excited. You can try and find a less disgusting product to center your money-making around, or you can
just relax.

"Don't call the destructor". There has to be /some/ reason for the destructor call to compile, doesn't it? Perhaps
sharing it with us could help calm down.

-END

OK, OK already; I won't explicitly call the destructor of a local; but how do I handle the above situation?

FAQ: Now you're talking! Here's a tip - you can simply surround the object with an /artificial block/:

@
{
  AMiserableFileClass file("f1.txt");
} \/\/the file object dies here
@

FQA: Is this ugly code supposed to be better than [11.5 the ugly code] calling a destructor and than a constructor? On a level,
this version is more cryptic
(at least it's easy to see what gets called when in that other ugly piece of code). But the truth is that
for many actual C++ programmers the "artificial blocks" (isn't all code "artificial"?) are more readable.

-END

What if I can't wrap the local in an artificial block?

FAQ: If you absolutely have to, do something like adding a |close| method to |AMiserableFileClass| which closes the file
 in its destructor. So you can achieve the effect of the destructor call without calling the destructor. Which is a taboo,
 get it?

 The FAQ also points out how hard it is to write a |close| function so that the destructor doesn't try to close a closed
 file.

FQA: If you can change |AMiserableFileClass|, it's better than using ugly code to work around its deficiencies. But
 where's the FAQ's brave new [13.4 reuse-oriented world] now? What about all those classes with stable interfaces
 you can't change? Seriously, it can happen with classes not available in source form.

I sincerely believe that the not-so-appetizing "call the destructor, then call a constructor" method is legal C++.
 If this is indeed so, I fail to understand the problem with mentioning it in the answer.

As to the problem of having destructors and close functions respect each other - one way around this is to [10.5 avoid
non-trivial constructors] and destructors and always use init and close functions. Next, you can replace [7.1 C++ classes]
 with their [7.4 metaphysical "encapsulation"] with [7.5 forward-declared] C |struct|s, which can actually yield stable binary interfaces
 and save recompilation. Next, you can replace C++ with C (where execution time matters) or with one of the many sane, safe
languages (where development time matters). There, doesn't it feel [6.5 much better] now?
                        
-END

But can I explicitly call a destructor if I've allocated my object with |new|?

FAQ: You can't, unless the object was allocated with placement |new|. Objects created by |new| must be |delete|d, which
 does two things (remember them): calls the destructor, then frees the memory.

FQA: Translation: |delete| /is/ a way to explictly call a destructor, but it /also/ deallocates the memory. You can
also call a destructor without deallocating the memory. It's ugly and useless in most cases,
 but you can do that.

Questions like "What /exactly/ does |delete| do?" probably cross the fine line separating between the questions everyone claiming to know
 C++ should be able to answer and the questions identifying people with too much C++-related garbage in their brains.
People can be quite productive by simply calling
 |new| and |delete| without thinking too much about the two steps involved, so not knowing about the two steps is probably no big deal.
 The most interesting thing about the two steps is that the idea of [10.1 having the code using the class managing the memory
 of its objects] is the main reason C++ code is [7.4 recompiled so frequently].

-END

What is "placement |new|" and why would I use it?

FAQ: There are many uses for placement |new|. For example, you can allocate an object in a particular location,
 you can pass the pointer to this location to placement |new| like this: |C* p = new(place) C(args);|

Don't use this unless you really care where the object lives (say, you have a memory-mapped hardware device
 like a timer, and you want to have a |Timer| object at the particular location).

Beware! It is your job to make sure that the address where you allocate the object is properly aligned and that
you have enough space for the object. You are also responsible for calling the destructor with |p->~C();|.

FQA: Size is relatively easy to deal with because we have |sizeof|, alignment can be more painful. Here's an advice:
if you care where your objects are allocated, don't make them objects of classes with constructors and destructors and stuff.
This way, you can create [11.14 memory pools] with code like |C pool[N];|, which takes care of alignment /and/ "type safety".
But if the class |C| has a constructor, it's going to get called N times by this statement (slow and stupid), and if you want someone to use
placement |new| with the pool, you'll have to /call the destructors/ after the constructors finish running
(slow, stupid and cryptic). Or you can use |char pool[N*sizeof(C)];| with platform-specific additions to handle
alignment, and then you won't be able to easily inspect the pool in a debugger (the object |pool| has the wrong type), etc.

And you have to be /out of your mind/ to call placement |new| when you [13.3 deal with memory-mapped hardware].
Do you realize that the constructor is going to /directly modify the state of the hardware/?
Even if you get this right (yes, there are ways to get this wrong, too boring to enumerate here),
this is one very unmaintainable way to write this kind of code. If you think that's "intuitive", think again.
What is the constructor doing - "creating" the timer? Come on, it's /hardware/, it was already physically there. Oh, it "initializes" it?
So why don't use a function with "init" in its name instead of a "constructor"?

You have enough trouble thinking about the semantics
of the hardware interface, so why would anyone want to add the complexity of C++ to the problem?

At least the FAQ has finally disclosed the [11.5 top secret information] about explicitly calling destructors.

-END

When I write a destructor, do I need to explicitly call the destructors for my member objects?

FAQ: No, they are called implicitly in the reverse order of their declaration in the class.

FQA: Pay attention to the details. If your member is a pointer
to something allocated with |new|, /the pointer's destructor/, which is a purely metaphysical entity doing nothing
                                                         physically observable,
is called, but it's /your/ job to call |delete| on the pointer, which calls the destructor of the pointed object.
The pointed object is technically /not/ a member of your class (the pointer is). The difference between
the intuitive feeling that "it's part of the class" and the formal definition of the term "member" is one reason making
|const| [18.2 less than useful] (is changing the object pointed by a member "changes" the object itself or not?).

Experienced C++ programmers find this natural since the C++ approach to these issues is relatively uniform.
If you have the tough luck of using C++ a lot, this point is obvious
(but you wouldn't ask the question in the first place).

There's a nifty thing called [16.1 "garbage collection"] that's been around for nearly half a century. The run time system
automatically figures out which objects are not pointed by anything and collects this garbage. Check it out, it's quite nice.

-END

When I write a derived class's destructor, do I need to explicitly call the destructor for my base class?

FAQ: No, this is done implicitly, in the reverse order of the appearance of the classes in the inheritance list
 (but |virtual| inheritance complicates matters), and after the destruction of the class members.

FQA: The FAQ says that if someone is [11.3 relying] on more complicated details of the finalization order, you'll need information outside the scope
 of the FAQ. The remark probably refers to useful information like locations of mental institutions and drug prescriptions.

Seriously, a Usenet language FAQ is already a place normally visited only by language lawyers. If you need /more/
obscure information to get your job done, the only legitimate reason is that you're writing a C++ compiler.
 If that's the case, and you feel miserable, cheer up - it could be worse. For example, imagine the misery of the people who'll /use/ your compiler!

-END

Should my destructor throw an exception when it detects a problem?

FAQ: THAT IS DANGEROUS! Which is discussed in [17.3 a FAQ about exceptions].

FQA: It shouldn't. And you can't return an error code either. However, on many systems you can send an e-mail with the word
 "BUMMER" to your support e-mail address.

If you want your destructor to detect problems, make it a |close| function.

-END
 
Is there a way to force |new| to allocate memory from a specific memory area?

FAQ: Oh, yessssss! Pools! Pools, pools, pools, pools, pools...

Please forgive me this time. I can't summarize what the FAQ is saying. It's almost as long as
 /all the previous answers/. And it's totally out of control. If you feel like it, fasten your seat belt,
 grab a barf bag, follow the link
 and knock yourself out.

FQA: Oh, nooooooo! Don't do that!

I know that your system has more than one kind of memory and\/or you have real time requirements and
 you can't use a traditional |malloc| implementation. But trust me, you're going to hate the day you've
 heard about those pools. Pools have arbitrary size limits (at most 20 objects of this, at most 30 objects of that...).
 Everybody is going to have a paranoia attack and set the limits to huge values, and then you're out of memory,
 and then you start thinking about the "right" limits, and it turns out that it's extremely hard to figure that out,
 because seemingly independent modules have related memory requirements (say, they handle mutually exclusive situations
                                                                         so you'd like them to use the same memory, but how?),
 and then you need some hairy logic to compute those values on a per-configuration basis, which means building several
 versions of the program, and maybe creating scripts for computing the values at build time, and you're going to /hate the day you've
 heard about those pools/.

If you're absolutely sure you can't create a single allocator managing your memory, at least /don't allocate objects
of classes with constructors/ from pools, [11.10 use C-like structs instead]. If you refuse to give up and admit that you're
 doing a pretty low-level thing and instead want to keep pretending that you're [8.6 "programming in the problem domain"],
 and for some reason you think C++ classes help you with that - go ahead. The punishments for your crime are
                                                                         discussed throughout the FQA.

-END


================================================
FILE: exceptions.fqa
================================================
Exceptions and error handling
{'section':17,'faq-page':'exceptions.html'}
This page is about C++ exceptions - an error handling facility which may be worse than dereferencing a null pointer upon error.

What are some ways |try \/ catch \/ throw| can improve software quality?

FAQ: You'll have less |if| statements in your code: you won't have to check for errors
each time you call a function. Conditional statements are known to contain
more bugs than other statements. With less |if| tests, you'll ship a better product, faster.

FQA: This is `<a href=http://en.wikipedia.org/wiki/Cargo_cult>cargo cult</a>` programming. Conditional
statements are error-prone because they are used to handle complicated scenarios, where an action
can result in many different outcomes, which affect the next actions. In order to make errors less probable, one has to simplify
the model of the desired behavior of the software. The problem is the complexity that leads to |if|
statements, not the |if| keyword, and using different keywords is not going to solve the problem by itself.

Exceptions are supposed to simplify the error handling model based on the assumption that in most cases,
a function that detected an error can't handle it, and has to propagate it to the caller. Finally,
a "high-level" enough caller is reached and actually makes a decision (pops up an error message, tries a different
action, etc.).

Despite its promises, this approach has inherent problems. There's a "social" problem -
with exceptions, people are not aware of the different errors that may happen in the code because most
of the code doesn't deal with errors. And when people rarely think about a particular aspect of an application,
ultimately this aspect is unlikely to be handled well. There's a more "technical" problem - functions essentially
doing nothing upon error except for propagating errors to the caller still can't be completely unaware of errors.
That's because they may need to release the resources they acquired before returning to the caller, which
may lead to /more/ errors, which must also be handled. Finally, in practice exception support has run-time overhead, and very
significant code size overhead, even if exceptions are never raised at run time, and even if they are /not mentioned/ in your code.
C++ devotees may claim otherwise; you can check by compiling your code with and without exception support (if your compiler
doesn't have such a flag, compile code as C and as C++ instead). This is unacceptable in resource-constrained systems.

Still, in many cases, the benefits of exceptions are more important than their problems. For example, if your
language manages memory automatically, the problem of releasing acquired resources becomes a small one (you only
have to care about files, etc., which are a tiny part of the "resources" used by a program - most of the
"resources" are memory). If your language throws exceptions when you violate its rules (for example, upon
out-of-bounds array access), these exceptions will help you find lots of bugs, especially if you can get the call stack
from an exception. If the purpose of an application is automated testing, and\/or it's used as a quick-and-dirty
internal tool as opposed to a product for an end user, this kind of exceptions is all you need to handle errors of
almost all kinds. In some languages, you can even resume the execution from the point where the exception was
raised after fixing the problem at the point where it was caught.

C++ exceptions offer none of these features. "Exception-safe" C++ code [17.3 can't handle errors] which happen
when it tries to release resources; "exception-unsafe" C++ code will [16.1 leak] resources, most frequently memory; and once you throw
an exception, the call stack is [17.7 lost]. This means that even separating your code to several processes and executing
code like |*(int*)0 = 0;| upon error is a better way to handle errors than C++ exceptions: at least the memory
is going to be reclaimed by the operating system, and you can typically have it save a snapshot of the process,
so that you can open it in a debugger and see where the error happened. A recommendation to "ban" exceptions
is probably over the edge, but think /a lot/ before using C++ exceptions, /or/ a feature that implicitly depends
on them, such as [17.2 constructors] and [13.1 overloaded operators], which have no other way to report an error. What C++ calls
"exceptions" is as unlikely to give you the benefits people get from exceptions in other languages as what
C++ calls "classes" is [7.1 unlikely] to give you the benefits of OO.

-END

How can I handle a constructor that fails?

FAQ: As you'd guess from the location of this question in the FAQ, the answer is "by throwing an exception". Alternatively,
you can mark the object as a "zombie" by using some kind of validity flag. You can then check that flag in the
calling code and maybe in the member functions of the object. The latter solution tends to "get ugly".

FQA: The inability to gracefully handle errors in C++ constructors is one good reason to [10.17 avoid] constructors
that do more than nothing, and use initialization functions instead. And C++ exceptions are not a graceful way to
handle errors, /especially/ in constructors. If your member object constructor throws an exception,
and you want to catch it in your constructor, the normally [10.6 ugly] colon syntax gets much uglier.

By the way, the C++ standard library doesn't throw exceptions in constructors (except for the ones thrown by
|operator new|). For example, you are supposed to test whether |ofstream| objects are zombies when you pass
them a filename in the constructor.

-END

How can I handle a destructor that fails?

FAQ: Actually you can't - not beyond logging the problem to a file or the like. In particular, /do not/ throw an exception.
The problem is that destructors are called when exceptions are thrown so that functions propagating errors to their
callers can clean up resources. Your destructor can also be called in such a situation. And when an exception is already
thrown, throwing another one will result in a call to |terminate()|, killing your process. Because you see, what else could C++ do?
There's an ambiguity: which exception out of the two do you want caught now?

Strictly speaking, you can make that "do not throw exceptions in a destructor unless you are sure that it won't be called
as a result of an exception already thrown", but you can rarely be sure of that.

FQA: That's right, |terminate()|. Solomon-style conflict resolution carried to the end.
See? Exceptions are not a graceful way to handle errors.

And "don't throw exceptions in destructors" actually means "don't call functions in destructors unless you
are sure they don't throw an exception". The C++ compiler won't check for you, because it can't: the language
doesn't force a function to declare whether it throws exceptions.

This is one good reason to avoid destructors
doing more than nothing: like constructors and operators, they can't handle errors.

-END

How should I handle resources if my constructors may throw exceptions?

FAQ: Well, the destructor of your class will not get called, but the destructors of the successfully constructed
sub-objects will get called. Conclusion: you should have all the resources allocated by your constructors
assigned to sub-objects. For example, if you call |new| in a constructor, don't use a bare member pointer to hold
the result - use a smart pointer, like |std::auto_ptr|. You can also define your own smart pointer classes to
point to things like [13.3 disk records]! Groovy!

And you can use |typedef| to make the syntax of using smart pointers easier.

FQA: `<b>WARNING</b>` - cyclic dependency between C++ features detected! You see, exceptions are a must in this language
so that you can handle errors in all the functions which fail to look like functions, such as constructors & operators.
Then it turns out that you need /constructors/ to work with /exceptions/ - unless each and every piece of memory
you acquire is not immediately assigned to some smart pointer, your code is not exception safe. This is known
as "Resource Allocation Is Initialization" (RAII) in the C++ community; it's supposed to be a /good/ thing.

And smart pointers are no picnic, as are virtually all automatic devices with something like "smart", "simple" or
"fast" in their name. Sure, you can use |typedef| to simplify the syntax. So can someone else; you'll end up with
many different type names for the same thing. This may annoy people, but it's perfectly OK with the compiler -
when it spits an [35.17 error message], it simply substitutes the full type names for all |typedef| names. But you can write a program to filter
the error messages...

Seriously, the syntax of smart pointers is the small problem. The big problem is their semantics. When you see
a bare pointer, you know how it works. But a smart pointer can work in /a lot/ of ways. The [http://boost.org boost] libraries allow
you to instantiate hundreds of different smart pointer classes from a single template (which made it to TR1, so we're going to see it in the next version of the C++ standard). How are you going to
figure out whether your program manages resources correctly or not when it's littered with smart pointers of different kinds,
especially in case there's any non-trivial scenario there, like the cases when "ownership" (the right & duty to dispose a resource)
is passed from object to object, or there are cyclic references in your code, or whatever?

When every single piece of software is "smart", and you can't trust things like |*p| and |p->x|, the software
becomes unmanageable.

-END

How do I change the string-length of an array of |char| to prevent memory leaks even if\/when someone throws an exception?

FAQ: If you want to work with strings, use something like |std::string| instead of |char*|. Otherwise, there's lots
of exceptions to catch, and lots of code to manage memory.

FQA: The FAQ is right about one thing - |char*| is a nasty kind of string, and using it for text processing is very
tedious. If you're doing anything not entirely trivial with strings, |std::string| is better than |char*|; using
a different language than C++ for text processing, one with a good built-in string type, is still better.

However, the part with exceptions really comes from |operator new|, not from |char*|. You can use |malloc| instead, or
configure your compiler to disable exceptions.

-END

What should I throw?

FAQ: C++ allows you to throw objects of arbitrary types; however, you probably shouldn't throw objects of built-in
types. For example, you can derive all your exception classes from |std::exception|, and throw temporary objects
of your classes.

FQA: Yep, C++ allows to throw anything. Too bad you can't really /catch/ it later. The only way to catch an arbitrary exception
is to use |catch(...)|, which doesn't let you find out what was thrown from where, and will even catch
/illegal memory access/ on some systems. This makes finding code like |throw "C++ is so grand - you can throw anything!!";|
a lot of fun (you have to find it on occasions when the uncaught exception crashes your program).

The FAQ's advice is thus a good one, as opposed to the language decision to allow to throw anything - a typical example
of the twisted notion of "generality" used throughout the language design. This decision is completely incomprehensible
unless you realize that there's a basic axiom in C++: the language must not force the compiler writer to treat any class
specially. For example, having a common base class for all user-defined classes which have at least one |virtual| function could
be quite handy, but it's incompatible with this implicit axiom. What did the C++ designers gain from following this
bizarre rule? Apparently nothing, except for an illusion of "generality", whatever that means.

-END

What does |throw;| (without an exception object after the |throw| keyword) mean? Where would I use it?

FAQ: It means "throw the last caught exception". It may be handy to catch an exception object, add some context information
and rethrow it; this way you get something like a stack trace. This feature also allows you to factor out several exception
handlers into a function called from a |catch(...)| block. Inside the function, you list the handlers for various special
cases and prefix them with |try { throw; }|.

FQA: Rethrowing the last exception is a useful feature, and many languages have it. It would be equally useful in C++ if C++
exceptions were any good. In particular, having to use this kind of feature throughout the code to get a /call stack/
is an insult to the language user. Unless it's some kind of "logical" call stack (context information not equivalent to
the list of C++ functions you'd see in a debugger at the point where the exception was thrown), call stacks should be
provided by the language.

If you are using C++ and want to figure out the current call stack, it may be better to
rely on platform-specific tricks (reading the frame pointer using inline assembly and traversing the linked list pointed
by it, then translating the instruction pointers using a symbol table) than to litter your code with statements
duplicating the information that's already there.

-END

How do I throw polymorphically?

FAQ: Suppose you have a |BaseEx| exception class and a |DerivedEx| exception class, which is inherited from |BaseEx|.
Than the following code might not work as you expect:

@
void f(BaseEx& e)
{
  throw e;
}
void g()
{
  DerivedEx e;
  try {
    f(e);
  }
  catch(DerivedEx&) {
    std::cout << "derived exception caught" << std::endl;
  }
}
@

The program will /not/ enter the |catch| block because you didn't throw polymorphically. That is, the statement |throw e;|
throws the object |e| as a |BaseEx|, because that's the type of |e| in that context; once an object is thrown as a
|BaseEx|, it will not get caught as a |DerivedEx|. If you prefer the other behavior, you can "easily get it" by having a
|virtual void raise() { throw *this; }| in your base class /and/ your derived class, and calling |e.raise();| instead of
|throw e;|. This way |DerivedEx::raise()| is called, and in the context of that function |e| is of type |DerivedEx|.

FQA: Let's see. You use C++ exceptions. Moreover, you have a hierarchy of exception classes. Moreover, you /pass exception
objects to functions/, in a way relying on an /implicit upcast/. Looks like you have lots of confidence in your knowledge of
C++ features. But along comes C++ and beats your common sense once again. The startling inconsistency of the language is
almost a virtue: maybe this time you will learn the value of simplicity and write something readable.

The behavior of |throw|, which looks at the static type of its argument expression, is somewhat surprising considering the
behavior of |catch|, which does "respect" inheritance (to the extent made possible by |throw|). In practice, it is probably
better to remove some of the complexity in the example rather than add more complexity by mixing the dynamic binding
of |virtual| with the static binding of |throw|. A human might need to understand the code, you know.

If you do want
to memorize the quirks of C++, try to warp your mind to think in terms used by the compiler construction peanut gallery.
From this perspective, the behavior of |throw| and |catch| /is/ consistent: both only look at things known at compile time
(the relationships between classes), and ignore things only known at run time (the actual type of an object). Basically
all of C++ behaves this way except for |virtual|, |dynamic_cast| and |typeid|. I think.

-END

When I throw this object, how many times will it be copied?

FAQ: Zero or more. There's no universal answer. The compiler has to make sure a thrown object provides a copy constructor,
even if it doesn't actually copy anything.

FQA: If you care about performance, C++ exceptions are probably no good for you. Exception support translates to a huge
mountain of code in your executable, and slows down function calls throughout your program. If you didn't care about
performance, you wouldn't ask this question. If you /think/ that you [10.9 care] about performance, but never actually measure
it or look at the performance implications of the techniques you use in your code, feel free to entertain yourself with
any fake answer that suits your emotional needs.

-END

Exception handling seems to make my life more difficult; clearly /I'm/ not the problem, am I??

FAQ: /Of course/ you can be the problem!

Here are some habits that may prevent you from utilizing the power of C++ exception handling:

`<ul>`
`<li>` /Return codes style/: people may put try blocks around every function call as if exceptions were error codes. `</li>`
`<li>` /The Java style/: using try\/finally instead of RAII, cluttering the code with clean-up statements. `</li>`
`<li>` /Organizing exceptions around the location of the error rather than its reason/: this way you need to handle
the same error many times and convert between types of exceptions. `</li>`
`<li>` /Categorizing errors using data members of exception classes rather than types/: this way you catch more errors
than you can handle in the given |catch| blocks, and rethrow exceptions after a test. `</li>`
`<li>` /Using different exception classes in different subsystems/: the FAQ decides to repeat the point before
previous, probably to create an impression that there are so many wrong mindsets out there. `</li>`
`<li>` /Using bare pointers instead of smart pointer classes/: a special case of avoiding RAII, admits the FAQ, but
it can't fight the temptation to list yet another "wrong mindset". `</li>`
`<li>` /Confusing bugs with run time errors/: if someone passes a null pointer to a function when that's illegal,
the code must be fixed. Throwing an exception without fixing the calling code doesn't solve the problem. `</li>`
`</ul>`

There are other wrong mindsets as well.

FQA: Yeah, you know how it is with those humans. They always [12.2 fail to realize] /they/ are the problem, and keep asking the
wrong questions. You give them a helpful and powerful language, and all they do is shooting themselves in the feet. Clearly
it's their flawed minds that must be fixed.

Let's look a little closer at the impressive list of "wrong mindsets" compiled by the FAQ:

`<ul>`
`<li>` /Return codes style/ is surely a wrong way to use exceptions, but it's one of the best ways to use /C++ exceptions/,
because otherwise the chance to manage resources correctly is not very high. Of course using real return codes is somewhat
cleaner, but what if exceptions are thrown by third-party libraries? `</li>`
`<li>` /The Java style/ is suited quite well to a managed environment like Java, because most of the so-called resources
are in fact /memory/, and you only need try\/finally blocks for stuff like files, of which there are few. This style
is problematic in C++ which [16.1 lacks garbage collection], but so is [17.4 RAII] which forces you to wrap everything with
"smart pointers" in a language which
only has built-in dumb pointers. The truth is that with C++ exceptions, you can't win. `</li>`
`<li>` /Organizing exceptions around the location of the error rather than its reason/: suppose you have 2 parsers in
your system. Would you prefer a single |ParseError| exception, or 2 separate classes, |HtmlParseError| and
|ConfigFileParseError|? Two different modules may raise exceptions for /similar/ reasons, but rarely /the same/ reason -
or else why are they different modules? An obvious exception to this rule are errors detected at the language level,
things like |ArrayIndexOutOfBoundsException|. Luckily, the C++ language run time environment does not detect errors,
so we don't need to discuss this kind of thing. `</li>`
`<li>` /Categorizing errors using data members of exception classes rather than types/ is not necessarily bad. C++ is
centered around the [15.1 assumption] that you can represent almost anything using types (class hierarchies or template "pattern matching")
more than any other popular statically typed language. However, this assumption is frequently refuted by reality,
and sticking to it is counter-productive in many cases. For instance, if a subsystem throws exceptions of a single class,
and you figure out the kind of error from looking at the object members or even inspecting error strings, you may end
up with less problems compared to the case where you have several dozens of classes in your exception inheritance tree.
This is a special case where modeling an aspect of your program using the language static type system may or may not be
optimal. `</li>`
`<li>` /Using different exception classes in different subsystems/: WOW, this is so /nasty/! Of course all subsystems
should share exception classes and other important common types. All subsystems of all systems in the world should be written
in close coordination between the implementers. This way, we'll finish the Tower of Babel in no time! That's why a
language should have no good way to pass an object of arbitrary type through a "subsystem".
Trust us: we are the people advocating a language without a /common string type/.
We sure know a thing or two about the issue.
`<li>` /Using bare pointers instead of smart pointer classes/: how about starting with the language and the standard
library? When |operator new| returns a smart pointer, and |"abc"| has the type |std::string|, we'll have something
to discuss. Until then, why should anyone manually emulate a high-level language on top of a low-level one throughout
one's code? `</li>`
`<li>` /Confusing bugs with run time errors/: this has absolutely nothing to do with exceptions. It's equally applicable
to any run time error handling strategy. Unless, of course, your environment throws exceptions upon events like null pointer dereferencing,
which C++ doesn't. `</li>`
`</ul>`

-END

I have too many try blocks; what can I do about it?

FAQ: Maybe you have a "return codes mindset" even though syntactically you use exceptions. There are many special cases
of this problem in which you can organize the code differently to reduce the amount of try blocks (the FAQ lists several cases).
If you can't solve the problem yourself, get a mentor.

FQA: Alternatively, you can stop throwing C++ exceptions so you won't have to catch them.

-END


================================================
FILE: faq.fqa
================================================
The FQA FAQ
{}
This page contains answers to Frequently Asked Questions about the C++
Frequently Questioned Answers. Which is a pretty bad case of having too many levels of indirection.
The FQA FAQ is based on a semantical histogram of about a couple of hundred messages,
some of which were supposed to be for me, and some others - for all the happy Web 2.0 users out there.
Questions that were asked several times made it to the list (there was no lower bound on the quality though).

If you want to question the facts in the FQA, there's a separate page for that.
[http://yosefk.com Send me e-mail], and if you [http://yosefk.com/c++fqa/web-vs-fqa.html correct a factual error],
I'll add your stuff.

Most of the questions here manifest negative attitude. Let me assure you that I got plenty of positive
feedback, too, but, somewhat naturally, it rarely comes in the form of a question.
And I am not going to add fake FAQs to make the subject look better the way [7.5 C++ FAQ does].
`<!-- h2toc -->`

`<h2>`It looks like a bunch of random points, what are you trying to say?`</h2>`

Read [http://yosefk.com/c++fqa/defective.html Defective C++] if you're looking
for a summary. The Q&A sections follow the structure of the C++ FAQ, and talk
about things on varying scales and of different importance.

`<h2>`I want to ask you something and get an answer, what should I do?`</h2>`

Send me [http://yosefk.com mail].

Here's how it works. Publishing stuff makes sense.
Face to face conversations and e-mail conversations make sense. Conversations in the form
of articles replying to other articles make sense some of the time. Comment thread conversations are futile.
Special case: Usenet conversations are futile. If they are moderated, they are futile and (almost) polite.

An example of a futile, (almost) polite discussion of the C++ FQA can be found in
[http://groups.google.co.il/group/comp.lang.c++.moderated/browse_frm/thread/870d15c57e831fc5/5868fd6e57f6ae2c?hl=en&tvc=1#5868fd6e57f6ae2c this comp.lang.c++.moderated thread]. For some reason, several people
well-known in the C++ community decided to have a bunch of off-topic arguments in that thread
(like how bad it is that some obscure features are going into C++0x and other obscure features aren't).
Off-topic and futile, but amusing and (almost) polite.

`<h2>Is there any alternative to C++?</h2>`

Yes, there's [6.5 plenty]. And no, there's [25.3 none].

As the C++ FAQ correctly points out, there's a key issue with choosing a programming language -
availability. That is, stuff that /already exists/ that your project depends upon. For example,
you may need C++ libraries which have no alternative in other languages
(today, in practice - not in the future, in theory). The project can already have lots
of C++ code in it, and rewriting it in another language is most often not an option.
Note how you can substitute COBOL for C++ in this paragraph and the claims will still hold.

However, if you're asking about the programming language by itself, then C++ is never the best
choice. In particular, use languages with safe execution and automatic memory management
whenever possible, because that greatly increases the speed of development and solves
many practical stability and security problems. There's plenty of languages in that
family. If you [10.9 really] need the speed badly enough to settle for unsafe execution,
you still have better options than C++ - for example, D, Objective-C, and plain old
C, a good snapshot of the language taken before the postfix increment
(Clarification: I know that many things were back-ported from C++ to ANSI C, you language lawyer).
You can also mix many programming languages fairly easily.

Of course you are forced to use C++ quite frequently, and in this sense there may
be no alternative to it. I use C++ a lot. I wouldn't write the FQA if I didn't.
But since I've stopped using it when I don't have to, many things became really easy.
/Try it/. Stop being a die-hard C++ weenie that does simple throwaway text processing in C++ and calls
the compiled programs "scripts". This behaviorial pattern yields suboptimal results.
And if you really need to use C++, make sure you know its problems, and don't
blindly trust the recommendations of the C++ overlords.

`<h2>`Can't the problems you mention be solved by proper design \/ project management?`</h2>`

They can. Theoretically. It will still cost more than not having to solve these problems in the first place.
You may not realize it, because you're fairly good. The thing is that your ability to juggle
lots and lots of things in your head yields the best results when these things are not entirely
worthless. Without having to work around C++, you'll get more done. But the bottom line is
that you can have good C++ code, with most problems of C++ not manifesting themselves.
/If everybody on the team is really good at C++, and has a practical approach and lots of experience,
and your schedules aren't too tight/.

This last statement rarely holds, especially for larger projects. The issue with real-world schedules and
having no time to fight C++ in addition to the real problems is probably clear. The practical
approach and the experience are relatively obvious, too. People who prefer complicated solutions
because it demonstrates their skills and\/or try to use their language naively and [7.5 "naturally"] can cause
lots of damage if their weapon is C++; the FQA has lots of details on that one. The strangest thing for most strong programmers is -
if someone is not very good at C++ (or whatever your project is written in, for that matter),
why do you want them on your team anyway?

This is really important, and took me some time to understand - it's one of the several
things that go against the grain of the training most programmers undergo. Well, let's look at an example.
We have this guy who is really good at physics, or statistics, or economics, or AI\/machine learning,
or genetics - whatever your domain is. And he can program. He's not an expert programmer, but he's brilliant,
and the code turns out pretty neat, at the semantical level, although admittedly he prints
objects to |cout| with |printSomething| functions - [15.1 pretty lame], that. We can have him on board,
happily coding away. We can hire him and let a strong programmer talk to him, convert his ideas
to code and bring back whatever the machine has to say when it runs, iteratively. Or we can
send the clueless PhD away and hire another [35.11 SFINAE] expert. It's your call. What will it be?

Let's move on. What about the young, bright, responsible but inexperienced type, constantly
looking for the most urgent problem and rushing to fight it? What about
the amazing coder, who can only be seen coding if you put a camera in his office and play the recording
in slow motion - most of the time he's surfing non-productive sites, except somehow
all that stuff that scares the heck out of other people gets done in no time? What about the super-orderly,
super-smart person, who can do anything you ask for, precisely and quickly, but just happens
to be a newbie in your language, and will have no time to become an expert?
Too bad all these people are not language lawyers, and can wreak havoc in C++. Would you have them on your team,
or would you send them over to your competitor?

/The programming language is not the main theme in programming./ Therefore, using a language which
doesn't require expertise from all users can help you utilize your human resources better,
as [7.4 the business-friendly-looking FAQ] would say.

`<h2>`But I already know C++, and so do many others. Isn't learning new languages hard?`</h2>`

No. And the amazing part is that you'll tell me that /yourself/. Many times I heard something like
"C'mon, this language is trivial and has nothing new, /why would I invest all that energy
into learning it/?" Prediction: the next step in the evolution of the brain will be a built-in consistency checker.

Clarification: learning new libraries can take time, and rewriting old code is not a sane option
in most cases. I'm talking about new code, not old code.

And, you'll be surprised how easy most languages are compared to C++. You can stay
extremely ignorant about how they work and they won't bite you, for years. I tested this one
myself since I was very curious. Perhaps I'll write about it some time.

Not only are most languages easier to learn than C++ - they're easier to use, too.
Especially the higher-level ones. You can get interesting work done in /no time/. You'll think differently about things.
The meaning of "design" changes. For instance, hardware hackers call /the code/ describing the hardware
"design". "Compile the design". In C++, they usually call the structure of the definitions
(classes, functions, templates) "design". At a higher level, you can call the details of how the /functionality/
is specified "design"; writing the code and connecting the pieces is easy enough to be called "implementation details".
I'm not really good with this sort of terminology, but it's something like that.

`<h2>`Why are you writing in such an emotional way?`</h2>`

Am not! This is the sanitized, calm and rational version. Do you have any idea how much editing it took?

Seriously, let's examine the breakdown of the potential FQA readers. People who hate C++ will be
entertained by the rants, which is not the main purpose, but is a good thing. Some of the people who love
C++ can be offended, but would they really feel otherwise if I used different language? And why do
they read something having such a title - is this some kind of informational masochism, and
how am I responsible for it, anyway?

And now we reach the most important subset of the readers - the ones working with C++ and having
their doubts. What's a bigger risk: to scare them with overly aggressive style, or to put them to sleep?
Note that the thing that really counts is the information, not the style. Yes, sir, that would be always,
and you ought to learn this or else you'll go extinct in no time. Therefore some of the people who won't be able
to extract the information from the text because of the style have critical flaws in their thinking,
and I don't mind losing this part of the audience. Especially considering the fact that any technical
document is an excellent cure for insomnia, and the people who entertain themselves reading RFCs
are a tiny minority of the population I'd like to talk to. So the sleeping risk has to be minimized first.
This is called risk management, as everybody who was forced to study a braindead Methodology-related
document during their career will readily tell you.

By the way, /have you seen the FAQ/? The FQA is way more vegetarian in many aspects. In particular,
the FAQ labels groups of people as [6.5 techie weenies endangering the interests of their employers],
and in general talks a lot about the (bogus) business aspect of the issues. As if you can [14.3 cut costs]
by fiddling with syntax and in general have your enterprise thrive by applying a bunch of
C++ coding tricks. This crosses the red line as far as I'm concerned. As one of my early reviewers
told me in a private message when I asked about my style, many of the FAQ's claims are
close to attempts at brainwashing, and therefore my replies are justified.
I don't know if he's right at the bottom line, but his message has a special place in my heart.

`<h2>`You are not very objective, are you?`</h2>`

No - it's your job. Do stuff, read stuff, think and make up your mind. Have you actually
selected an entity which you think of as "objective"? This is like having a slave port
in your brain.

There's plenty of material praising C++ and covering up its deficiencies
with unbelievable excuses and broken "solutions". There aren't many sources debunking this
material, and for a good reason - there's no money in it.
And then the C++ FAQ, which the FQA is based upon, is not at all objective, either.

Can anybody explain me /why/ the FQA should be "objective"? And just what does "objective" mean here?
Should I list a plethora of broken workarounds for each mentioned C++ misfeature? Or should
I say that many people don't think it's a problem each time I raise a problem? I sincerely and honestly don't get it.

`<h2>`You don't know C++ very well, do you?`</h2>`

If you have valid counter arguments, shoot. I don't feel like demonstrating my C++ skills,
or anything else for that matter, to strangers who weren't even taught to be polite.

If this issue is important to you, browse the FQA. You'll find out that I'm aware of
RAII, SFINAE, C++0x and just about every other idiotic C++-related acronym you wish to inform me about.

`<h2>`You're clearly into "managed environments", who cares what you think about C++, which has different goals?`</h2>`

They've discovered some time ago that you are supposed to refer to whatever the person says,
not the person, to make a valid argument.

I've done lots of low-level work. Real time, interrupts, context switching and
process migration, CPUs with small address spaces, 2-digit numbers of processors with shared
memory and incoherent caches and local memories, locating and working around hardware bugs, these sorts of things. In C++.
Yes, I also worked with managed environments, that part is based on my personal experience, too.

When I say that safe execution
is safer than unsafe execution, you can trust me. Do you always prefer credentials to logic?
Pretty risky, that.

`<h2>`Why do you complain when C++ lets you do bad things? The language is not your nanny.`</h2>`

I don't really complain about that, you probably took something out of a more complicated context. And check the previous answer, tough guy.

`<h2>`C++ is just a tool. Have you hurt yourself with a big nasty hammer, little baby?`</h2>`

C++ isn't just a tool, it's a language. Languages have [25.3 different dynamics] than tools. And I love you, too.

`<h2>`Are you a troll?`</h2>`

No, I'm a Turing-complete mammal just like you. Trolls are a different species. Biologists
inform us that trolls are characterized by the use of /flame baits/. A dictionary further
enlightens us, explaining that a bait is "food or other lure placed on a hook or in a trap
and used in the taking of fish, birds, or other animals".

Now, the key insight is that for a troll to survive, it has to use cost-effective baits.
That is, the bait should be significantly cheaper than the food, or else the troll will go bankrupt.

Of course, your not-so-well-thought-out emotional response counts
as a medium-sized piece of a fish, a bird, or some other animal.
But let me assure you, the FQA is way costlier and thus makes a lousy bait. Try doing something like this,
and you'll realize that a troll will not pick this path to ensure its survival.

Oh, and I also sign with my real name. Do you do that, too, or is it |cooluser35|?
Humans don't have names like that, you know. And what's that hair doing on your ears?

`<h2>`Don't you know that C++0x will fix all those problems?`</h2>`

I've seen TR1, and my expectations are low. Anyway, the FQA doesn't discuss the future
of C++, only its present, and even that is mostly limited to the stuff from the C++ FAQ
(that's why we don't talk about implicit casting and overload resolution too much here).
So you'll either have to wait for C++0x to materialize
(I promise to add a special section when it's adopted), or you can persuade Marshall Cline
 to add a C++0x section to the FAQ, and I'll see what I can do.

`<h2>`But you could do this to any language. Doesn't it make the whole thing meaningless?`</h2>`

Well, nobody did this to other languages, not on this scale anyhow.
 The difference in our opinions is that you're saying that I'm special, and I'm saying C++ is special.
 There are more programmers than there are programming languages, so statistically my argument
 has better chances to be correct
 (not; we don't know anything about the distribution of anything, so never mind).
  
  Well, your argument is shaky, too. How about getting some empirical data? Try to write
  this kind of thing about some other popular language, start with something like "Defective C++" and try to show
  that whatever you're trying to do with this language just doesn't work. I think
  your argument will fall apart.

Don't try to discuss it with me - you have nothing to say about the actual reasoning in the FQA,
  so it's all worthless. I'm just trying to trick you into doing some creative writing.
  Maybe commenters will show up - you'll discover lots of things about yourself at that point.

`<h2>`All those C++ users and overlords can't be wrong, can they? Why should I believe you?`</h2>`

This sort of thinking will get you in trouble, since it's recursive and it has no termination condition.
  Very large groups of people with the usual subset of those having impressive credentials are known to have been
  wrong for very long periods of time (the flat Earth issue comes to mind; these people weren't stupid, mind you,
                                       "wrong" and "stupid" is not the same thing).
  Supposing you are in a group of people who are wrong right now, how do you plan to find it out
  using your kind of thinking?

You are not supposed to believe me; you're supposed to believe what I say, or not, depending
  on whether it makes sense. If you feel an urge to discuss this, keep in mind that I don't really care to convince /you/.
  I want to talk to people who are likely to start new software projects, with an emphasis on "new".
  And I don't think you can produce anything "new" in any significant sense before you change
  your attitude, because new things are by definition not backed up by large groups of supporters,
  so how would you know what to do?

(/John Millikin:/ Most educated people from Aristotle onward believed Earth to be round, and
[http://en.wikipedia.org/wiki/Flat_Earth#Classical_Antiquity Eratosthenes measured its circumference] rather accurately.
Examples in which educated people were wildly incorrect en mass include [http://en.wikipedia.org/wiki/Humorism Humorism]
 and [http://en.wikipedia.org/wiki/Geocentric_model Geocentrism].)

`<h2>`Do you even realize that C++ was shaped by various goals and trade-offs? How can you judge it otherwise?`</h2>`

I'm [6.2 aware] of the trade-offs and goals. If you identify with the language designer,
  that's very noble of you. I am a language user. I care about getting work done.
  In other languages, it's way easier for me than it is in C++, and many people
  feel that way. Of course you are free to misattribute that to my incompetence in the area of C++,
  computing in general or whatever, and (independently of that) keep having fun with C++.

  By the way, I don't try to make you stop
  using C++, and nowhere in the FQA do I say anything derogatory about people who use C++ in general.
  Do what you like. People who think this is obvious: sorry. We're not alone on this planet.

`<h2>`Why do you use complicated libraries like boost if they don't make your life easier, and isn't it your fault?`</h2>`

What makes you think I use them? I have no idea why they keep asking /that/. It looks like
  people try to build a model of the personality behind the text instead of a model of what
  the text says. Is it really that helpful?

If you try to make your C++ code simple and easy to follow, I might even enjoy working with you some day.

`<h2>`Why not quit whining and find a better job where there's no C++?`</h2>`

I find my job very interesting. The programming languages you get to use are not at all the most important
  part of the job, it's what you get to do that counts.

I do try to minimize my use of C++; I try to only deal with it when I help others out of trouble.

And thanks for your genuine interest in my career! I hope you're all right, too. This whole line
  of discussion is of course very relevant to the contents of the FQA.

`<h2>`Why don't you get a life?`</h2>`

You typed that at some software weenie Web 2.0 site, didn't you?

`<h2>`C++ is already dead, so isn't the whole purpose of this document to get page views?`</h2>`

/Of course/ I want people to view these pages! People usually write stuff so that other people read it.
  And what makes your fingers type, may I ask?

Regarding "C++ is dead": if you work on businessy apps, it's possible that you didn't notice that
  there's a huge market of embedded software. C++ only starts to penetrate it /now/. Also, google
  for SystemC (hint: it really should have been "SystemC++"). But there's also lots of new code in C++
  outside of embedded software or the hardware modeling world. If you use the web to approximate reality, your perspective
  will be invariably skewed by the people who work with the newest \/ obscure \/ most exciting and successful stuff
  (in random order),
  since these make the most noise.

  And there's
  lots of people who do most of their work in C++ everywhere, some of them with half a year
  of experience, and refuse to learn new languages. There are even young people who will /refuse
  to take a job/ unless they'll get to work in C++.

I don't think people would read this if C++ was acknowledged as a language that people don't
  write new code in. Would you chase a link to a COBOL FQA?
  
C++ is not dead, it just smells funny.


================================================
FILE: fqa2html.py
================================================
#!/opt/python-2.3.5_mob/bin/python
# -*- coding: utf-8 -*-
'''convert a C++ FQA page to HTML'''
import sys
import re
import os

site = os.environ.get('FQA_SITE','') #'http://geocities.com/yossi_kreinin/'

# in October 2007, parashift.com disappeared from the DNS
faq_site = 'http://www.parashift.com/c++-faq-lite'
#faq_site = 'http://www.dietmar-kuehl.de/mirror/c++-faq'
#faq_site = 'http://www.ensta.fr/~diam/c++/online/c++-faq-lite'

style = '''
  <style type='text/css'>
  <!--
  body { font-family: arial; color: black; background: white }
  h2   { color: black; background-color: #ddeeff }
  h1   { color: black; background-color: #ddeeff }
  h5   { background-color: #eeeeee }
  pre  { background-color: #eeeeee }
  .part{ color: gray }
  .FQA { background-color: blue; color: gold }
  .FAQ { background-color: gold; color: blue }
  .corr{ color: red }
  -->
  </style>
'''

import time
import datetime
ga = open('ga.js').read()
end_of_doc = '''
<hr>
<small class="part">Copyright \xc2\xa9 2007-%d <a href="http://yosefk.com">Yossi Kreinin</a><br>
<tt>revised %s</tt></small>
%s
</body>
</html>'''%(datetime.datetime.now().year,time.strftime('%d %B %Y',time.localtime()),ga)

re_link = re.compile('\\[http:([^ ]+) ([^\\]]+)\\]')
re_int = re.compile('\\[(\\d+)\\.(\\d+) ([^\\]]+)\\]')
re_corr = re.compile('\\[corr\\.(\\d+) ([^\\]]+)\\]')

num2sec = {
   6: 'picture',
   7: 'class',
   8: 'ref',
   9: 'inline',
   10: 'ctors',
   11: 'dtor',
   12: 'assign',
   13: 'operator',
   14: 'friend',
   15: 'io',
   16: 'heap',
   17: 'exceptions',
   18: 'const',
   19: 'inheritance-basics',
   20: 'inheritance-virtual',
   21: 'inheritance-proper',
   22: 'inheritance-abstract',
   23: 'inheritance-mother',
   25: 'inheritance-multiple',
   27: 'smalltalk',
   32: 'mixing',
   33: 'function',
   35: 'templates',
}

def main():
  if len(sys.argv)!=2:
    raise Exception('usage: %s <input C++ FQA text>'%sys.argv[0])
  run(sys.argv[1])

def run_to(arg,stream,sp=False):
  try:
    oldout = sys.stdout
    sys.stdout = stream
    run(arg,sp)
  finally:
    sys.stdout = oldout

def doit(arg):
  run_to(arg+'.fqa',open(arg+'.html','wb'))
  
def run(arg,sp=False):
  fqa = open(arg)
  fqa_page = arg.replace('.fqa','.html')

  # escape sequences with beginnings and endings, for example:
  # /xxx/ => <i>xxx</i>
  esc2mark = {
    '/':('<i>','</i>'),
    '|':('<tt>','</tt>'),
    '@':('<pre>','</pre>'),
  }
  # html entities
  plain2html = {
    '"':'&quot;',
    "'":'&#39;',
    '&':'&amp;',
    '<':'&lt;',
    '>':'&gt;',
  }

  def replace_html_ent(s):
    'see also str2html. this one is for titles'
    o = ''
    for x in s:
      o += plain2html.get(x) or x
    return o

  def replace_links(s):
    def rl(m):
      g=m.groups()
      return '`<a href="http:%s">%s</a>`'%(g[0],g[1])
    def ri(m):
      g=m.groups()
      snum=int(g[0])
      sec=num2sec[snum]
      num=int(g[1])
      cap=g[2]
      if sp: sec = sp
      else: sec += '.html'
      return '`<a href="%s%s#fqa-%d.%d">%s</a>`'%(site,sec,snum,num,cap)
    def rc(m):
      g=m.groups()
      num=int(g[0])
      cap=g[1]
      if sp: sec = sp
      else: sec = 'web-vs-fqa.html'
      return '`<a class="corr" href="%s#correction-%d">%s</a>`'%(sec,num,cap)
    s = re_link.sub(rl,s)
    s = re_int.sub(ri,s)
    s = re_corr.sub(rc,s)
    return s

  def str2html(p):
    '''convert a string to html (escaping and fqa markup)'''

    p = replace_links(p)
    
    op = ''
    i = 0
    esc2state = {}
    ek = esc2mark.keys()
    for k in ek:
      esc2state[k]=0
    pk = plain2html.keys()
    asis = False
    while i<len(p):
      c = p[i]
      if c == '`':
        asis = not asis
      elif not asis and c == '\\':
        i+=1
        if i<len(p):
          op += p[i]
      elif not asis and c in ek:
        op += esc2mark[c][esc2state[c]]
        esc2state[c] = 1-esc2state[c]
      elif not asis and c in pk:
        op += plain2html[c]
      else:
        op += c
      i+=1
        
    return op
    
  def read_paragraph():
    '''a paragraph is a bunch of non-blank lines'''

    p = ''
    line = fqa.readline()
    while line.strip() != '':
      p += line
      line = fqa.readline()
    if p.strip() == '':
      return None
    return str2html(p.strip())

  def print_paragraph(p):
    print '<p>'
    print p
    print '</p>'
    print

  # first line: page title
  title = fqa.readline()[:-1]

  def print_heading(faq_page):
    if sp:
      print '''<h1>%s</h1>'''%replace_html_ent(title)
      return
    if faq_page:
      below_heading = '''<small class="part">Part of <a href="index.html">C++ FQA Lite</a>.
      To see the original answers, follow the </small><b class="FAQ"><a href="%s/%s">FAQ</a></b><small class="part"> links.</small><hr>'''%(faq_site,faq_page)
    elif 'Main page' not in title:
      below_heading = '''<small class="part">Part of <a href="index.html">C++ FQA Lite</a></small><hr>'''
    else:
      below_heading = ''
      
    title_titag = 'C++ FQA Lite: '+title
    title_h1tag = title
    if 'Main page' in title:
      title_titag = 'C++ Frequently Questioned Answers'
      title_h1tag = 'C++ FQA Lite: Main page'
    print '''<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<html>
  <head>
  <title>%s</title>
  %s
  </head>
  <body>
  <h1>%s</h1>
  %s
  '''%(replace_html_ent(title_titag),style,replace_html_ent(title_h1tag),below_heading)

  # second line: attributes
  attrs = eval(fqa.readline())
  if len(attrs):
    section = attrs['section']
    faq_page = attrs['faq-page']
    print_heading(faq_page)
  else:
    print_heading(None)
    # this isn't a FAQ section - read and print all paragraphs
    while 1:
      p = read_paragraph()
      if p:
        print_paragraph(p)
      else:
        if not sp: print end_of_doc
        return
  #print 'formatting C++ FQA page %s (FAQ page: %s, section number %d)'%(title,faq_page,section)

  # we get here if this is a FAQ section
  class Question:
    def __init__(self,title,faq,fqa):
      self.title = title # one paragraph
      self.faq = faq # list of paragraphs
      self.fqa = fqa # list of paragraphs

    def toc_line(self,num):
      page=fqa_page
      if sp: page=sp
      return '<li><a href="%s#fqa-%d.%d">[%d.%d] %s</a></li>'%(page,section,num,section,num,self.title)

    def title_lines(self,num):
      return '''<a name="fqa-%(sec)d.%(num)d"></a>\n<h2>[%(sec)d.%(num)d] %(title)s</h2>\n'''%{'sec':section,'num':num,'title':self.title}

    def replace_faq(self,num):
      repstr = '<b class="FAQ"><a href="%s/%s#faq-%s.%s">FAQ:</a></b>\n'%(faq_site,faq_page,section,num)
      self.faq[0]=self.faq[0].replace('FAQ:',repstr)

    def replace_fqa(self):
      repstr = '<b class="FQA">FQA:</b>'
      self.fqa[0]=self.fqa[0].replace('FQA:',repstr)

  def read_question():
    '''format:

    what's up?

    FAQ: um. this, and
    this.

    and this.

    FQA: no, that, or maybe
    that, or...

    that.

    -END
    '''
    
    title = read_paragraph()
    if title == None:
      return None

    faqps = [read_paragraph()]
    while 'FQA:' not in faqps[-1]:
      if p.strip() == '':
        return None
      faqps.append(read_paragraph())

    fqaps = [faqps.pop()]
    while '-END' not in fqaps[-1]:
      fqaps.append(read_paragraph())

    fqaps.pop()
      
    return Question(title,faqps,fqaps)

  # next paragraph is a generic page description
  p = read_paragraph()
  print_paragraph(p)

  # other paragraphs are questions
  q = read_question()
  qs = []
  while q:
    qs.append(q)
    q = read_question()

  # generate a table of contents
  print '<ul>'
  for i,q in enumerate(qs):
    print q.toc_line(i+1)
  print '</ul>'

  # print the questions

  for i,q in enumerate(qs):
    n=i+1
    print
    print q.title_lines(n)

    q.replace_faq(n)
    for p in q.faq:
      print_paragraph(p)

    q.replace_fqa()
    for p in q.fqa:
      print_paragraph(p)

  # end
  if not sp: print end_of_doc

secindex = [
("picture",'Big Picture Issues'),
("class",'Classes and objects'),
("inline",'Inline functions'),
("ref",'References'),
("ctors",'Constructors'),
("dtor",'Destructors'),
("assign",'Assignment operators'),
("operator",'Operator overloading'),
("friend",'Friends'),
("io",'Input/output via <tt>&lt;iostream&gt;</tt> and <tt>&lt;cstdio&gt;</tt>'),
("heap",'Freestore management'),
("exceptions",'Exceptions'),
("const",'Const correctness'),
("inheritance-basics",'Inheritance - basics'),
("inheritance-virtual",'Inheritance - <tt>virtual</tt> functions'),
("inheritance-proper",'Inheritance - proper inheritance and substitutability'),
("inheritance-abstract",'Inheritance - abstract base classes'),
("inheritance-mother",'Inheritance - what your mother never told you'),
("inheritance-multiple",'Inheritance - multiple and <tt>virtual</tt> inheritance'),
("mixing",'How to mix C and C++'),
("function",'Pointers to member functions'),
("templates",'Templates'),
]

singlepageindex = '''C++ Frequently Questioned Answers
{}
This is a single page version of [http://yosefk.com/c++fqa C++ FQA Lite]. C++ is a general-purpose programming language, not necessarily suitable for your special purpose. [6.18 FQA] stands for "frequently
questioned answers". This FQA is called
"lite" because it questions the answers found in `<a href="http://www.parashift.com/c++-faq-lite/index.html">C++ FAQ Lite</a>`.

The single page version does not include most "metadata" sections such as [http://yosefk.com/c++fqa/faq.html the FQA FAQ].

`<h2>Table of contents</h2>`

`<ul>
<li><a href="%(sp)s#fqa-defective">Defective C++</a> - a list of major language defects
<li>C++ Q&A, structured similarly to C++ FAQ Lite, with links to the original FAQ answers
<ul>
<li><a href="%(sp)s#fqa-picture">Big Picture Issues</a></li>
<li><a href="%(sp)s#fqa-class">Classes and objects</a></li>
<li><a href="%(sp)s#fqa-inline">Inline functions</a></li>
<li><a href="%(sp)s#fqa-ref">References</a></li>
<li><a href="%(sp)s#fqa-ctors">Constructors</a></li>
<li><a href="%(sp)s#fqa-dtor">Destructors</a></li>
<li><a href="%(sp)s#fqa-assign">Assignment operators</a></li>
<li><a href="%(sp)s#fqa-operator">Operator overloading</a></li>
<li><a href="%(sp)s#fqa-friend">Friends</a></li>
<li><a href="%(sp)s#fqa-io">Input/output via <tt>&lt;iostream&gt;</tt> and <tt>&lt;cstdio&gt;</tt></a></li>
<li><a href="%(sp)s#fqa-heap">Freestore management</a></li>
<li><a href="%(sp)s#fqa-exceptions">Exceptions</a></li>
<li><a href="%(sp)s#fqa-const">Const correctness</a></li>
<li><a href="%(sp)s#fqa-inheritance-basics">Inheritance - basics</a></li>
<li><a href="%(sp)s#fqa-inheritance-virtual">Inheritance - <tt>virtual</tt> functions</a></li>
<li><a href="%(sp)s#fqa-inheritance-proper">Inheritance - proper inheritance and substitutability</a></li>
<li><a href="%(sp)s#fqa-inheritance-abstract">Inheritance - abstract base classes</a></li>
<li><a href="%(sp)s#fqa-inheritance-mother">Inheritance - what your mother never told you</a></li>
<li><a href="%(sp)s#fqa-inheritance-multiple">Inheritance - multiple and <tt>virtual</tt> inheritance</a></li>
<li><a href="%(sp)s#fqa-mixing">How to mix C and C++</a></li>
<li><a href="%(sp)s#fqa-function">Pointers to member functions</a></li>
<li><a href="%(sp)s#fqa-templates">Templates</a></li>
</ul>
</li>
<li><a href="%(sp)s#fqa-web-vs-fqa">`FQA errors`</a> found by readers</li>
</ul>
`
'''

def singlepage(outname):
  '''generate a single HTML page with: intro & index, Defective C++, Q&A sections, and FQA errors.'''
  outf = open(outname,'wb')
  print >> outf, '''<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<html>
  <head>
  <title>C++ Frequently Questioned Answers</title>
  </head>
  %s
  <body>
'''%style

  tmpfile = 'sp-index.tmp.fqa'
  tf=open(tmpfile,'wb')
  tf.write(singlepageindex%{'sp':outname})
  tf.close()
  run_to(tmpfile,outf,sp=outname)
  os.remove(tmpfile)

  def sec_ancor(secfname):
    print >> outf, '<a name="fqa-%s"></a>'%secfname[:-4]
  import imp
  h2toc=imp.load_source('h2toc','toc.py')
  def sec_with_toc(filename,name):
    sec_ancor(filename)
    tmpfile = 'sec-with-toc.tmp.html'
    tmp=open(tmpfile,'wb')
    run_to(filename,tmp,sp=outname)
    tmp.close()
    h2toc.gentoc(tmpfile,name,outname)
    outf.write(open(tmpfile).read())
    os.remove(tmpfile)
  sec_with_toc('defective.fqa','defect')
  for sec,title in secindex:
    sec_ancor(sec+'.fqa')
    run_to(sec+'.fqa',outf,sp=outname)
  sec_with_toc('web-vs-fqa.fqa','correction')
  print >> outf, end_of_doc
  outf.close()



================================================
FILE: friend.fqa
================================================
Friends
{'section':14,'faq-page':'friends.html'}
The questions here are about |friend| declarations. A short answer to them all: you probably don't need |friend| declarations.

What is a |friend|?

FAQ: A class can declare other classes and\/or functions as friends. The declaration allows the friends to
access non-|public| class members unaccessible to other code outside of the class.

FQA: In other words, |friend| refines the access control provided by the |private| keyword.
Which means it's almost useless, simply because |private| is [7.4 almost useless]. Specifically,
it fails to provide /encapsulation/, and therefore is little more than a /comment/.

If you define interfaces between modules developed independently and want these interfaces to be stable,
it's better to [6.3 use C for the interface definitions], not C++. If you insist on using C++ (forcing both modules to be built with the same tools),
relying on |private| to provide encapsulation is a bad idea, because changing private members triggers recompilation
of the client code. You can use [7.5 forward declarations] and\/or [20.1 pure abstract classes] to
provide a more stable interface.

If you work on the internal interfaces between the different classes of a module, and you're stuck with C++,
using |private| is surely better than defining all members |public|. This way, someone can easily tell
that a member is not accessed outside of the class, and clarity is good. However, there is little reason
to obsess with the fine details of access control in the internal interfaces.

Most of the time, the distinction
between |private| and |public| is good enough to describe what you want. If you feel a strong urge to split
tightly coupled functions between several classes, you can do it with |friend|, or yo
Download .txt
gitextract_io2u6nst/

├── .gitignore
├── LICENSE
├── assign.fqa
├── changelog.fqa
├── class.fqa
├── const.fqa
├── ctors.fqa
├── defective.fqa
├── disclaimers.fqa
├── dtor.fqa
├── exceptions.fqa
├── faq.fqa
├── fqa2html.py
├── friend.fqa
├── function.fqa
├── ga.js
├── heap.fqa
├── index.fqa
├── inheritance-abstract.fqa
├── inheritance-basics.fqa
├── inheritance-mother.fqa
├── inheritance-multiple.fqa
├── inheritance-proper.fqa
├── inheritance-virtual.fqa
├── inline.fqa
├── io.fqa
├── linkimages.py
├── linking.fqa
├── mixing.fqa
├── operator.fqa
├── picture.fqa
├── readme.txt
├── ref.fqa
├── refresh.py
├── templates.fqa
├── tidy.py
├── toc.py
├── upload.py
├── web-vs-c++.fqa
├── web-vs-fqa.fqa
└── why.fqa
Download .txt
SYMBOL INDEX (9 symbols across 4 files)

FILE: fqa2html.py
  function main (line 72) | def main():
  function run_to (line 77) | def run_to(arg,stream,sp=False):
  function doit (line 85) | def doit(arg):
  function run (line 88) | def run(arg,sp=False):
  function singlepage (line 401) | def singlepage(outname):

FILE: refresh.py
  function doit (line 5) | def doit():

FILE: tidy.py
  function getoutput (line 12) | def getoutput(cmd):
  function tidy (line 22) | def tidy(f):

FILE: toc.py
  function gentoc (line 4) | def gentoc(filename,name,visname=None):
Condensed preview — 41 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (593K chars).
[
  {
    "path": ".gitignore",
    "chars": 39,
    "preview": "*.pyc\n*.html\n*.exe\n_out_.txt\n*~\n.*.swp\n"
  },
  {
    "path": "LICENSE",
    "chars": 1297,
    "preview": "Copyright (c) 2015, Yossi Kreinin\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or witho"
  },
  {
    "path": "assign.fqa",
    "chars": 4517,
    "preview": "Assignment operators\n{'section':12,'faq-page':'assignment-operators.html'}\nThis section is about |operator=|. It's rathe"
  },
  {
    "path": "changelog.fqa",
    "chars": 2385,
    "preview": "Change log\n{}\nThis is a list of changes in the FQA part of the site done after October 28, 2007. It only mentions \"real\""
  },
  {
    "path": "class.fqa",
    "chars": 11319,
    "preview": "Classes and objects\n{'section':7,'faq-page':'classes-and-objects.html'}\nOne of the stated goals of C++ is support for ob"
  },
  {
    "path": "const.fqa",
    "chars": 18401,
    "preview": "Const correctness\n{'section':18,'faq-page':'const-correctness.html'}\nThis is about the |const| keyword, which makes you "
  },
  {
    "path": "ctors.fqa",
    "chars": 42865,
    "preview": "Constructors\n{'section': 10, 'faq-page': 'ctors.html'}\nThis section is about constructors, which create C++ objects, as "
  },
  {
    "path": "defective.fqa",
    "chars": 39003,
    "preview": "Defective C++\n{}\nThis page summarizes the major defects of the C++ programming language\n(listing all minor quirks would "
  },
  {
    "path": "disclaimers.fqa",
    "chars": 4084,
    "preview": "Disclaimers and excuses\n{}\nThis page lists a bunch of disclaimers and excuses, in no particular order.\n\nI know C++ bette"
  },
  {
    "path": "dtor.fqa",
    "chars": 16189,
    "preview": "Destructors\n{'section':11,'faq-page':'dtors.html'}\nDestructors are one of the many pieces of the puzzle that is the C++ "
  },
  {
    "path": "exceptions.fqa",
    "chars": 22534,
    "preview": "Exceptions and error handling\n{'section':17,'faq-page':'exceptions.html'}\nThis page is about C++ exceptions - an error h"
  },
  {
    "path": "faq.fqa",
    "chars": 21417,
    "preview": "The FQA FAQ\n{}\nThis page contains answers to Frequently Asked Questions about the C++\nFrequently Questioned Answers. Whi"
  },
  {
    "path": "fqa2html.py",
    "chars": 12518,
    "preview": "#!/opt/python-2.3.5_mob/bin/python\n# -*- coding: utf-8 -*-\n'''convert a C++ FQA page to HTML'''\nimport sys\nimport re\nimp"
  },
  {
    "path": "friend.fqa",
    "chars": 6427,
    "preview": "Friends\n{'section':14,'faq-page':'friends.html'}\nThe questions here are about |friend| declarations. A short answer to t"
  },
  {
    "path": "function.fqa",
    "chars": 15578,
    "preview": "Pointers to member functions\n{'section':33,'faq-page':'pointers-to-members.html'}\nThis is basically about the lack of fu"
  },
  {
    "path": "ga.js",
    "chars": 407,
    "preview": "<script type=\"text/javascript\">\nvar gaJsHost = ((\"https:\" == document.location.protocol) ? \"https://ssl.\" : \"http://www."
  },
  {
    "path": "heap.fqa",
    "chars": 39545,
    "preview": "Freestore management\n{'section':16,'faq-page':'freestore-mgmt.html'}\nThis page is about one of the most hard, boring and"
  },
  {
    "path": "index.fqa",
    "chars": 2874,
    "preview": "Main page\n{}\nThis is C++ FQA Lite. C++ is a general-purpose programming language, not necessarily suitable for your spec"
  },
  {
    "path": "inheritance-abstract.fqa",
    "chars": 10903,
    "preview": "Inheritance -- abstract base classes\n{'section':22,'faq-page':'abcs.html'}\nC++ abstract base classes are not bad at all "
  },
  {
    "path": "inheritance-basics.fqa",
    "chars": 9845,
    "preview": "Inheritance -- basics\n{'section':19,'faq-page':'basics-of-inheritance.html'}\nThis section outlines the C++ \"support\" for"
  },
  {
    "path": "inheritance-mother.fqa",
    "chars": 25415,
    "preview": "Inheritance -- what your mother never told you\n{'section':23,'faq-page':'strange-inheritance.html'}\nNote: section names "
  },
  {
    "path": "inheritance-multiple.fqa",
    "chars": 20946,
    "preview": "Inheritance -- multiple and virtual inheritance\n{'section':25,'faq-page':'multiple-inheritance.html'}\nThis section is ab"
  },
  {
    "path": "inheritance-proper.fqa",
    "chars": 25786,
    "preview": "Inheritance -- proper inheritance and substitutability\n{'section':21,'faq-page':'proper-inheritance.html'}\nThis section "
  },
  {
    "path": "inheritance-virtual.fqa",
    "chars": 17445,
    "preview": "Inheritance -- virtual functions\n{'section':20,'faq-page':'virtual-functions.html'}\nThis page is about |virtual| functio"
  },
  {
    "path": "inline.fqa",
    "chars": 16139,
    "preview": "Inline functions\n{'section':9,'faq-page':'inline-functions.html'}\nInline functions are a pet feature of [10.9 people] wh"
  },
  {
    "path": "io.fqa",
    "chars": 21554,
    "preview": "Input/output via <iostream> and <cstdio>\n{'section':15,'faq-page':'input-output.html'}\nThis section explains the benefit"
  },
  {
    "path": "linkimages.py",
    "chars": 864,
    "preview": "name2alt = {\n  'systemc': \"[System C: putting the 'hard' in hardware design]\",\n  'fqa': \"[C++ FQA Lite]\",\n  'defective':"
  },
  {
    "path": "linking.fqa",
    "chars": 5924,
    "preview": "Linking to the FQA\n{}\nIf you liked the FQA and wish to spread the word, here are some images\nfor the link face. If you l"
  },
  {
    "path": "mixing.fqa",
    "chars": 15457,
    "preview": "How to mix C and C++\n{'section': 32, 'faq-page': 'mixing-c-and-cpp.html'}\nThese questions are about mixing C and C++, wh"
  },
  {
    "path": "operator.fqa",
    "chars": 23908,
    "preview": "Operator overloading\n{'section':13,'faq-page':'operator-overloading.html'}\nThis section is about operator overloading - "
  },
  {
    "path": "picture.fqa",
    "chars": 35225,
    "preview": "Big Picture Issues\n{'section': 6, 'faq-page': 'big-picture.html'}\nThis part deals with the Big (and somewhat Sad) Pictur"
  },
  {
    "path": "readme.txt",
    "chars": 2988,
    "preview": "\nThis is the source code for the C++ FQA published at\n\n  http://yosefk.com/c++fqa/\n  \nYou're very welcome to edit the FQ"
  },
  {
    "path": "ref.fqa",
    "chars": 13151,
    "preview": "References\n{'section': 8, 'faq-page': 'references.html'}\nThis page is about C++ references - a duplicate language featur"
  },
  {
    "path": "refresh.py",
    "chars": 548,
    "preview": "import os\nimport imp\nf2h = imp.load_source('f2h','fqa2html.py')\nh2toc=imp.load_source('h2toc','toc.py')\ndef doit():\n    "
  },
  {
    "path": "templates.fqa",
    "chars": 44733,
    "preview": "Templates\n{'section': 35, 'faq-page': 'templates.html'}\nThis page is about C++ templates, one of the largest cannons to "
  },
  {
    "path": "tidy.py",
    "chars": 1169,
    "preview": "#!/opt/python-2.3.5_mob/bin/python\nimport os,commands\n\nfqas = [f for f in os.listdir('.') if f.endswith('.fqa')]\nhtmls ="
  },
  {
    "path": "toc.py",
    "chars": 1074,
    "preview": "# generate a table of contents from <h2> headers, and replace the <!-- h2toc --> comment with it\nimport re\nh2re = re.com"
  },
  {
    "path": "upload.py",
    "chars": 321,
    "preview": "import ftplib\nimport os\n\nfqas = [f for f in os.listdir('.') if f.endswith('.fqa')]\nhtmls = [f[:-4] + '.html' for f in fq"
  },
  {
    "path": "web-vs-c++.fqa",
    "chars": 16396,
    "preview": "C++ criticism by other people\n{}\nThis page is a collection of the best C++ criticism by FQA readers, copied\nfrom e-mail"
  },
  {
    "path": "web-vs-fqa.fqa",
    "chars": 8462,
    "preview": "FQA errors\n{}\nThis page lists the factual errors\\/inaccuracies in the C++ FQA. If you find one, please\n[http://yosefk.co"
  },
  {
    "path": "why.fqa",
    "chars": 611,
    "preview": "Purpose\n{}\nThe primary purpose of the FQA is to back up the following beliefs:\n\nNot using C++ is better than using C++. "
  }
]

About this extraction

This page contains the full source code of the yosefk/cpp-fqa GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 41 files (566.7 KB), approximately 132.6k tokens, and a symbol index with 9 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!