Topic: C++ syntactic trap
Author: johnw@jove.acs.unt.edu (John R. Williams)
Date: 1996/04/15 Raw View
J. Kanze (kanze@gabi-soft.fr) wrote:
> In article <4kcrhk$aj1@hermes.acs.unt.edu> johnw@jove.acs.unt.edu (John
> R. Williams) writes:
> [Concerning a warning for `new char( 10 )'...]
> |> I agree that it is uusual to allocate a single object of a built-in type
> |> this way, but how do you propose to write this in such a way that such a
> |> warning would not be generated? All I can think of is to warn when *any*
> |> conversion occurs (this one looks pretty explicit to me), forcing you to
> |> write something like this:
> |> char *foo = new char(static_cast<char>(10));
> |> (Actually this rule doesn't seem too bad if applied only to built-in
> |> types...)
> Let's see:
> int* pi = new int( static_cast< int >( 10 ) ) ;
> Do you want the compiler to warn if you omit the static_cast (of int to
> int)?
What I meant (but perhaps did not make clear) is that the warning would
only be in the case of *conversions* (and possibly promotions). In this
case my rule would allow more comfortable syntax without a warning.
> I do not think that I have a single instance of allocation of an array
> in any of my code. Why should you make the most frequent case the most
> difficult. (And allocating a single int is not that infrequent. You
> might look at the implementation of counted_ptr in Barton and Nackman,
> for example. It is certainly more frequent than allocating an array of
> int's, at least in well written C++ code.)
I admit that since I get a copy of HP's STL I have almost entirely
stopped using array new, but OTOH I can't remeber a single time I've
allocated just one object of a built-in type. This suggests to me that
the issue is one of of style and context, not ability to program.
At any rate, I don't like my idea either--I was just throwing it out to
see what people would think.
--
class JohnWilliams: public Student, public Programmer {
public:
char const *operator&() const { return "johnw@jove.acs.unt.edu"; }
char const *homepage () const { return "http://www.unt.edu/~johnw"; }
};
[ 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: vavasis@CS.Cornell.EDU (Stephen Vavasis)
Date: 1996/04/06 Raw View
I have just spent a long time tracking down a mysterious bug (the
heap-trashing variety of bug) in my program caused by a syntactic trap
in C++. The troubling thing about this trap is that none of the unix
compilers I tried (gcc-2.7.2, Sun SC3.0.1, HP-UX cfront 3.0.3) issued
a warning about the mistake, even on the highest warning level. Only
Visual C++4.0 observed that there might be a problem. Here is an
example of the trap. This program asks the user how many asterisks,
and then prints out that many asterisks.
#include <iostream.h>
int main() {
cout << " How many *'s? ";
int sz; cin >> sz;
char* a = new char(sz + 1); // bug is here, but syntax is legal.
for (int i = 0; i < sz; i++)
a[i] = '*';
a[sz] = 0;
cout << a << endl;
delete[] a;
return 0;
}
(Does everyone see the error? I did not, even after staring at my
code for a long time. The point is that the marked statement is an
unintended cast from int to char because I used () instead of [].)
I would like to make a plea to the compiler-writers who read this
group: please issue warnings for syntactic trouble spots! Implicit
type conversion probably creates other traps that I haven't thought
of. C++ programmers like me need help from the compiler to navigate
the traps!
-- Steve Vavasis (vavasis@cs.cornell.edu)
---
[ 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: solution@gate.net (Ken Walter)
Date: 1996/04/08 Raw View
In message <4k3q4p$lkd@syn.cs.cornell.edu> - vavasis@CS.Cornell.EDU (Stephen Va
vasis) writes:
[...]
:>I would like to make a plea to the compiler-writers who read this
:>group: please issue warnings for syntactic trouble spots! Implicit
:>type conversion probably creates other traps that I haven't thought
:>of. C++ programmers like me need help from the compiler to navigate
:>the traps!
:>
[...]
C and C++ are one of the worst syntacticly designed languages around.
There is nothing to be done about it without severe redesign (a new language)
The only one I can think of that is worse is PL/1 where amost anything
you write has some meaning, just not necessarily what you expect.
Maybe, as they keep adding features to fix something, the language will break
from all the syntatic twisting and someone will define a new replacement
language with a decent syntax covering all the concepts. (Algol 00 ?)
---
[ 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: davidb@datalytics.com (David Bradley)
Date: 1996/04/08 Raw View
vavasis@CS.Cornell.EDU (Stephen Vavasis) wrote:
>I would like to make a plea to the compiler-writers who read this
>group: please issue warnings for syntactic trouble spots! Implicit
>type conversion probably creates other traps that I haven't thought
>of. C++ programmers like me need help from the compiler to navigate
>the traps!
What about when I create a normal object?
MyClass* pMyObject = new MyClass(Initializer);
Should this also generate a warning? If the syntax was exceptional,
but legal, then I'd say'd it should generate a warning. However,
this syntax is not exception and is used quite frequently.
===============================================
DISCLAIMER: I may be a member of humanity,
but I'm not a spokesman for humanity.
davidb@datalytics.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: jcoffin@rmii.com (Jerry Coffin)
Date: 1996/04/08 Raw View
In article <4kat8s$2i6k@news.gate.net>, solution@gate.net says...
[ ... ]
> C and C++ are one of the worst syntacticly designed languages around.
C and C++ - I believe that's two not one... <G> I tend to disagree as to the
meaning of your statement as well.
> There is nothing to be done about it without severe redesign (a new
> language) The only one I can think of that is worse is PL/1 where amost
> anything you write has some meaning, just not necessarily what you expect.
I'd have to guess that you've never used TECO then. Nor FORTRAN. For
instance, in parsing FORTAN, you have to deal with things like this:
do 10 i=1,10
vs.
do 10 i=1
The first is a do loop, the second a simple assignment of the value 1 to a
variable named `do 10 i'. There's no way to know for certain which you're
looking at until you find whether there's a comma after the `=', so you have
to either use a backtracking parser, or else several symbols of lookahead.
Worse, this not only has to be done in the parser, but in the lexer as well,
since it changes from having three tokens before the `=' to only one token.
In short, it's about as bad of syntax design as you can find. IMO, nothing in
either C or C++ even comes close.
> Maybe, as they keep adding features to fix something, the language will
> break from all the syntatic twisting and someone will define a new
> replacement language with a decent syntax covering all the concepts. (Algol
> 00 ?)
Hmm...how does one define when a language is "broken" ? C++ is certainly a
good deal harder to parse than C or something really simple like LISP, but is
still quite a bit easier than many others such as FORTRAN or PL/I. You
mentioned PL/I above, but may have failed to give a proper idea of how
difficult it really is to compile; though I suspect this has changed more
recently, at one time it was claimed that IBM's PL/I level F compiler
consisted of over 100 passes... (I don't know how much of this was due to
language complexity and how much to simply allow the compiler to run in
minimal memory though.) I'm not particuarly certain there's a direct
corollary between difficulty of implementation, and "brokeness", though it
seems likely that if a language is difficult to implement that individual
implementations are more likely to be broken. (Note that here I'm separating
between the language being broken and the implementation being broken.)
Later,
Jerry.
---
[ 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: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/04/09 Raw View
In article <4k3q4p$lkd@syn.cs.cornell.edu> vavasis@CS.Cornell.EDU
(Stephen Vavasis) writes:
|> I have just spent a long time tracking down a mysterious bug (the
|> heap-trashing variety of bug) in my program caused by a syntactic trap
|> in C++. The troubling thing about this trap is that none of the unix
|> compilers I tried (gcc-2.7.2, Sun SC3.0.1, HP-UX cfront 3.0.3) issued
|> a warning about the mistake, even on the highest warning level. Only
|> Visual C++4.0 observed that there might be a problem. Here is an
|> example of the trap. This program asks the user how many asterisks,
|> and then prints out that many asterisks.
|> #include <iostream.h>
|> int main() {
|> cout << " How many *'s? ";
|> int sz; cin >> sz;
|> char* a = new char(sz + 1); // bug is here, but syntax is legal.
|> for (int i = 0; i < sz; i++)
|> a[i] = '*';
|> a[sz] = 0;
|> cout << a << endl;
|> delete[] a;
|> return 0;
|> }
|> (Does everyone see the error? I did not, even after staring at my
|> code for a long time. The point is that the marked statement is an
|> unintended cast from int to char because I used () instead of [].)
|> I would like to make a plea to the compiler-writers who read this
|> group: please issue warnings for syntactic trouble spots! Implicit
|> type conversion probably creates other traps that I haven't thought
|> of. C++ programmers like me need help from the compiler to navigate
|> the traps!
The problem is that most of the time, it is the initialization of a
single object (the form that you used) which is wanted. In practice,
one simply doesn't allocate arrays. Thus, your program would typically
be more like:
int
main()
{
int results( EXIT_FAILURE ) ;
cout << " How many *'s? " << flush ;
int sz ;
cin >> sz ;
if ( ! cin || sz < 0 )
cerr << "Illegal input value or EOF" << endl ;
else
{
cout << string( sz , '*" ) << endl ;
result = EXIT_SUCCESS ;
}
return results ;
}
Even if the purpose of the exercise is to use a loop to fill a vector,
the else branch of the if would be something like:
{
vector< char > a( sz + 1 ) ;
// ...
}
(Note that in this case, the input validation would have to reject the
value of INT_MAX, as well as negative values, in order to avoid a
possible overflow.)
--
James Kanze (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
---
[ 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: johnw@jove.acs.unt.edu (John R. Williams)
Date: 1996/04/09 Raw View
Stephen Vavasis (vavasis@CS.Cornell.EDU) wrote:
> #include <iostream.h>
> int main() {
> cout << " How many *'s? ";
> int sz; cin >> sz;
> char* a = new char(sz + 1); // bug is here, but syntax is legal.
> for (int i = 0; i < sz; i++)
> a[i] = '*';
> a[sz] = 0;
> cout << a << endl;
> delete[] a;
> return 0;
> }
> (Does everyone see the error? I did not, even after staring at my
> code for a long time. The point is that the marked statement is an
> unintended cast from int to char because I used () instead of [].)
> I would like to make a plea to the compiler-writers who read this
> group: please issue warnings for syntactic trouble spots! Implicit
> type conversion probably creates other traps that I haven't thought
> of. C++ programmers like me need help from the compiler to navigate
> the traps!
At the risk of sounding insulting, I wonder if you have been using C++
long. This strikes being similar the the error in the latest
PC-Lint ads ("for (i = 0; i <= 10; i++)"): It looks like it would be easy
to make but does not occur often in practice because programmers who use
the language often are simply not accustomed to writing the incorrect
version and would never do it under normal circumstances.
I agree that it is uusual to allocate a single object of a built-in type
this way, but how do you propose to write this in such a way that such a
warning would not be generated? All I can think of is to warn when *any*
conversion occurs (this one looks pretty explicit to me), forcing you to
write something like this:
char *foo = new char(static_cast<char>(10));
(Actually this rule doesn't seem too bad if applied only to built-in
types...)
--
class JohnWilliams: public Student, public Programmer {
public:
char const *operator&() const { return "johnw@jove.acs.unt.edu"; }
char const *homepage () const { return "http://www.unt.edu/~johnw"; }
};
---
[ 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: Sean A Corfield <sean@corf.demon.co.uk>
Date: 1996/04/10 Raw View
In article <4k3q4p$lkd@syn.cs.cornell.edu>,
vavasis@CS.Cornell.EDU (Stephen Vavasis) wrote:
|> The troubling thing about this trap is that none of the unix
|> compilers I tried (gcc-2.7.2, Sun SC3.0.1, HP-UX cfront 3.0.3) issued
|> a warning about the mistake, even on the highest warning level. Only
|> Visual C++4.0 observed that there might be a problem. Here is an
|> example of the trap.
...
|> char* a = new char(sz + 1); // bug is here, but syntax is legal.
Perhaps you should try one of the C++ lints? There are many, many areas
where the (draft) standard allows constructs of dubious value but the
committee have always been careful not to remove a construct solely on the
grounds that programmers might shoot themselves in the foot.
Sean A Corfield
Object Consultancy Services
C++ - Beyond the ARM - http://nw.demon.co.uk/ocsltd/c++/
---
[ 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: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/04/10 Raw View
In article <4kcrhk$aj1@hermes.acs.unt.edu> johnw@jove.acs.unt.edu (John
R. Williams) writes:
[Concerning a warning for `new char( 10 )'...]
|> I agree that it is uusual to allocate a single object of a built-in type
|> this way, but how do you propose to write this in such a way that such a
|> warning would not be generated? All I can think of is to warn when *any*
|> conversion occurs (this one looks pretty explicit to me), forcing you to
|> write something like this:
|> char *foo = new char(static_cast<char>(10));
|> (Actually this rule doesn't seem too bad if applied only to built-in
|> types...)
Let's see:
int* pi = new int( static_cast< int >( 10 ) ) ;
Do you want the compiler to warn if you omit the static_cast (of int to
int)?
I do not think that I have a single instance of allocation of an array
in any of my code. Why should you make the most frequent case the most
difficult. (And allocating a single int is not that infrequent. You
might look at the implementation of counted_ptr in Barton and Nackman,
for example. It is certainly more frequent than allocating an array of
int's, at least in well written C++ code.)
--
James Kanze (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
---
[ 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 ]