Dec 102017
Text file describing some of the known bugs in Turbo C++ 1.0.
File TCPPBUGS.ZIP from The Programmer’s Corner in
Category C Source Code
Text file describing some of the known bugs in Turbo C++ 1.0.
File Name File Size Zip Size Zip Type
TCPPBUGS.TXT 9378 3942 deflated

Download File TCPPBUGS.ZIP Here

Contents of the TCPPBUGS.TXT file

TITLE: Public Domain TC++ V1.0 Bug List.

Product: Borland Turbo-C++ 1.0

Author: Marshall P. Cline, Ph.D.
ECE department
Clarkson University
Potsdam, NY 13676

Voice: 315-268-3868
Secretary: 315-268-6511
FAX: 315-268-7600

ARPA: [email protected] -or- [email protected]
Bitnet: BH0W@CLUTX
UUnet: uunet!!bh0w

Copyright: The Author releases this to the Public Domain

Date: June 11, 1990
Revised: August 9, 1990
Revised: August 14, 1990

This file, along with code fragments it contains, is public domain.
That means no one (including myself) can restrict its use/distribution.
In particular, you can't copyright it. No one can. Not even me.

If you have a TC++ bug to report, please email to the above addresses.
But please try to find/send a work-around to the problem/bug.
Also please explicitly state that your comments/code are public domain.


Several classlib\include\*.h have #include "foo.h" rather than .
This will only cause a problem if you have an indentically named header file
in your current working directory (#include "file.h" starts in current dir,
then searches the "standard places"; only searches standard places).
Note that TC++ by default doesn't find the classlib header files; if you want
it to, add the line to turboc.cfg: -IC:\TC\CLASSLIB\INCLUDE

