net!nic.cerf.net!mpcline
Subject: C++ FAQ (#7 of 7)
Date: 6 Nov 1996 23:24:28 GMT
Summary: Please read this before posting to comp.lang.c++

Archive-name: C++-faq/part7
Posting-Frequency: monthly
URL: http://www.cerfnet.com/~mpcline/C++-FAQs-Lite/

AUTHOR: Marshall Cline / cline@parashift.com / Paradigm Shift, Inc. /
One Park St. / Norwood, NY 13668 / 315-353-6100 (voice) / 315-353-6110 (fax)

COPYRIGHT: This posting is part of "C++ FAQs Lite."  The entire "C++ FAQs Lite"
document is Copyright(C) 1991-96 Marshall P. Cline, Ph.D., cline@parashift.com.
All rights reserved.  Copying is permitted only under designated situations.
For details, see section [1].

NO WARRANTY: THIS WORK IS PROVIDED ON AN "AS IS" BASIS.  THE AUTHOR PROVIDES NO
WARRANTY WHATSOEVER, EITHER EXPRESS OR IMPLIED, REGARDING THE WORK, INCLUDING
WARRANTIES WITH RESPECT TO ITS MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
PURPOSE.

C++-FAQs-Lite != C++-FAQs-Book: This document, C++ FAQs Lite, is not the same
as the C++ FAQs Book.  The book (C++ FAQs, Cline and Lomow, Addison-Wesley) is
500% larger than this document, and is available in bookstores.  For details,
see section [3].

==============================================================================

SECTION [34]: Miscellaneous technical issues


[34.1] Why can't the compiler find my header file in #include "c:\test.hpp" ?

Because "\t" is a tab character.

You should use forward slashes ("/") rather than backslashes ("\") in your
#include filenames, even on an operating system that uses backslashes such as
DOS, Windows, OS/2, etc.  For example:

    #if 1
      #include "/version/next/alpha/beta/test.hpp"    // RIGHT!
    #else
      #include "\version\next\alpha\beta\test.hpp"    // WRONG!
    #endif

Note that you should use forward slashes ("/") on all your filenames[15.8], not
just on your #include files.

==============================================================================

[34.2] Does C++ have new scoping rules for for loops?

Yep.

The following code used to be legal, but not any more, sinc i's scope is now
inside the for loop only:

    for (int i = 0; i < 10; ++i) {
      // ...
      if ( /* something wierd */ )
        break;
      // ...
    }

    if (i != 10) {
      // We exited the loop early; handle this situation separately
      // ...
    }

Unless you use a for loop variable after the for loop, the new scoping rule
won't break your code.  If it does break your code, in most cases the compiler
will give you a compile-time error message such as "Variable i is not in
scope".

Unfortunately it is possible that this new rule will silently cause your code
to do the wrong thing.  For example, if you have a global variable i, the above
code if (i != 10) silently change in meaning from the for loop variable i under
the old rule to the global variable i under the new rule.  This is not good.
If you're concerned, you should check with your compiler to see if it has some
option that forces it to use the old rules with your old code.

Note: You should avoid having the same variable name nested scopes, such as a
global i and a local i.  In fact, you should avoid globals althogether whenever
you can.  If you abided by these coding standards in your old code, you won't
be hurt by the new scoping rules for for loop variables.

==============================================================================

[34.3] Why can't I overload a function by its return type?

If you declare both char f() and float f(), the compiler gives you an error
message, since calling simply f() would be ambiguous.

==============================================================================

[34.4] What is "persistence"? What is a "persistent object"?

A persistent object can live after the program which created it has stopped.
Persistent objects can even outlive different versions of the creating program,
can outlive the disk system, the operating system, or even the hardware on
which the OS was running when they were created.

The challenge with persistent objects is to effectively store their member
function code out on secondary storage along with their data bits (and the data
bits and member function code of all member objects, and of all their member
objects and base classes, etc).  This is non-trivial when you have to do it
yourself.  In C++, you have to do it yourself.  C++/OO databases can help hide
the mechanism for all this.

==============================================================================

[34.5] Why is floating point so inaccurate? Why doesn't this print 0.43?

    #include <iostream.h>

    main()
    {
      float a = 1000.43;
      float b = 1000.0;
      cout << a - b << '\n';
    }

(On one C++ implementation, this prints 0.429993)

Disclaimer: Frustration with rounding/truncation/approximation isn't really a
C++ issue; it's a computer science issue.  However, people keep asking about it
on comp.lang.c++, so what follows is a nominal answer.

Answer: Floating point is an approximation.  The IEEE standard for 32 bit float
supports 1 bit of sign, 8 bits of exponent, and 23 bits of mantissa.  Since a
normalized binary-point mantissa always has the form 1.xxxxx... the leading 1
is dropped and you get effectively 24 bits of mantissa.  The number 1000.43
(and many, many others) is not exactly representable in float or double format.
1000.43 is actually represented as the following bitpattern (the "s" shows the
position of the sign bit, the "e"s show the positions of the exponent bits, and
the "m"s show the positions of the mantissa bits):

        seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
        01000100011110100001101110000101

The shifted mantissa is 1111101000.01101110000101 or 1000 + 7045/16384.  The
fractional part is 0.429992675781.  With 24 bits of mantissa you only get about
1 part in 16M of precision for float.  The double type provides more precision
(53 bits of mantissa).

==============================================================================

SECTION [35]: Miscellaneous environmental issues


[35.1] Is there a TeX or LaTeX macro that fixes the spacing on "C++"?

Yes, here are three (the first prevents line breaks between the C and "++"):

    \def\CC{{C\nolinebreak[4]\hspace{-.05em}\raisebox{.4ex}{\tiny\bf ++}}}

    \def\CC{C\raise.22ex\hbox{{\footnotesize +}}\raise.22ex\hbox{\footnotesize +}}

    \def\CC{{C\hspace{-.05em}\raisebox{.4ex}{\tiny\bf ++}}}

==============================================================================

[35.2] Are there any pretty-printers that reformat C++ source code?

In alphabetical order:
 * C++2LaTeX is a LaTeX pretty printer.  It is available via ftp from
   ftp://ftp.germany.eu.net/pub/packages/TeX/support/pretty/C++2LaTeX-3.02.tar.gz
 * C-Clearly by V Communications, Inc. is a Windows program that comes with
   standard formatting templates and also allows you to customize your own.
   http://www.v-com.com/
 * GNU indent program may help.  It's somewhere on ftp://www.cygnus.com [Note:
   If anyone has a better URL, please let me know (cline@parashift.com).]
 * tgrind is a Unix based pretty printer.  It usually comes with the public
   distribution of TeX and LaTeX in the directory
   "...tex82/contrib/van/tgrind".  A more up-to-date version of tgrind by Jerry
   Leichter can be found on: ftp://venus.ycc.yale.edu/pub in [.TGRIND].  [Note:
   If anyone has an updated URL for tgrind, please let me know
   (cline@parashift.com).]

