Topic: int x = x;" or "T t(t);" is OK?
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1996/12/14 Raw View
Alex Martelli wrote:
>
> Tom Payne <thp@cs.ucr.edu> writes:
>
> >Bill Seurer <seurer@rchland.ibm.com> wrote:
> >: In article <558kj7$iil@toralf.uib.no>, boukanov@sentef2.fi.uib.no
> >: (Igor Boukanov) writes:
> >: |> From the current DWP point of view is it possible to write:
> >: |> int x = x;
> >: |> T t(t);
> >: |>
> >: |> where T has copy constructor?
> >: |>
> >: |> I found that many C++ compilers accept the code without any warnings.
> >: |> And of cause very unfortunately from C point it is OK.
>
> >: Semantically and syntactically they are correct but of course they are
> >: probably coding errors.
>
> >I hope that the standard specifies that objects thus initialized have
> >indeterminate and possibly illegal values, so that their subsequent
> >use (other than assigning them legitimate values) yields undefined
> >behavior.
>
> But *assignment*, too, ought to be similarly "undefined behaviour"
> in this case, it seems to me! Consider for example:
[...example...]
> Should I then, when I'm designing a class meant to be "bullet
> proof" against the existence of uninitialized variables of that
> class (which IS, after all, the very point of having ctors,
> isn't it -- "uninitialized no more"...!-), protect the copy
> ctor similarly to how I normally protect the assignment operator,
> i.e. with a "if(this==&x)" test under which I would actually
> perform a default ctor rather than the copy ctor? It's doable,
If you want to be really bullet proof, you need to do it.
BTW, while the assignment case can happen at code where you don't see it
in the code, the self-copy of uninitialized objects will only happen
in this particular case.
BTW, maybe the check itself could add some problems. I don't know if
the following code could make sense, but if it does, your check would
possibly break it:
X*p = new(&x) X(x); // re-construct (maybe for fixing vtbl in shared
memory)
[...]
I think, the original 'self-initializsation' should not be allowed.
Maybe,
there could be the notion of an 'incomplete object' similar to an
'incomplete type':
Assuming you have a declaration like
X x=...;
Then x should be considered an inclomplete object until the final ';'
(or ',' if there are more variables defined in one statement).
That means, until there it is not allowed to use the object itself, but
only to use its address. Of course, this would still allow you to write
X x=*&x;
but this is most probably not done by accident, so if you do it, you
probably know what you are doing (or at least you think you know it ;-)
)
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/11/01 Raw View
boukanov@kvark.fi.uib.no (Igor Boukanov) writes:
>Microsoft VC++(<= 4.0) do the same and BC accept even
>const int x = x; // constant expression with undefined value?
>char array[x]; // array with undefined size?
>
>So is it possible (again, from DWP point of view) to have
>at compile time a constant expression with undefined value?
As far as I can tell from reading 5.19 [expr.const], the DWP
does not define whether or not `x' in the above example is a
constant expression. You can deduce from the DWP only that
`x' is a constant expression iff `x' is a constant expression,
which is of course a logical tautology.
So my interpretation is that according to the DWP, compilers
are allowed to accept code like that (and do whatever they like
when it is executed), but they're also allowed to reject it.
The DWP does not place any requirements on compilers for
the above code.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/11/01 Raw View
boukanov@sentef2.fi.uib.no (Igor Boukanov) writes:
>From the current DWP point of view is it possible to write:
>int x = x;
>T t(t);
>
>where T has copy constructor?
Yes, it's possible to write such code, but if the code gets executed,
the behavour is undefined.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "denis bider" <denis.bider@abm.si>
Date: 1996/11/01 Raw View
In <55arrb$ns5@toralf.uib.no>,
boukanov@kvark.fi.uib.no (Igor Boukanov)
writes:
>
>Microsoft VC++(<= 4.0) do the same and BC
accept even
>const int x = x; // constant expression with
undefined value?
>char array[x]; // array with undefined size?
>
And it can actually happen:
int a(123);
void f() {
int a(a);
}
The a declared inside f() will not have a value
of 123, as I would
expect, but will be copied onto itself,
receiving an undefined value.
(I checked it with Watcom 10.6)
denis [denis.bider@abm.si]
denis [denis.bider@abm.si]
Grammatical corrections welcome.
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1996/11/01 Raw View
In article ns5@toralf.uib.no, boukanov@kvark.fi.uib.no (Igor Boukanov) writes:
>David A. Cuthbert (dacut@ugcs.caltech.edu) wrote:
>> Wow! What a way to leave an object in an undefined state! Is this
>> problem very specific to this code (i.e., something I will probably
>> never encounter except for this test case), or are there other
>> possible situations where a similar bug can occur?
>
>Microsoft VC++(<= 4.0) do the same and BC accept even
>const int x = x; // constant expression with undefined value?
>char array[x]; // array with undefined size?
>
>So is it possible (again, from DWP point of view) to have
>at compile time a constant expression with undefined value?
The problem is the gap between the definition of an object and the
point at which it becomes initialized. An object is defined at the
point when its declarator is complete. For example:
int x = ...
You may refer to x at any point from the '=' onward. If that were not
the case, many useful constructions would be impossible. For example:
struct X { X* next; ... }; // circular list
X x = { &x, ... }; // single object points to self
The same thing applies to constructors. In particular, if you could
not refer to an object until its initialization was complete, a
constructor could not refer to already-constructed parts of the object
under construction.
It is possible to write code that uses an object before it has been
initialized:
int x; // auto variable
cout << x;
It is an error to do so. The compiler is not obligated to report
the error, because the general ase is impossible to detect at compile
time. A good compiler will warn about use of uninitialized objects when
it can reliably make the diagnosis.
The code in question,
int x = x;
is just a special case of using an uninitialized object, as someone
else has already pointed out. A good compiler should tell you about it.
---
Steve Clamage, stephen.clamage@eng.sun.com
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: martelli@cadlab.it (Alex Martelli)
Date: 1996/11/09 Raw View
Tom Payne <thp@cs.ucr.edu> writes:
>Bill Seurer <seurer@rchland.ibm.com> wrote:
>: In article <558kj7$iil@toralf.uib.no>, boukanov@sentef2.fi.uib.no
>: (Igor Boukanov) writes:
>: |> From the current DWP point of view is it possible to write:
>: |> int x = x;
>: |> T t(t);
>: |>
>: |> where T has copy constructor?
>: |>
>: |> I found that many C++ compilers accept the code without any warnings.
>: |> And of cause very unfortunately from C point it is OK.
>: Semantically and syntactically they are correct but of course they are
>: probably coding errors.
>I hope that the standard specifies that objects thus initialized have
>indeterminate and possibly illegal values, so that their subsequent
>use (other than assigning them legitimate values) yields undefined
>behavior.
But *assignment*, too, ought to be similarly "undefined behaviour"
in this case, it seems to me! Consider for example:
class X {
int *p;
public:
X(): p(0) {}
~X() { delete p; }
X(int i): p(new int(i)) {}
X(const X&x): p(x.p?new int(*x.p):0) {}
X& operator=(const X&x) {
if(this!=&x) {
delete p;
p=x.p?new int(*x.p):0;
}
return *this;
}
};
Surely the "delete p;" statement in the assignment operator will
yield undefined behaviour if "*this" is garbage at that point,
no matter how "legitimate" the argument x may be.
Should I then, when I'm designing a class meant to be "bullet
proof" against the existence of uninitialized variables of that
class (which IS, after all, the very point of having ctors,
isn't it -- "uninitialized no more"...!-), protect the copy
ctor similarly to how I normally protect the assignment operator,
i.e. with a "if(this==&x)" test under which I would actually
perform a default ctor rather than the copy ctor? It's doable,
it seems to be, but VERY tedious and error-prone, since _each_
member initializer in the list will have to be similarly cautious --
the "if" will only really work for whatever, if anything, is in
the *body* of the copy ctor, while just about every member
initializer will have a "this==&x?defaulctorcase:copyctorcase"
(yech). E.g., in the above example,
X(const X&x): p((this!=&x && x.p)?new int(*x.p):0): {}
a simple case because we have only one member initializer
and it contains a ?: anyway.
One more "trap and pitfall" that hadn't occurred to me yet...
Alex
--
DISCLAIMER: these are MY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it -- Phone: +39 (51) 597 313 [Fax: 597 120]
Cad.Lab S.p.A., v. Ronzani 7/29, 40033 Casalecchio (BO), Italia
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: boukanov@sentef2.fi.uib.no (Igor Boukanov)
Date: 1996/10/30 Raw View
Author: seurer@rchland.ibm.com (Bill Seurer)
Date: 1996/10/31 Raw View
In article <558kj7$iil@toralf.uib.no>, boukanov@sentef2.fi.uib.no (Igor Boukanov) writes:
|> From the current DWP point of view is it possible to write:
|> int x = x;
|> T t(t);
|>
|> where T has copy constructor?
|>
|> I found that many C++ compilers accept the code without any warnings.
|> And of cause very unfortunately from C point it is OK.
Semantically and syntactically they are correct but of course they are
probably coding errors. About the best you can expect (but nothing
requires it) is to get some sort of diagnostic about the use of
uninitilized variables.
--
- Bill Seurer ID Tools and Compiler Development IBM Rochester, MN
Business: BillSeurer@vnet.ibm.com Home: BillSeurer@aol.com
WWW: http://members.aol.com/BillSeurer
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: dacut@ugcs.caltech.edu (David A. Cuthbert)
Date: 1996/10/31 Raw View
Igor Boukanov <boukanov@sentef2.fi.uib.no> wrote:
>From the current DWP point of view is it possible to write:
>int x = x;
>T t(t);
>
>where T has copy constructor?
>
>I found that many C++ compilers accept the code without any warnings.
Even more alarming is the possible behavior from at least one of these
compilers (BC++ 4.52; g++ 2.7.2 didn't like it). I compiled the
following:
class A {
public:
A() { cout << "ctor "; }
A(const A&) { cout << "copy "; }
~A() { cout << "dtor "; }
};
int main() {
A a(a);
}
Borland accepted the code. I expected the output to be
ctor copy dtor dtor
where the first ctor and first dtor were on a temporary. Instead, I
got only:
copy dtor
Wow! What a way to leave an object in an undefined state! Is this
problem very specific to this code (i.e., something I will probably
never encounter except for this test case), or are there other
possible situations where a similar bug can occur? (Obviously, actual
bugs would be environment specifc; just wondering about general
possibilities here on this and other similarly-behaving compilers)
Incidentally, a quick check shows that the object is, indeed, being
copied onto itself (in BC, at least).
--
David A. Cuthbert
dacut@ugcs.caltech.edu
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Tom Payne <thp@cs.ucr.edu>
Date: 1996/11/01 Raw View
Bill Seurer <seurer@rchland.ibm.com> wrote:
: In article <558kj7$iil@toralf.uib.no>, boukanov@sentef2.fi.uib.no
: (Igor Boukanov) writes:
: |> From the current DWP point of view is it possible to write:
: |> int x = x;
: |> T t(t);
: |>
: |> where T has copy constructor?
: |>
: |> I found that many C++ compilers accept the code without any warnings.
: |> And of cause very unfortunately from C point it is OK.
: Semantically and syntactically they are correct but of course they are
: probably coding errors.
I hope that the standard specifies that objects thus initialized have
indeterminate and possibly illegal values, so that their subsequent
use (other than assigning them legitimate values) yields undefined
behavior.
Tom Payne
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]