neath@solar-1.stars.flab.Fujitsu.JUNET (05/04/89)
I have just spent an hour trying to find out why my Vector class implementation
was core dumping. It turns out that the C++ variable declaration mechanism
whereby declarations can get moved around and/or performed in a new block can
result in some problems. Look at the following code fragment:
class X {
int i;
public:
X() {};
X(int n) { i = n; }
void times_two () {i *= 2;}
};
void dummy (int k) {
int i;
if (k > 3)
X* t = new X[10];
else
X* t = new X[20];
t.times_two();
}
At a first glance, this code seems to be OK. The pointer variable "t" is
declared in one of two ways depending upon the value of variable "k". If you
compile this, you get a "error: two declarations of t" message from cfront.
This is because cfront generated two empty declaration statements "X* t" in the
outer body with specific initialization code in the "if" and "else" clauses. An
even worse problem (and the one that was affecting my code) is shown below:
class X {
int i;
public:
X() {};
X(int n) { i = n; }
void times_two () {i *= 2;}
};
void dummy (int k) {
int i;
if (k > 3) {
::: // some code here
X* t = new X[10];
::: // more code here
}
else
X* t = new X[20];
t.times_two();
}
What happens if the "k > 3" test is TRUE? Well, not what you think! Since the
code contained in the body of the if statement is surrounded by braces, the
variable declaration of "t" is lexically scoped to this inner block. Now, that
would not be so bad if that was the only place that had a declaration, since
any attempt to use "t" outside of that block would result in a "variable not
declared" error.
However, because of the second declaration of "t" in the "else" clause, no such
thing happens. The reason is that cfront places an empty declaration of "t" in
the outer body, then initializes it in the "else" clause. If "k > 3" is TRUE,
then the inner-block "t" is declared and initialized. At the end of this block,
this "t" falls out of scope, and future references to "t" get the uninitialized
outer-block variable. This, of course, is a NULL pointer that, when first used
in the code, will kindly result in a bus error or some other nasty thing :-(
My questions are: 1) Is this a bug in cfront?
2) If it is a bug, is it fixed in 2.0?
Regards
Martin Neath <neath@dsg.ti.com>
------------------------------------------------------------------------
DISCLAIMER: As always, the opinions expressed above are strictly my own
and do not reflect those of my employer, Texas Instruments.
------------------------------------------------------------------------ark@alice.UUCP (Andrew Koenig) (05/06/89)
In article <NEATH.89May4105353@solar-1.stars.flab.Fujitsu.JUNET>, neath@solar-1.stars.flab.Fujitsu.JUNET writes: > if (k > 3) > X* t = new X[10]; > else > X* t = new X[20]; Cfront 2.0 will give an error message if you try to make a declaration the (only) subject of an if or else clause. It is far from clear what something like this should mean: if (x > 0) int y; Clearly, this cannot conditionally declare y in the surrounding context: how could one possibly compile this: if (x > 0) int y; y++; If you really want the declaration to live in a block of its own, you can still write if (x > 0) { int y; } and your meaning is then clear. -- --Andrew Koenig ark@europa.att.com
mat@mole-end.UUCP (Mark A Terribile) (05/07/89)
> I have just spent an hour trying to find out why my Vector class > implementation was core dumping. ... _> class X { _> int i; _> public: _> X() {}; _> X(int n) { i = n; } _> void times_two () {i *= 2;} _> }; _> void dummy (int k) { _> int i; _> if (k > 3) _> X* t = new X[10]; _> else _> X* t = new X[20]; _> t.times_two(); _> } > At a first glance, this code seems to be OK. Eh? Try X* t = ( k > 3 ) ? new X[ 10 ] : new X[ 20 ] ; > ... An even worse problem ... _> void dummy (int k) { _> int i; _> if (k > 3) { _> ::: // some code here _> X* t = new X[10]; // <== Wrong scope, fershure ... _> ::: // more code here _> } _> else _> X* t = new X[20]; _> t.times_two(); _> } > My questions are: 1) Is this a bug in cfront? > 2) If it is a bug, is it fixed in 2.0? More likely, it's a weakness in the language. This is one of those places where you really ought to declare the variable and initialize it later, I think. -- (This man's opinions are his own.) From mole-end Mark Terribile