==============================================================================

[35.3] Is there a C++-mode for GNU emacs? If so, where can I get it?

Yes, there is a C++-mode for GNU emacs.

The latest and greatest version of C++-mode (and C-mode) is implemented in the
file cc-mode.el.  It is an extension of Detlef and Clamen's version.  A version
is included with emacs.  Newer version are available from the elisp archives.

==============================================================================

[35.4] Where can I get OS-specific questions answered (e.g., BC++, DOS,
       Windows, etc)?

See one of the following:
 * comp.os.msdos.programmer
 * comp.windows.ms.programmer
 * comp.unix.programmer

Note: If anyone has an e-mail address for a BC++, VC++, or Semantic C++ bug
list and/or discussion mailing list, please let me know how to subscribe
(cline@parashift.com), and I'll mention it here.  Thanks; Marshall.

==============================================================================

[35.5] Why does my DOS C++ program says "Sorry: floating point code not
       linked"?

The compiler attempts to save space in the executable by not including the
float-to-string format conversion routines unless they are necessary, but
sometimes it guesses wrong, and gives you the above error message.  You can fix
this by (1) using <iostream.h> instead of <stdio.h>, or (2) by including the
following function somewhere in your compilation (but don't call it!):

    static void dummyfloat(float *x) { float y; dummyfloat(&y); }

See FAQ on stream I/O for more reasons to use <iostream.h> vs. <stdio.h>.

==============================================================================

[35.6] Why does my BC++ Windows app crash when I'm not running the BC45 IDE?

If you're using BC++ for a Windows app, and it works OK as long as you have the
BC45 IDE running, but when the BC45 IDE is shut down you get an exception
during the creation of a window, then add the following line of code to the
InitMainWindow() member function of your application
(YourApp::InitMainWindow()):

    EnableBWCC(TRUE);

==============================================================================

-- 
Marshall Cline, Ph.D., President, Paradigm Shift, Inc.
315-353-6100 (voice)
315-353-6110 (fax)
mailto:cline@parashift.com