Some include files have #ifndef __FILENAME_H, others have #ifndef _FILENAME_H.
(inconsistent #leading underscores). See for example sortable.h vs set.h, etc.

TCCNVT.EXE (the configuration file converter) isn't in the distribution.

`make -n' looks for and reads `builtins.mak' ONLY if it's in the current dir.
Naturally this is a bug, since make can't give an accurate picture of what a
real `make' would do without the macros and implicit rules in `builtins.mak'.

always includes which slows compilation some. In fact
doesn't need `NULL', and only needs memcpy() if _BIG_INLINE_ is
defined, which will probably be rare. Therefore the line
#include // to get memcpy and NULL
can be replaced with:
#ifdef _BIG_INLINE_
#include // to get memcpy
Since nearly everything includes , and since relatively few things
will want _BIG_INLINE_, this should be a winner. Note however that some code
might assume pulls in .

needs but doesn't get it. Add this to :
#ifndef __IOSTREAM_H

There is no . I constructed the following work-alike. It should go
into your standard include directory (where is, for example):
// new.h
// Author: Dr. Marshall Cline/ECE Dept/Clarkson Univ/Potsdam,NY 13676
// Email: [email protected]
// Phone: Voice: 315-268-6511; Fax: 315-268-7600
// Copyright: The Author releases this to the Public Domain, 9-July-90.
// Date: 9-July-1990
// Please include these acknowledgements when distributing this file
#ifndef __NEW_H
#define __NEW_H
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned size_t;
void* operator new(size_t size, void* ptr);
// _new_handler is a ptr to a parameterless function returning void
extern void (*_new_handler)();
void (*set_new_handler(void (*replacement_handler)()))();
#endif __NEW_H

Bug in istream: an extremely common C++ main input loop is something like:
while (cin >> chunk) chunk.do_something();
This works under the condition that istream::operator void* returns 0 (false)
after the input stream reads past EOF (or encounters an error). TC++'s
iostream.h is consistent with its documentation [programmer's guide p.183] in
stating that this operator returns 0 only when istream::fail() is true (when
failbit, badbit or hardfail are set), but unfortunately `fail' doesn't get
set after you've read past EOF. The correct operation is to return 0 (false)
on the read after you've run into EOF as well [Lippman p.384], which CAN BE
accomplished by the _bad bit being set wnen seeking past end-of-file [Lippman
p.402]. This can be fixed by changing "ios::operator void*()" in
as follows:
inline _Cdecl ios::operator void* ()
{ return (state & (eofbit|failbit|badbit|hardfail)) ? 0 : this; }
NB: the `official' (if there is such a thing in these pre-ANSI-C++ days)
behavior of istream::operator>> isn't clear. I've discussed this matter with
both Borland, and with a collegue who is in charge of certain C++ libraries
inside AT&T, and no one is yet sure what is really ``supposed'' to happen.
The above patch (checking the eofbit) appears to work correctly, but it may
be that a more comprehensive solution is eventually in order. In any event,
most people's code doesn't run around checking individual bits inside an ios,
so the above is probably `safe'.

There is an error in TCC that isn't in TC (they generate different code).
[Borland is as surprised that they'd behave differently as I was; I'd imagine
the internals are identical, and this assumption has be confirmed by Borland].
When a virtual fn is called from a non-virtual inline member, the virtualness
of the call vanishes. Compile the following with `tcc -vi':
class B {
virtual void virt();
void nonvirt() { cout << "B::nonvirt() calling "; virt(); }
class D : public B {
void virt();
D d;
(&d)->nonvirt(); // B::nonvirt() should call D::virt()
d.nonvirt(); // ditto
void B::virt() { cout << "B::virt()\n"; }
void D::virt() { cout << "D::virt()\n"; }
Unfortunately both of these call B::nonvirt().
Ie:Both d.nonvirt() & (&d)->nonvirt() translate to "call near ptr @B@virt$qv".
Obviously these should be virtual function calls. This is a serious error, as
calling a virtual from a non-virtual is fairly common. Note: if B::virt() is
a pure virtual (another legal operation, but perhaps not as common), the call
to "@B@virt$qv" generates a linker error (there is no B::virt()!). If
B::nonvirt() is a regular (non-inline) function (either by moving it out of
the class, or by `-v' or `-vi-'), TCC generates the correct code. Strangely
enough, TC appears to *always* generate the correct code.

The 1.2 streams package (called ) is nice, however AT&T treats the
inclusion of as an alias to . Therefore you should
rename it from to , and let simply be:
It is notable that a number of posters on comp.lang.c++ have been confused by
including thinking they were getting ...

: Instead of using the usual "name2" style macros, Borland
invented their own set of macros for concatenating pieces of names. Any code
using the Stroustrup-style macros (eg. code compatable with g++, CC, or
Zortech C++) will break. A work-around is to stick the following on the
bottom of your :
#define name2 _Paste2
#define name3 _Paste3
#define name4 _Paste4
This bug and its work-around is thanks to:
Pete Humphrey / [email protected] / 505-345-1863
EDS Research / 5951 Jefferson Street NE / Albuquerque, NM 87109-3432

TC++ signals a compiler error when the LAST default parameter for a
constructor is initialized by a constructor for some other class. A
workaround is to add an extra dummy default parameter of some
predefined type like int. Ex: if A and B are classes, then:
This will be an error: A::A(B b = B(...));
But this is ok: A::A(B b = B(...), int dummy=0);
Thanks to:Zerksis Umrigar/[email protected]/SUNY Binghamton NY

When an object is created as a side effect of an expression, and the expression
is short-circuited, the destructor for the object seems to get called anyway:
class X {
X create_copy_of_X() { return *this; } //Return *BY VALUE*
int whatever();
X x;
if (0 && x.create_copy_of_X().whatever()) stmt;
At the close of main(), TC++ calls a destructor on the copy of `x' even though
the copy was never properly constructed. This only happens when inline functns
are NOT inlined. Thanks to: Jamshid Afshar/[email protected]

 December 10, 2017  Add comments

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>