Topic: Dumbed-down
Author: kanze.james@neuf.fr (James Kanze)
Date: Tue, 15 Aug 2006 18:50:43 GMT Raw View
Fernando Cacciola wrote:
> Greg Herlihy wrote:
>> [...]
>> After all, if 70 lines of highly specialized template code
>> are needed just to determine
> If "70 lines of highly specialized template code" refers to
> the boost implementation then you should know that the purpose
> of that code is not just to determine if a conversion is in
> range for a target type but also to perform the range check as
> efficiently as possible. For example, if you convert an
> "unsigned" to an "int" then the actual range checking tests
> only for negative values; and if you convert an "int" to a
> "double" then a runtime range check is totally ellided.
> A big part of the code complextity in the boost implementation
> comes from deciding at compile time whether runtime range
> checking is actually needed, and if it is what exactly is
> minimally required.
Not just. I've not looked at it, but a large part of the
problem is avoiding the implicit conversions which take place,
causing (sometimes) signed values to be compared as unsigned,
etc. And dealing with the fact that std::numeric_limits<>::min
has different semantics for integral values and for floating
point.
>> whether converting a floating point to integer value wouldn't
>> core dump in C++
> If the conversion core dumps then a checked conversion is
> probably unneeded.
Agreed. The problem is that it doesn't, always. The problem is
that you don't really know, in advance, what it will do. (At
least not portably.)
--=20
James Kanze kanze.james@neuf.fr
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Wed, 16 Aug 2006 16:26:59 GMT Raw View
kanze.james@neuf.fr (James Kanze) writes:
> Fernando Cacciola wrote:
>
>> A big part of the code complextity in the boost implementation
>> comes from deciding at compile time whether runtime range
>> checking is actually needed, and if it is what exactly is
>> minimally required.
>
> Not just. I've not looked at it, but a large part of the
> problem is avoiding the implicit conversions which take place,
> causing (sometimes) signed values to be compared as unsigned,
> etc. And dealing with the fact that std::numeric_limits<>::min
> has different semantics for integral values and for floating
> point.
Since Fernando wrote the Boost implementation I think he knows "just"
what problems it's solving and how much size that contributes ;-D
--
Dave Abrahams
Boost Consulting
www.boost-consulting.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Tue, 1 Aug 2006 11:43:50 CST Raw View
Greg Herlihy wrote:
> James Kanze wrote:
> > Greg Herlihy wrote:
> > > "Krzysztof Zelechowski" wrote:
> > >> Uzytkownik "kanze" <kanze@gabi-soft.fr> napisal w wiadomosci
> > >> news:1153126683.242065.284470@35g2000cwc.googlegroups.com...
> > >>> "Krzysztof Zelechowski" wrote:
> > >>>> assert(Target(x) == x);
> > >>> You may get an implementation defined signal before the
> > >>> assert trips (which probably doesn't matter). You may
> > >>> also fail to trip even when you should, if the
> > >>> conversion is between signed and unsigned types, e.g.
> > >>> Target is unsigned int, Source is int, and the value of
> > >>> x is -3.
> > >> My code should be used when the compiler issues a
> > >> warning. Should there be a warning about an implicit
> > >> cast from int to unsigned int, my code would fail. But
> > >> the OP wanted to handle a warning about truncation.
> > > It is also possible when converting from one numeric type
> > > to another to have an assertion detect either value
> > > truncation or a signed/unsigned value mismatch between
> > > the original and converted value. The key is to have the
> > > assertion perform the comparison with a numeric type of
> > > sufficient range and resolution to resolve the inequality
> > > (in other words, a long double):
> > > typedef long double LongDouble;
> > > ...
> > > assert( LongDouble(x) == LongDouble( Target(x)));
> > The whole point of the verifications is to avoid doing
> > Target(x), which may have implementation defined behavior,
> > and in fact core dumps for some values and some Target types
> > on may systems.
> Then the concern is overblown. As long as Target(x) is not
> undefined, than the expression is perfectly safe and will have
> either an implementation-defined or a well-defined value - (in
> no event would it ever have implementation-defined
> "behavior").
That's not what the standard says. The C++ standard is rather
vague about what could happen, but the C standard is very clear:
either an implementation defined value, or an
implementation-defined signal.
In practice, I suspect that on most modern implementations, it
will depend on the settings of the FPU: C99 requires the
presence of an option for trapping, and it would be surprising
if implementations of C++ didn't offer it as well.
> Furthermore, while a program could test
> numeric_limits<Target>::traps to determine whether the Target
> type traps at all, it is not even necessary in this case.
> There is no chance that initializing a Target type with a
> valid numeric value could ever trap - since only arithmetic
> operations can trap.
The standard says differently. At least, it says that the
conversion may raise an implementation defined signal.
> Initialization is not an arithmetic operation.
> After all, if 70 lines of highly specialized template code are
> needed just to determine whether converting a floating point
> to integer value wouldn't core dump in C++, who in their right
> mind would ever decide to write a numerical program in C++?
Maybe those who understand the language, and know how to use it
for there applications. Or those who want the machine to trap
on an error condition. If you know the types involved, it's
very easy to write the code. The problem is to write it
generically without knowledge of the types, and correctly handle
all of the oddities concerning unsigned and signed comparisons
and promotions.
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Tue, 1 Aug 2006 11:44:51 CST Raw View
kuyper@wizard.net wrote:
> James Kanze wrote:
> > ThosRTanner wrote:
> > > My experience with IDEs is that they provide
> > > a) "Integrated" compilation which takes you to the point of an error on
> > > compilation
> > That's a feature of the editor. All of the editors I'm aware of
> > have it.
> The environment you work in sounds quite different from the
> ones I've used. The only editors I'm aware of with that
> feature are parts of IDEs. The main editor I use is vi, and it
> doesn't seem to have that feature.
I should have said *modern* editors. It's true the vi doesn't
have this; nor does ed. Vim and emacs do, however---vim is
largely compatible with vi, and emacs has a viper mode which
more or less emulates vi, so why not change? (If you're under
Linux, when you request vi, you typically get vim anyway.)
I'm curious what kind of environment you work in. vi is a
typical Unix editor---the only times I've seen it elsewhere have
been with Unix emulation kits (MKS ToolKit, UWin, etc.). And a
typical Unix today comes with not only vi (and ed), but also
emacs, and sometimes vim as well. (The Sun development
environment comes with both emacs and vim, and uses them as the
editor in its IDE.)
> .
> > > i) when you are using an object of a particular class, you can select
> > > an available method or member of the class
> > That's also a feature of the editor. All of the editors I'm
> > aware of have an automatic completion feature.
> I've only seen that feature in editors that were part of an IDE.
Well, vim and emacs often are part of an IDE. But the features
are part of the editor, and are there, IDE or not.
> .
> > > ii) syntax validation (or syntax deduction) when typing the code.
> > Again, most editors have this to some degree, e.g. matching
> > braces, automatic indentation, etc.
> Again, I've only seen that in IDE editors.
Come now, even vi had that. Twenty years ago. Not to the
degree you get today, of course, but matching parentheses,
braces, etc., and automatic indention (not syntax dependant)
where there.
Still, I'd say that the syntax dependant automatic indention of
vim or emacs is probably the single one feature I depend most
on. Hit return at the end of a statement, and the cursor
positions itself in the wrong column, and you know right away
you've screwed something up: mismatches a parentheses, forgotten
a semi-colon, or something along those lines.
None of them to date handles matching <...> for templates. And
I suspect that they won't very soon; unlike (...), [...] and
{...}, the < and the > aren't necessarily bracing, and
determining when they are, and when they are just less than or
more than, requires a lot more knowledge of C++ than any general
purpose editor is likely to have anytime soon.
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Fernando Cacciola" <fernando_cacciola@hotmail.com>
Date: Wed, 2 Aug 2006 15:57:13 CST Raw View
Greg Herlihy wrote:
> [...]
> After all, if 70 lines of highly specialized template code are needed
> just to determine
>
If "70 lines of highly specialized template code" refers to the boost
implementation then you should know that the purpose of that code is not
just to determine if a conversion is in range for a target type but also
to perform the range check as efficiently as possible.
For example, if you convert an "unsigned" to an "int" then the actual range
checking tests only for negative values; and if you convert an "int" to a
"double" then a runtime range check is totally ellided.
A big part of the code complextity in the boost implementation comes from
deciding at compile time whether runtime range checking is actually needed,
and if it is what exactly is minimally required.
> whether converting a floating point to integer value
> wouldn't core dump in C++
>
If the conversion core dumps then a checked conversion is probably unneeded.
The real practical problem ocurrs when the conversion silently fails,
truncating, or even worse, warpping around, the result.
> who in their right mind would ever decide
> to write a numerical program in C++?
Well, I have been writing numerical programs in C++ for a decade and a half
now FWIW
But then none of my friends would say I'm in my right mind though
Fernando Cacciola
SciSoft
http://fcacciola.50webs.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Tue, 8 Aug 2006 07:05:05 CST Raw View
Frederick Gotham wrote:
> The objective of the function is to increment a pointer by a specified
> number of bytes -- it's the client's problem if they end up with a pointer
> to a misaligned object.
>
> One plausible use of it would be, (assuming we have an "alignof" operator):
>
> AdvPtr(p, alignof(*p));
>
>
alignof is non-standard, thus, non-portable.
Though, there is tr1::alignment_of... I didn't thought of it, probably
because tr1 is not yet widely supported.
> > Back to your question:
> >> And again we have melodramatic use of "dangerous". There's nothing
> >> wrong with the way I use casts.
> >
> > The mere interface of your function is *dangerous*!
> > If the caller pass a non-correctly aligned "bytes" argument, it will
> > have non-portable, implementation-specific results.
>
>
> Which is why the caller shouldn't pass an incorrect value for "bytes".
>
> Is array indexing dangerous? Nothing's to stop me writing:
>
> int array[8];
>
> array[242] = 4;
>
>
> Quick! Let's ban array indexing!
>
My point was that it was very very low-level.
In fact, without tr1, the only usage that I can see is incrementation
with values multiple of sizeof(T).
I agree that with tr1 this function can make sense.
I just hope that this type of low-level thing occupy less than 5% of
your programs (except if you are developing drivers, OS kernels or such
low-level applications).
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "AllanW" <allan_w@my-dejanews.com>
Date: Tue, 8 Aug 2006 11:23:22 CST Raw View
James Kanze wrote:
> Untested, but there's got to be a simpler solution.
template <class Target, class Source>
inline Target numeric_cast(Source x)
{
Target y = static_cast<Target>(x);
Source z = static_cast<Source>(y);
assert(z==x);
return y;
}
Also untested, but certainly simpler...
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "AllanW" <allan_w@my-dejanews.com>
Date: Wed, 9 Aug 2006 06:32:31 CST Raw View
> Frederick Gotham wrote:
> > Why should expert programmers be burdened with unwieldy names? It insults
> > human intelligence.
James Dennett wrote:
> Most good programmers accept that they make mistakes, and
> embrace tools and techniques that help to reduce the
> frequency of those mistakes.
Personally, I embrace SOME of these tools, but not all of them.
There was a computer language called CSP. I think it stood for
Cross-Systems Product; despite this, as far as I know it was only
ever implemented on IBM mainframes (but under multiple operating
systems). I don't know if this language is still in use, but I hope
not.
CSP was allegedly a "fourth-generation language" (this phrase too
seems to have died, possibly from being so overhyped that it lost
any semblance of meaning). But this particular language "helped"
the programmer by tying his hands, preventing him from making
certain mistakes.
What I find most memorable about this language was that it
prevented programmers from making procedures too complicated,
by limiting procedures to only one I/O statement. So even simple
programs with only 5 I/O statements, had to be written as 5
procedures calling each other.
Early in my career, this was the first programming language that
I ever worked on, that I didn't put on my r sum ... I figured that if
knowing CSP would help me get a certain job, I didn't want that job.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kwikius" <andy@servocomm.freeserve.co.uk>
Date: Wed, 9 Aug 2006 09:12:14 CST Raw View
AllanW wrote:
> James Kanze wrote:
> > Untested, but there's got to be a simpler solution.
>
> template <class Target, class Source>
> inline Target numeric_cast(Source x)
> {
> Target y = static_cast<Target>(x);
> Source z = static_cast<Source>(y);
> assert(z==x);
> return y;
> }
>
> Also untested, but certainly simpler...
It might be worth you guys trying this stuff out, and then saying its
simpler, meanwhile I am still happy to stick with
boost::numeric::converter:
#include <limits>
#include <cassert>
#include <iostream>
template <class Target, class Source>
inline Target numeric_cast(Source source)
{
Target target = static_cast<Target>(source);
Source back_to_source = static_cast<Source>(target);
std::cout << "source = " << source <<'\n';
std::cout << "target = " << target <<'\n';
std::cout << "back_to_source = " << back_to_source <<'\n';
// assert(back_to_source==source);
return target;
}
int main()
{
long v1 = std::numeric_limits<long>::max();
numeric_cast<float>(v1);
}
/*
output:
in VC7.1 32 bit windows
source = 2147483647
target = 2.14748e+009
back_to_source = -2147483648
output in gcc 32 bit windows
source = 2147483647
target = 2.14748e+09
back_to_source = -2147483648
*/
regards
Andy Little
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: david.thompson1@worldnet.att.net (Dave Thompson)
Date: Mon, 14 Aug 2006 16:18:56 GMT Raw View
On Tue, 1 Aug 2006 11:43:50 CST, "kanze" <kanze@gabi-soft.fr> wrote:
> Greg Herlihy wrote:
> > James Kanze wrote:
<snip>
> > > The whole point of the verifications is to avoid doing
> > > Target(x), which may have implementation defined behavior,
> > > and in fact core dumps for some values and some Target types
> > > on may systems.
>
> > Then the concern is overblown. As long as Target(x) is not
> > undefined, than the expression is perfectly safe and will have
> > either an implementation-defined or a well-defined value - (in
> > no event would it ever have implementation-defined
> > "behavior").
>
> That's not what the standard says. The C++ standard is rather
> vague about what could happen, but the C standard is very clear:
> either an implementation defined value, or an
> implementation-defined signal.
>
Only between integer types, and only in C99 which postdates C++98.
For floating-point (and floating-point to integer) value outside
representable range is (still) Undefined Behavior in C99.
Most hardware I've seen either does produce some value
or a trap which might become a signal, but that's not required.
> In practice, I suspect that on most modern implementations, it
> will depend on the settings of the FPU: C99 requires the
> presence of an option for trapping, and it would be surprising
> if implementations of C++ didn't offer it as well.
>
Only for floating-point and only if the implementation claims to
support IEC 60559 aka IEEE which is optional. Hardware that supports
IEEE (or could) is common and getting more so, so _reasonable_
implementations should support it, but it's not required.
- David.Thompson1 at worldnet.att.net
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kanze.james@neuf.fr (James Kanze)
Date: Sun, 30 Jul 2006 19:37:45 GMT Raw View
kwikius wrote:
> James Kanze wrote:
>> kwikius wrote:
>> > James Kanze wrote:
>> >> Untested, but there's got to be a simpler solution.
>> > http://www.boost.org/libs/numeric/conversion/doc/index.html
>> When I look at the paragraph "Range Checking Logic", in the
>> documentation, I'm not sure that they've found a simpler
>> solution.
> Don't know quite how to put this, but their solution must be
> simpler, since it actually works. Heres a quick test of your
> solution, tried in VC7.1 and gcc4.0
Actually works doesn't necessarily mean simpler. The original
suggestion I was responding to was far, far simpler than
anything in Boost or that I have proposed. It didn't work for
negative values, of course, but it was simple.:-)
For the rest, I don't doubt that the solution in Boost works; it
wouldn't have made it into Boost if it hadn't. It even treats a
number of issues that hadn't even occured to me, like rounding
mode. (It's also well documented, which for publicly available
code outside of Boost is rather exceptional.)
> int main()
> {
> int result1 =3D
> numeric_cast<int>(static_cast<double>(std::numeric_limits<int>::max())=
);
> std::cout << result1 <<'\n';
> int result2 =3D
> numeric_cast<int>(static_cast<double>(std::numeric_limits<int>::max())
> + 1);
> std::cout << result2 <<'\n';
> }
> In my definition of simpler, the boost version is *considerably*
> simpler ....... ;-)
I'm not sure what point you're trying to argue. If you mean
using a working solution from Boost is a lot simpler than
writing one of your own which probably doesn't work for a few
corner cases, then I fully agree. Using working code written by
someone else is always simpler than trying to develop something
on your own.
I was talking not about use in a project, but about the
implementation. I would be very surprised that the internal
implementation of Boost was very simple, given all of the issues
that the explicitly address.
--=20
James Kanze kanze.james@neuf.fr
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kanze.james@neuf.fr (James Kanze)
Date: Sun, 30 Jul 2006 19:38:10 GMT Raw View
Greg Herlihy wrote:
> James Kanze wrote:
>> Untested, but there's got to be a simpler solution.
> How about:
>
> assert( static_cast<Source>( static_cast<Target>(x)) =3D=3D x );
> ?
Full of implementation defined behavior. Where Source is a
floating point type, and Target an integral type, it will core
dump on a lot of implementations.
--=20
James Kanze kanze.james@neuf.fr
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kanze.james@neuf.fr (James Kanze)
Date: Sun, 30 Jul 2006 19:38:30 GMT Raw View
Greg Herlihy wrote:
> "Krzysztof Zelechowski" wrote:
>> Uzytkownik "kanze" <kanze@gabi-soft.fr> napisal w wiadomosci
>> news:1153126683.242065.284470@35g2000cwc.googlegroups.com...
>>> "Krzysztof Zelechowski" wrote:
>>>> assert(Target(x) =3D=3D x);
>>> You may get an implementation defined signal before the assert
>>> trips (which probably doesn't matter). You may also fail to
>>> trip even when you should, if the conversion is between signed
>>> and unsigned types, e.g. Target is unsigned int, Source is int,
>>> and the value of x is -3.
>> My code should be used when the compiler issues a warning.
>> Should there be a warning about an implicit cast from int to
>> unsigned int, my code would fail. But the OP wanted to
>> handle a warning about truncation.
> It is also possible when converting from one numeric type to
> another to have an assertion detect either value truncation or
> a signed/unsigned value mismatch between the original and
> converted value. The key is to have the assertion perform the
> comparison with a numeric type of sufficient range and
> resolution to resolve the inequality (in other words, a long
> double):
> typedef long double LongDouble;
> ...
> assert( LongDouble(x) =3D=3D LongDouble( Target(x)));
The whole point of the verifications is to avoid doing
Target(x), which may have implementation defined behavior, and
in fact core dumps for some values and some Target types on may
systems.
--=20
James Kanze kanze.james@neuf.fr
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kanze.james@neuf.fr (James Kanze)
Date: Sun, 30 Jul 2006 20:03:58 GMT Raw View
ThosRTanner wrote:
> James Kanze wrote:
>> ThosRTanner wrote:
>> > Mind you C++ with an IDE is also a much better language than
>> > C++ with an editor.
>> And what is C++ with an IDE other than C++ with a particular
>> editor imposed on you? If that editor happens to be better than
>> the one you would otherwise use, it's an improvement. If not,
>> it's anything but an improvement.
> My experience with IDEs is that they provide
> a) "Integrated" compilation which takes you to the point of an error o=
n
> compilation
That's a feature of the editor. All of the editors I'm aware of
have it.
> b) Code completion so that
> i) when you are using an object of a particular class, you can select
> an available method or member of the class
That's also a feature of the editor. All of the editors I'm
aware of have an automatic completion feature. On the other
hand, they generally don't understand C++ grammar and scoping
rules, so the completion set is all visible symbols, and not
just the symbols which would be legal in a C++ program at this
point.
I'm still up in the air with regards to the advantages of this.
It's certainly a plus that, having typed std::v, completion
finds vector, and nothing else. For user defined symbols, on
the other hand, it's less clear; it's certainly not rare for me
to conceptually add a member variable to a class because I need
it, and to start using it in the functions, before I've actually
edited the class definition to include it.
> ii) syntax validation (or syntax deduction) when typing the code.
Again, most editors have this to some degree, e.g. matching
braces, automatic indentation, etc. Does syntax validation
beyond this point help that much? (It could, of course. When
you define a local variable which is in fact a function
declaration, for example, a really C++ aware editor could point
this out, and request confirmation. In the end, however, it's
not a question of IDE or not; it's a question of how much C++
the editor knows.)
> c) Easier source modification when debugging
I'll admit that I don't get this one. How does the editor play
a role here? You have a log file and a post-mortem (core dump
or whatever), which you analyse with various tools. Does the
IDE understand your log file format, to be able to position you
directly at the line which produced the log? (The best I've
seen in non-IDE editors is that you position the cursor on the
filename in one window, enter a command, and a second window
opens on that file. Although it should be possible to create a
command script in vim which would parse something like
[abc.cc:123] to open a new frame at line 123 of file abc.cc.)
> I realise that some editors and debuggers tend towards the
> functionality of IDEs, but generally IDE's do it better. And
> most IDEs can have their editing behaviour customised.
It's probably true that most special purpose IDE editors
understand more C++ than general purpose editors line vim or
emacs. On the other hand, they seem to be missing a number of
other features, many of which are, at least for me, more
important. (And of course, not a few IDE's use an external
editor.)
But that's what I said to begin with: the choice is the editor.
If the IDE provides a better editor, it is a win. If it
doesn't, it isn't (and I can't be bothered with the Unix IDE's
which use vim or emacs as their editor---I don't see any
advantage in them compared to using vim or emacs directly).
> I am an incredibly bad typist, so anything that can reduce my
> level of mistakes is all to the good
Any thing that can reduce the number of typing errors is all to
the good. Unless you're such a good typist that you never make
mistakes. And I don't think that anyone is that good.
--=20
James Kanze kanze.james@neuf.fr
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Mon, 31 Jul 2006 11:13:03 CST Raw View
James Kanze wrote:
> Greg Herlihy wrote:
> > "Krzysztof Zelechowski" wrote:
> >> Uzytkownik "kanze" <kanze@gabi-soft.fr> napisal w wiadomosci
> >> news:1153126683.242065.284470@35g2000cwc.googlegroups.com...
> >>> "Krzysztof Zelechowski" wrote:
> >>>> assert(Target(x) == x);
> >>> You may get an implementation defined signal before the assert
> >>> trips (which probably doesn't matter). You may also fail to
> >>> trip even when you should, if the conversion is between signed
> >>> and unsigned types, e.g. Target is unsigned int, Source is int,
> >>> and the value of x is -3.
>
> >> My code should be used when the compiler issues a warning.
> >> Should there be a warning about an implicit cast from int to
> >> unsigned int, my code would fail. But the OP wanted to
> >> handle a warning about truncation.
>
> > It is also possible when converting from one numeric type to
> > another to have an assertion detect either value truncation or
> > a signed/unsigned value mismatch between the original and
> > converted value. The key is to have the assertion perform the
> > comparison with a numeric type of sufficient range and
> > resolution to resolve the inequality (in other words, a long
> > double):
>
> > typedef long double LongDouble;
> > ...
> > assert( LongDouble(x) == LongDouble( Target(x)));
>
> The whole point of the verifications is to avoid doing
> Target(x), which may have implementation defined behavior, and
> in fact core dumps for some values and some Target types on may
> systems.
Then the concern is overblown. As long as Target(x) is not undefined,
than the expression is perfectly safe and will have either an
implementation-defined or a well-defined value - (in no event would it
ever have implementation-defined "behavior"). Furthermore, while a
program could test numeric_limits<Target>::traps to determine whether
the Target type traps at all, it is not even necessary in this case.
There is no chance that initializing a Target type with a valid numeric
value could ever trap - since only arithmetic operations can trap.
Initialization is not an arithmetic operation.
After all, if 70 lines of highly specialized template code are needed
just to determine whether converting a floating point to integer value
wouldn't core dump in C++, who in their right mind would ever decide to
write a numerical program in C++?
Greg
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Mon, 31 Jul 2006 11:13:34 CST Raw View
James Kanze wrote:
> ThosRTanner wrote:
> > James Kanze wrote:
> >> ThosRTanner wrote:
>
> >> > Mind you C++ with an IDE is also a much better language than
> >> > C++ with an editor.
>
> >> And what is C++ with an IDE other than C++ with a particular
> >> editor imposed on you? If that editor happens to be better than
> >> the one you would otherwise use, it's an improvement. If not,
> >> it's anything but an improvement.
>
> > My experience with IDEs is that they provide
> > a) "Integrated" compilation which takes you to the point of an error on
> > compilation
>
> That's a feature of the editor. All of the editors I'm aware of
> have it.
I use nedit, and I haven't worked out how to make it do that yet.
Therefore I don't think it's true to say that all editors have that
feature. However, I know that all IDE's do.
PS I hate emacs and vim.
> > b) Code completion so that
> > i) when you are using an object of a particular class, you can select
> > an available method or member of the class
>
> That's also a feature of the editor.
It's always a feature of (the editor in) an IDE. Not always of an
editor.
> All of the editors I'm
> aware of have an automatic completion feature. On the other
> hand, they generally don't understand C++ grammar and scoping
> rules, so the completion set is all visible symbols, and not
> just the symbols which would be legal in a C++ program at this
> point.
I don't think that's much help. Certainly in our ghastly software,
where nearly every conceivable combination of characters is accessible
from the global namespace...
> I'm still up in the air with regards to the advantages of this.
> It's certainly a plus that, having typed std::v, completion
> finds vector, and nothing else. For user defined symbols, on
> the other hand, it's less clear; it's certainly not rare for me
> to conceptually add a member variable to a class because I need
> it, and to start using it in the functions, before I've actually
> edited the class definition to include it.
Umm. I'd edit the class first in that case - if only because I know
I'll get compilation errors if I don't edit it because I'll forget
otherwise. Anyway, in a decent editor, it'd just mean you had to type
it out in full till you've provided a definition (again, in an IDE I'd
expect something like 'create declaration for xxxx in class/on stack/'
options to appear fairly quickly)
> > ii) syntax validation (or syntax deduction) when typing the code.
>
> Again, most editors have this to some degree, e.g. matching
> braces, automatic indentation, etc.
That's not so much help, except when typing in, and the automatic
indentation works the way I like to indent code (almost invariably
never). I sort of meant like some editors/IDEs do, like on typing
if<space> they work out you are likely to then type (, ) ( and } in
short order, so do it for you and let you fill the spaces in.
> Does syntax validation
> beyond this point help that much? (It could, of course. When
> you define a local variable which is in fact a function
> declaration, for example, a really C++ aware editor could point
> this out, and request confirmation. In the end, however, it's
> not a question of IDE or not; it's a question of how much C++
> the editor knows.)
> > c) Easier source modification when debugging
>
> I'll admit that I don't get this one. How does the editor play
> a role here?
As in when using the IDE to step through source code (debugging
existing code,
rather than debugging from core file - though really I'd hope an IDE
/could/ debug from a core file). It's the debug, look at variables,
find line in error, change line, rebuild code, substitute new code in
executable and carry on debugging from where you were.
OK, that can be tricky, but I've seen it done from time to time with
varying levels of success. But ONLY in IDEs - never in editors, or
debuggers.
> You have a log file and a post-mortem (core dump
> or whatever), which you analyse with various tools. Does the
> IDE understand your log file format, to be able to position you
> directly at the line which produced the log? (The best I've
> seen in non-IDE editors is that you position the cursor on the
> filename in one window, enter a command, and a second window
> opens on that file. Although it should be possible to create a
> command script in vim which would parse something like
> [abc.cc:123] to open a new frame at line 123 of file abc.cc.)
>
> > I realise that some editors and debuggers tend towards the
> > functionality of IDEs, but generally IDE's do it better. And
> > most IDEs can have their editing behaviour customised.
>
> It's probably true that most special purpose IDE editors
> understand more C++ than general purpose editors line vim or
> emacs. On the other hand, they seem to be missing a number of
> other features, many of which are, at least for me, more
> important. (And of course, not a few IDE's use an external
> editor.)
>
> But that's what I said to begin with: the choice is the editor.
> If the IDE provides a better editor, it is a win. If it
> doesn't, it isn't (and I can't be bothered with the Unix IDE's
> which use vim or emacs as their editor---I don't see any
> advantage in them compared to using vim or emacs directly).
Well, I think the development environment isn't just the editor. Given
a development environment with a reasonable editor/debugger with
reasonable integration between editor and source code, or good
editor/reasonable debugger/no integration, I'd probably go for the
integrated environment. However if it had an editor I couldn't work
with even if I was paid the same as a footballer, then I'd think
differently. As I hate emacs / vim, I guess my perspective might be a
little different to yours ;-)
> > I am an incredibly bad typist, so anything that can reduce my
> > level of mistakes is all to the good
>
> Any thing that can reduce the number of typing errors is all to
> the good.
Didn't I just say that?
> Unless you're such a good typist that you never make
> mistakes. And I don't think that anyone is that good.
When I worked in a printing firm, their compositors were required to
achieve 99.9% accuracy. That works out at about 1 typo per page of book
I think. Secretarial courses only required 95%. I don't think I achieve
even that at first hit.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kuyper@wizard.net
Date: Mon, 31 Jul 2006 12:26:00 CST Raw View
James Kanze wrote:
> ThosRTanner wrote:
.
> > My experience with IDEs is that they provide
> > a) "Integrated" compilation which takes you to the point of an error on
> > compilation
>
> That's a feature of the editor. All of the editors I'm aware of
> have it.
The environment you work in sounds quite different from the ones I've
used. The only editors I'm aware of with that feature are parts of
IDEs. The main editor I use is vi, and it doesn't seem to have that
feature.
.
> > i) when you are using an object of a particular class, you can select
> > an available method or member of the class
>
> That's also a feature of the editor. All of the editors I'm
> aware of have an automatic completion feature.
I've only seen that feature in editors that were part of an IDE.
.
> > ii) syntax validation (or syntax deduction) when typing the code.
>
> Again, most editors have this to some degree, e.g. matching
> braces, automatic indentation, etc.
Again, I've only seen that in IDE editors.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Dennett <jdennett@acm.org>
Date: Tue, 1 Aug 2006 00:17:15 CST Raw View
Greg Herlihy wrote:
> James Kanze wrote:
>> Greg Herlihy wrote:
>> > "Krzysztof Zelechowski" wrote:
>> >> Uzytkownik "kanze" <kanze@gabi-soft.fr> napisal w wiadomosci
>> >> news:1153126683.242065.284470@35g2000cwc.googlegroups.com...
>> >>> "Krzysztof Zelechowski" wrote:
>> >>>> assert(Target(x) == x);
>> >>> You may get an implementation defined signal before the assert
>> >>> trips (which probably doesn't matter). You may also fail to
>> >>> trip even when you should, if the conversion is between signed
>> >>> and unsigned types, e.g. Target is unsigned int, Source is int,
>> >>> and the value of x is -3.
>>
>> >> My code should be used when the compiler issues a warning.
>> >> Should there be a warning about an implicit cast from int to
>> >> unsigned int, my code would fail. But the OP wanted to
>> >> handle a warning about truncation.
>>
>> > It is also possible when converting from one numeric type to
>> > another to have an assertion detect either value truncation or
>> > a signed/unsigned value mismatch between the original and
>> > converted value. The key is to have the assertion perform the
>> > comparison with a numeric type of sufficient range and
>> > resolution to resolve the inequality (in other words, a long
>> > double):
>>
>> > typedef long double LongDouble;
>> > ...
>> > assert( LongDouble(x) == LongDouble( Target(x)));
>>
>> The whole point of the verifications is to avoid doing
>> Target(x), which may have implementation defined behavior, and
>> in fact core dumps for some values and some Target types on may
>> systems.
>
> Then the concern is overblown. As long as Target(x) is not undefined,
> than the expression is perfectly safe and will have either an
> implementation-defined or a well-defined value - (in no event would it
> ever have implementation-defined "behavior").
The problem is the undefined cases.
> Furthermore, while a
> program could test numeric_limits<Target>::traps to determine whether
> the Target type traps at all, it is not even necessary in this case.
> There is no chance that initializing a Target type with a valid numeric
> value could ever trap - since only arithmetic operations can trap.
> Initialization is not an arithmetic operation.
Conversion, however, is. It's not storing the result of the
conversion that's the problem; it's doing the conversion in
the first place.
> After all, if 70 lines of highly specialized template code are needed
> just to determine whether converting a floating point to integer value
> wouldn't core dump in C++, who in their right mind would ever decide to
> write a numerical program in C++?
That's the kind of care that is needed to write completely
portable numeric code in C++ (or C), and the people who do
it well are those who understand this and take the care when
it's needed.
-- James
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Tue, 1 Aug 2006 11:36:21 CST Raw View
ThosRTanner wrote:
> James Kanze wrote:
> > ThosRTanner wrote:
> > > James Kanze wrote:
> > >> ThosRTanner wrote:
> > >> > Mind you C++ with an IDE is also a much better
> > >> > language than C++ with an editor.
> > >> And what is C++ with an IDE other than C++ with a
> > >> particular editor imposed on you? If that editor
> > >> happens to be better than the one you would otherwise
> > >> use, it's an improvement. If not, it's anything but an
> > >> improvement.
> > > My experience with IDEs is that they provide
> > > a) "Integrated" compilation which takes you to the point of an error on
> > > compilation
> > That's a feature of the editor. All of the editors I'm
> > aware of have it.
> I use nedit, and I haven't worked out how to make it do that
> yet. Therefore I don't think it's true to say that all
> editors have that feature.
I said all of the editors I'm aware of. And I should have said
all of the *modern* editors I'm aware of; ed didn't have it.
(But I haven't used ed, outside of scripts, for around 20
years.) It's a feature of the editor; if your editor doesn't
have it, and it is an important feature, change the editor.
> However, I know that all IDE's do.
All of the editors in IDE's do seem to have it. But I don't see
the advantage the IDE brings compared to the editor alone.
> PS I hate emacs and vim.
So find another one. I don't care for emacs that much myself;
I've got vi in my fingers. (Personally, I don't like the editor
in Visual Studios. But that could easily be because I don't
know it that well. To the point that I don't even know how to
do the most fundamental things with it: piping a block of
text/code through an external program, for example, or doing a
global search and replace.)
> > > b) Code completion so that
> > > i) when you are using an object of a particular class, you can select
> > > an available method or member of the class
> > That's also a feature of the editor.
> It's always a feature of (the editor in) an IDE. Not always of
> an editor.
Some editors have the feature, some don't. If a particular
feature is important to you, obviously, then that becomes part
of your criteria for choosing an editor.
A good IDE, of course, will let you choose your editor. A good
editor will have hooks so that it can be integrated into an IDE.
The choice of an editor should be independant of whether you are
using an IDE or not.
> > All of the editors I'm aware of have an automatic completion
> > feature. On the other hand, they generally don't understand
> > C++ grammar and scoping rules, so the completion set is all
> > visible symbols, and not just the symbols which would be
> > legal in a C++ program at this point.
> I don't think that's much help. Certainly in our ghastly
> software, where nearly every conceivable combination of
> characters is accessible from the global namespace...
It helps, but admittedly because of the heuristics used to
search for the completion, which favors 1) nearby symbols, 2)
symbols in the same file, and 3) symbols in recently visited
files. It's not perfect, and after std::vector<X>::i,
completion will probably give you if, and not iterator, which is
obviously a better choice. But I've not found the difference to
be significant.
> > I'm still up in the air with regards to the advantages of
> > this. It's certainly a plus that, having typed std::v,
> > completion finds vector, and nothing else. For user defined
> > symbols, on the other hand, it's less clear; it's certainly
> > not rare for me to conceptually add a member variable to a
> > class because I need it, and to start using it in the
> > functions, before I've actually edited the class definition
> > to include it.
> Umm. I'd edit the class first in that case - if only because I
> know I'll get compilation errors if I don't edit it because
> I'll forget otherwise. Anyway, in a decent editor, it'd just
> mean you had to type it out in full till you've provided a
> definition (again, in an IDE I'd expect something like 'create
> declaration for xxxx in class/on stack/' options to appear
> fairly quickly)
It's probably possible to add such functionality to vim; it's
certainly possible to add it to emacs. My point is that it is
functionality of the editor which is embedded in the IDE, not of
the fact you are using an IDE. Now, you may prefer the editors
present in your IDE. That's a different question---if I had to
choose between vim in an IDE and emacs outside, for example, I'd
use the IDE. But the difference isn't IDE vs. no IDE; the
difference is between two editors. The IDE as such brings me
nothing.
> > > ii) syntax validation (or syntax deduction) when typing
> > > the code.
> > Again, most editors have this to some degree, e.g. matching
> > braces, automatic indentation, etc.
> That's not so much help, except when typing in, and the
> automatic indentation works the way I like to indent code
> (almost invariably never). I sort of meant like some
> editors/IDEs do, like on typing if<space> they work out you
> are likely to then type (, ) ( and } in short order, so do it
> for you and let you fill the spaces in.
I'd have to see it to see whether I liked it. I did use a
package for emacs once which did something similar, for Java.
It wasn't that bad, but it didn't bring enough to make me prefer
emacs over vim.
> > > c) Easier source modification when debugging
> > I'll admit that I don't get this one. How does the editor play
> > a role here?
> As in when using the IDE to step through source code
> (debugging existing code, rather than debugging from core file
> - though really I'd hope an IDE /could/ debug from a core
> file). It's the debug, look at variables, find line in error,
> change line, rebuild code, substitute new code in executable
> and carry on debugging from where you were.
That's more complicated. I'll admit that I rarely if ever step
through code; I can't see the point of it. (But there are
exceptions, particularly when trying to debug someone else's
code.) That is the sort of thing I understand by an IDE: the
editor's involved, but so are the compiler, the linker, the
debugger, and perhaps other tools. All "integrated". I'm
sceptical of this sort of development, however.
> OK, that can be tricky, but I've seen it done from time to
> time with varying levels of success. But ONLY in IDEs - never
> in editors, or debuggers.
Because, of course, it does require recompiling the code (which
the editor can't do, at least not directly), relinking it, and
getting the debugger to use the new version when it continues.
The Sun IDE supports it, but I've never used it.
[...]
> > But that's what I said to begin with: the choice is the
> > editor. If the IDE provides a better editor, it is a win.
> > If it doesn't, it isn't (and I can't be bothered with the
> > Unix IDE's which use vim or emacs as their editor---I don't
> > see any advantage in them compared to using vim or emacs
> > directly).
> Well, I think the development environment isn't just the editor.
Certainly not. You need awk and sed:-). (Seriously, of course,
you need a compiler/linker. In addition, tools like Rational
Rose are invaluable, and definitly some sort of source code
control. But a good scripting language is essential as well.)
> Given a development environment with a reasonable
> editor/debugger with reasonable integration between editor and
> source code, or good editor/reasonable debugger/no
> integration, I'd probably go for the integrated environment.
> However if it had an editor I couldn't work with even if I was
> paid the same as a footballer, then I'd think differently. As
> I hate emacs / vim, I guess my perspective might be a little
> different to yours ;-)
I presume that emacs and vim are not the only powerful editors
around:-). Personally, you're the first person I've heard from
who hates both; the philosophies are so different that if you
hate one, you usually like the other. Emacs can be customized
to more or less resemble any other editor. (But it's not the
same thing.)
[...]
> > Unless you're such a good typist that you never make
> > mistakes. And I don't think that anyone is that good.
> When I worked in a printing firm, their compositors were
> required to achieve 99.9% accuracy. That works out at about 1
> typo per page of book I think. Secretarial courses only
> required 95%. I don't think I achieve even that at first hit.
At first hit:-). The difference is that we are required to
achieve 100% accuracy. Since even the best can't do it at first
hit, all of our tools allow for corrections. (There's also the
question of time. You probably could achieve close to 100%
accuracy... at a rate of one character every 5 seconds. There's
such a thing as typing too fast; if correcting the additional
errors takes more time than you gained by typing faster, it's a
net loss.)
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Mon, 24 Jul 2006 14:44:00 CST Raw View
"Krzysztof Zelechowski" wrote:
> Uzytkownik "kanze" <kanze@gabi-soft.fr> napisal w wiadomosci
> news:1153126683.242065.284470@35g2000cwc.googlegroups.com...
> > "Krzysztof Zelechowski" wrote:
> >> assert(Target(x) == x);
> >
> > You may get an implementation defined signal before the assert
> > trips (which probably doesn't matter). You may also fail to
> > trip even when you should, if the conversion is between signed
> > and unsigned types, e.g. Target is unsigned int, Source is int,
> > and the value of x is -3.
> >
>
> My code should be used when the compiler issues a warning. Should there be
> a warning about an implicit cast from int to unsigned int, my code would
> fail. But the OP wanted to handle a warning about truncation.
It is also possible when converting from one numeric type to another to
have an assertion detect either value truncation or a signed/unsigned
value mismatch between the original and converted value. The key is to
have the assertion perform the comparison with a numeric type of
sufficient range and resolution to resolve the inequality (in other
words, a long double):
typedef long double LongDouble;
...
assert( LongDouble(x) == LongDouble( Target(x)));
Greg
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kwikius" <andy@servocomm.freeserve.co.uk>
Date: Mon, 24 Jul 2006 23:21:16 CST Raw View
John Nagle wrote:
> It's a cute idea, but not too helpful, since it won't
> catch arithmetic overflow. Doing that efficiently requires
> compiler and language support, since you'll want to look
> at hardware overflow flags you can't see from C++.
I have exactly this problem at the monent as it happens.
The Quan library can be seen at one level as a wrapper class for
(usually) an inbuilt type.
It performs checks on calculations on physical quantities.
http://sourceforge.net/projects/quan.
Seeing as it performs these checks it would be useful for the library
also to perform checks for overflow too.
For the case of int Op int my current solution is to, by default, cast
the operands to a floating point type, do the calculation and then cast
the result back using boost::numeric::converter ( which throws
exceptions on overflow), but give the user the option to switch that
off and just do the raw int Op int calculation.
Even there there are problems. For example,the round trip from long to
float and back can, in a corner case, cause the return to be of a
different value to the original dependent on what long and float
actually consist of IIRC.
And floating point operations and what happens in case of overflow are
implementation dependent in C++ or whatever the phrase is. It would
sure be nice to have some types available which provide a precise
specification for what are acceptable values, independent of the
hardware and consistent behaviour too. It would also be nice to be able
to trap integer overflow without the need for these casts. The goal
being a library where I can make absolute guarantees regarding safe
values without specifying that the library does X on hardware Y and E
on hardware B. AFAIC Java has made good headway in that direction. I
know the results arent perfect, but I appreciate the intent.
The benefits for industry, safety critical applications and financial
calulations should be obvious.
regards
Andy Little
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <kanze.james@neuf.fr>
Date: Sat, 22 Jul 2006 18:19:06 CST Raw View
ThosRTanner wrote:
> Mind you C++ with an IDE is also a much better language than
> C++ with an editor.
And what is C++ with an IDE other than C++ with a particular
editor imposed on you? If that editor happens to be better than
the one you would otherwise use, it's an improvement. If not,
it's anything but an improvement.
--
James Kanze kanze.james@neuf.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kanze.james@neuf.fr (James Kanze)
Date: Sat, 22 Jul 2006 23:18:44 GMT Raw View
Seungbeom Kim wrote:
> kanze wrote:
>>> Seungbeom Kim posted:
>>>> template <class Target, class Source>
>>>> inline Target numeric_cast(Source x)
>>>> {
>>>> assert( x is in the range of Target );
>>>> return static_cast<Target>(x);
>>>> }
>>>> (I'm not sure how to express in C++ what I wrote inside assert( );
>>> assert( numeric_limits<Target>::max() >=3D x );
>> assert( std::numeric_limits< Target >::max() >=3D x
>> && (! std::numeric_limits< Target >::is_signed
>> || (std::numeric_limits< Target >::is_integer
>> ? std::numeric_limits< Target >::min() >=3D x
>> : -std::numeric_limits< Target >::max() >=3D x)=
) )
>> ;
> Thanks for your idea.
> But this causes numeric_cast<signed>(1) to fail the assertion,
> because 'std::numeric_limits< Target >::min() >=3D x' is false.
> You might have meant 'std::numeric_limits< Target >::min() <=3D x'
Obviously:-).
> but this causes numeric_cast<signed>(1000000000U) to fail the
> assertion (where int is 32 bits).
Or even numeric_cast< signed >( 1U ).
Yuck. You're right. Worse: I'm not sure right off of a good
solution. I suspect that you'd have to do something involving
the signedness of Source as well. (If the first test passes,
and !std::numeric_limits< Source >::is_signed, no further tests
are applicable.)
Note that my expression also fails in the reverse case:
numeric_limits< unsigned >( -1 )
Again, -1 gets converted to unsigned in some of the
comparisons.
The best I can come up with rapidly is:
template< bool condition >
class Discriminator
{
} ;
// Target is_signed, ! is_integer, Source is_signed
template< typename Target, typename Source >
inline bool
isValidLower( Source value, Discriminator< true >, Discriminator<=20
false > )
{
return -std::numeric_limits< Target >::max() <=3D value ;
}
// Target is_signed, is_integer, Source is_signed
template< typename Target, typename Source >
inline bool
isValidLower( Source value, Discriminator< true >, Discriminator<=20
true > )
{
return std::numeric_limits< Target >::min() <=3D value ;
}
// Target ! is_signed, is_integer, Source is_signed
template< typename Target, typename Source >
inline bool
isValidLower( Source value, Discriminator< false >, Discriminator<=20
true > )
{
return 0 <=3D value ;
}
// Source unsigned...
template< typename Target, typename Source >
inline bool
isValid( Source value, Discriminator< false >, Discriminator< false =
> )
{
return std::numeric_limits< Target >::max() <=3D value ;
}
// Source signed
template< typename Target, typename Source >
inline bool
isValid( Source value, Discriminator< true >, Discriminator< false >=
)
{
// Note: this may give a false negative if Target is
// unsigned and value is negative. But in this case,
// the second condition would be sure to fail anyway,
// so the results would still be false.
return std::numeric_limits< Target >::max() <=3D value
&& isValidLower(
value,
Discriminator< std::numeric_limits< Target >::is_signed=20
> >(),
Discriminator< std::numeric_limits< Target=20
>::is_integer> >() ) ;
}
template< typename Target, typename Source >
Target
numeric_cast( Source x )
{
assert(
isValid< Target >( x,
Discriminator< std::numeric_limits< Source=20
>::is_integer >(),
Discriminator< std::numeric_limits< Target=20
>::is_integer >() ) ) ;
return static_cast< Target >( x ) ;
}
Untested, but there's got to be a simpler solution.
--=20
James Kanze kanze.james@neuf.fr
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kwikius" <andy@servocomm.freeserve.co.uk>
Date: Sun, 23 Jul 2006 01:58:23 CST Raw View
James Kanze wrote:
> Untested, but there's got to be a simpler solution.
http://www.boost.org/libs/numeric/conversion/doc/index.html
#include <boost/numeric/conversion/converter.hpp>
#include <limits>
#include <iostream>
template <typename Target, typename Source>
bool in_range( Source const & s)
{
typedef boost::numeric::converter<
Target,Source
> converter;
return converter::out_of_range(s) == boost::numeric::cInRange;
}
int main()
{
bool result1 =
in_range<int>(static_cast<double>(std::numeric_limits<int>::max()));
std::cout << result1 <<'\n';
bool result2 =
in_range<int>(static_cast<double>(std::numeric_limits<int>::max())+1);
std::cout << result2 <<'\n';
}
regards
Andy Little
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kanze.james@neuf.fr (James Kanze)
Date: Sun, 23 Jul 2006 13:46:41 GMT Raw View
kwikius wrote:
> James Kanze wrote:
>> Untested, but there's got to be a simpler solution.
> http://www.boost.org/libs/numeric/conversion/doc/index.html
When I look at the paragraph "Range Checking Logic", in the
documentation, I'm not sure that they've found a simpler
solution.
--=20
James Kanze kanze.james@neuf.fr
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kwikius" <andy@servocomm.freeserve.co.uk>
Date: Sun, 23 Jul 2006 12:45:14 CST Raw View
James Kanze wrote:
> kwikius wrote:
> > James Kanze wrote:
>
> >> Untested, but there's got to be a simpler solution.
>
> > http://www.boost.org/libs/numeric/conversion/doc/index.html
>
> When I look at the paragraph "Range Checking Logic", in the
> documentation, I'm not sure that they've found a simpler
> solution.
Don't know quite how to put this, but their solution must be simpler,
since it actually works. Heres a quick test of your solution, tried in
VC7.1 and gcc4.0
int main()
{
int result1 =
numeric_cast<int>(static_cast<double>(std::numeric_limits<int>::max()));
std::cout << result1 <<'\n';
int result2 =
numeric_cast<int>(static_cast<double>(std::numeric_limits<int>::max())
+ 1);
std::cout << result2 <<'\n';
}
In my definition of simpler, the boost version is *considerably*
simpler ....... ;-)
regards
Andy Little
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: John Nagle <nagle@animats.com>
Date: Mon, 24 Jul 2006 08:59:47 CST Raw View
It's a cute idea, but not too helpful, since it won't
catch arithmetic overflow. Doing that efficiently requires
compiler and language support, since you'll want to look
at hardware overflow flags you can't see from C++.
John Nagle
kwikius wrote:
> James Kanze wrote:
>
>>kwikius wrote:
>> > James Kanze wrote:
>>
>> >> Untested, but there's got to be a simpler solution.
>>
>> > http://www.boost.org/libs/numeric/conversion/doc/index.html
>>
>>When I look at the paragraph "Range Checking Logic", in the
>>documentation, I'm not sure that they've found a simpler
>>solution.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Mon, 24 Jul 2006 09:01:18 CST Raw View
James Kanze wrote:
> Seungbeom Kim wrote:
> > kanze wrote:
> >>> Seungbeom Kim posted:
> >>>> template <class Target, class Source>
> >>>> inline Target numeric_cast(Source x)
> >>>> {
> >>>> assert( x is in the range of Target );
> >>>> return static_cast<Target>(x);
> >>>> }
> >>>> (I'm not sure how to express in C++ what I wrote inside assert( );
> >>> assert( numeric_limits<Target>::max() >= x );
> >> assert( std::numeric_limits< Target >::max() >= x
> >> && (! std::numeric_limits< Target >::is_signed
> >> || (std::numeric_limits< Target >::is_integer
> >> ? std::numeric_limits< Target >::min() >= x
> >> : -std::numeric_limits< Target >::max() >= x)) )
> >> ;
>
> > Thanks for your idea.
>
> > But this causes numeric_cast<signed>(1) to fail the assertion,
> > because 'std::numeric_limits< Target >::min() >= x' is false.
> > You might have meant 'std::numeric_limits< Target >::min() <= x'
>
> Obviously:-).
>
> > but this causes numeric_cast<signed>(1000000000U) to fail the
> > assertion (where int is 32 bits).
>
> Or even numeric_cast< signed >( 1U ).
>
> Yuck. You're right. Worse: I'm not sure right off of a good
> solution. I suspect that you'd have to do something involving
> the signedness of Source as well. (If the first test passes,
> and !std::numeric_limits< Source >::is_signed, no further tests
> are applicable.)
>
> Note that my expression also fails in the reverse case:
> numeric_limits< unsigned >( -1 )
> Again, -1 gets converted to unsigned in some of the
> comparisons.
>
> The best I can come up with rapidly is:
>
(long solution omitted)
>
> Untested, but there's got to be a simpler solution.
How about:
assert( static_cast<Source>( static_cast<Target>(x)) == x );
?
Greg
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Mon, 24 Jul 2006 09:00:06 CST Raw View
James Kanze wrote:
> ThosRTanner wrote:
>
> > Mind you C++ with an IDE is also a much better language than
> > C++ with an editor.
>
> And what is C++ with an IDE other than C++ with a particular
> editor imposed on you? If that editor happens to be better than
> the one you would otherwise use, it's an improvement. If not,
> it's anything but an improvement.
My experience with IDEs is that they provide
a) "Integrated" compilation which takes you to the point of an error on
compilation
b) Code completion so that
i) when you are using an object of a particular class, you can select
an available method or member of the class
ii) syntax validation (or syntax deduction) when typing the code.
c) Easier source modification when debugging
I realise that some editors and debuggers tend towards the
functionality of IDEs, but generally IDE's do it better. And most IDEs
can have their editing behaviour customised.
I am an incredibly bad typist, so anything that can reduce my level of
mistakes is all to the good
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kst-u@mib.org (Keith Thompson)
Date: Wed, 19 Jul 2006 06:03:45 GMT Raw View
fgothamNO@SPAM.com (Frederick Gotham) writes:
[...]
> I find it *extremely* easy to use casts properly.
>
> I never make an unnecessary or inappropriate cast.
You've done so in this very thread:
| unsigned long long const gdp = 12485725486486764U;
[...]
| unsigned long long const population = 297279178249U;
[...]
| unsigned gdp_per_capita = (unsigned)(gdp / population);
The cast is unnecessary. Without the cast, the expression is
implicitly converted to unsigned anyway. (Whether the cast is
inappropriate is another question; in my opinion it is.)
Be careful about the word "never".
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: krixel@qed.pl ("Krzysztof Zelechowski")
Date: Wed, 19 Jul 2006 14:56:29 GMT Raw View
Uzytkownik "kanze" <kanze@gabi-soft.fr> napisal w wiadomosci
news:1153229444.088021.309170@s13g2000cwa.googlegroups.com...
> Frederick Gotham wrote:
>> ThosRTanner posted:
>
>> >> And who's to say if a cast is "inappropriate"... ?
>
>> > Or indeed necessary
>
>> You either get a compile error or you don't.
>
> ??? If you use a cast, you'll almost never get a compiler
> error. Even when it's unnecessary. And a lot of use of casts
> won't give you a compiler error if you forget it; you'll just
> get wrong results.
>
Mr Gotham probably meant that a cast is necessary when you get a
compile-time error when you do not use it: no error = no cast. And, since
not getting compile-time errors seems to be his main objective, there is
nothing to ???? about. You just use the cast to compile and deliver your
product and afterwards, when it breaks at run time, you happily explain that
it was only a demo ;-)
Chris
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Wed, 19 Jul 2006 09:56:35 CST Raw View
Frederick Gotham wrote:
> ThosRTanner posted:
>
> >> Learning to walk is hard. Learning to talk is hard. Learning to throw a
> >> ball is hard. Learning to read is hard. Learning to write is hard.
> >> Learning to perform a heart transplant is hard.
> >
> > Walking, talking, throwing, reading, writing are tools. Peforming heart
> > transplants is not a tool.
> >
> > Tools are meant to make things easier. In the long run, what sort of
> > tool is going to be more succesful, more frequently used. A tool that
> > only experts can use without causing damage, or a tool that many people
> > can use to do what they need.
>
>
> Wordplay.
A point of view that is different to yours is not wordplay.
>
> >> No more dangerous than eating fish. Watch for bones and you'll have no
> >> problem.
> > Or buy filleted fish.
>
>
> Filleted fish is more expensive in terms of money.
Depends how much money choking to death on a bone involves really.
> Dumbed-down programming languages are more expensive in terms of
> efficiency.
Not if people can produce working code more easily and non-working
code less easily.
>
> >> There are people in my college who employ use of a calculator to add
> >> two single-digit numbers.
> > And?
>
>
> Context: An example of a insult to human intelligence.
In your view perhaps. It could also be laziness, or the mathematical
equivelent of dyslexia (which does exist). Neither of those are an
insult to human intelligence (though one is rather more forgivable than
the other!).
>
> > Any programmer who uses a cast without a large amount of documentation
> > surrounding it is more than poor.
> Depends if she intends her code to be read by poor programmers.
No, depends if he/she intends her code to be maintainable. We should
he/she assume he/she is going to be the only person maintaining the
program? I dare say you haven't done any maintenance programming. It
really opens your eyes.
>
>
> > Well, for a start, if p is a pointer to a T, why are you incrementing
> > by a number of bytes that is not a multiple of sizeof(T). In which
> > case, why not just use p += num_elems;
> >
> > So what have we got:
> > 1) Removing constness from a pointer is always dangerous. In this
> > situation it is safe, but only because you have a completely
> > unnecessary cast to a const pointer.
> > 2) If bytes is not a multiple of sizeof(T), you are liable to end up
> > pointing into the middle of some data structure in an embarassing
> > fashion
> > 3) If bytes is not a multiple of the alignment of T, you will turn p
> > into a non-aligned pointer, This will either crash or slow your system
> > down something chronic.
>
>
> The topic of this thread is not the objective of my function, but rather
> the successful use of casts.
I cannot see how your program snippet succesfully uses casts. It is an
accident waiting to happen.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: musiphil@bawi.org (Seungbeom Kim)
Date: Wed, 19 Jul 2006 15:07:36 GMT Raw View
kanze wrote:
>> Seungbeom Kim posted:
>>> template <class Target, class Source>
>>> inline Target numeric_cast(Source x)
>>> {
>>> assert( x is in the range of Target );
>>> return static_cast<Target>(x);
>>> }
>>> (I'm not sure how to express in C++ what I wrote inside assert( );
>
>> assert( numeric_limits<Target>::max() >= x );
>
> assert( std::numeric_limits< Target >::max() >= x
> && (! std::numeric_limits< Target >::is_signed
> || (std::numeric_limits< Target >::is_integer
> ? std::numeric_limits< Target >::min() >= x
> : -std::numeric_limits< Target >::max() >= x)) )
> ;
Thanks for your idea.
But this causes numeric_cast<signed>(1) to fail the assertion,
because 'std::numeric_limits< Target >::min() >= x' is false.
You might have meant 'std::numeric_limits< Target >::min() <= x'
but this causes numeric_cast<signed>(1000000000U) to fail the assertion
(where int is 32 bits).
--
Seungbeom Kim
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: krixel@qed.pl ("Krzysztof Zelechowski")
Date: Tue, 18 Jul 2006 13:18:37 GMT Raw View
Uzytkownik "kanze" <kanze@gabi-soft.fr> napisal w wiadomosci
news:1153126683.242065.284470@35g2000cwc.googlegroups.com...
> "Krzysztof Zelechowski" wrote:
>> assert(Target(x) == x);
>
> You may get an implementation defined signal before the assert
> trips (which probably doesn't matter). You may also fail to
> trip even when you should, if the conversion is between signed
> and unsigned types, e.g. Target is unsigned int, Source is int,
> and the value of x is -3.
>
My code should be used when the compiler issues a warning. Should there be
a warning about an implicit cast from int to unsigned int, my code would
fail. But the OP wanted to handle a warning about truncation.
Chris
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Tue, 18 Jul 2006 08:45:55 CST Raw View
"Krzysztof Zelechowski" wrote:
> Uzytkownik "kanze" <kanze@gabi-soft.fr> napisal w wiadomosci
> news:1153126683.242065.284470@35g2000cwc.googlegroups.com...
> > "Krzysztof Zelechowski" wrote:
> >> assert(Target(x) == x);
> > You may get an implementation defined signal before the
> > assert trips (which probably doesn't matter). You may also
> > fail to trip even when you should, if the conversion is
> > between signed and unsigned types, e.g. Target is unsigned
> > int, Source is int, and the value of x is -3.
> My code should be used when the compiler issues a warning.
> Should there be a warning about an implicit cast from int to
> unsigned int, my code would fail. But the OP wanted to handle
> a warning about truncation.
Actually, the original poster was complaining about C++ code
being too readable, but this sub-thread has drifted considerably
away from that topic. Seungbeom Kim asked for a range checked
conversion, with an assertion failure if the source value didn't
fit into the target type. I was just pointing out that in some
special cases, your assert would pass despite an error. And
that formally, at least, the expression Target(x), in itself,
may trigger an implementation defined signal (although in this
case, that probably doesn't matter).
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Tue, 18 Jul 2006 15:01:24 GMT Raw View
kanze posted:
> Actually, the original poster was complaining about C++ code
> being too readable
No, I was complaining about words taking too much horizontal screenspace.
Readability is great, but not at the expense of taking up half the screen.
--
Frederick Gotham
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Tue, 18 Jul 2006 10:12:33 CST Raw View
Frederick Gotham wrote:
> SuperKoko posted:
>
> > The const_cast is very inappropriate here.
>
>
> It's there for a reason.
>
> I don't use unnecessary casts.
>
> I don't use inappropriate casts.
>
>
For such very simple functions, usually, programmers write the function
twice:
template <class T>
inline void AdvPtr(T*& p, std::size_t const bytes) {
p = reinterpret_cast<T*>(
reinterpret_cast<const char *>(p) + bytes);
}
template <class T>
inline void AdvPtr(const T*& p, std::size_t const bytes) {
p = reinterpret_cast<const T*>(
reinterpret_cast<char *>(p) + bytes);
}
> > Worst, actually, reinterpret_casting from a misaligned char*
>
>
> No such thing as a misaligned char*.
>
>
No, but there exists something such as a char* which is not enough
aligned to be safely/portably converted to a T* where T is a type which
might require alignment.
I mean that on a 68000 CPU, doing
int x[2];
int* p=x;
AdvPtr(p,sizeof(int)-1); /* VERY BAD idea */
AdvPtr(p,1); /* Don't expect it to points to x[1] : The first
conversion might have "dropped" the lower bits of the pointer */
So, I can't see any *portable* usage of this function with values of
bytes not equal to a multiple of sizeof(T).
That's why, you don't need a cast at all:
template <class T>
inline void AdvPtr(T*& p, std::size_t const bytes) {
p = bytes/sizeof(T); /* portable, though probably not useful */
}
> unsigned char* would indeed be preferable if you actually access the data at
> the specified address.
>
> If you're just doing pointer arithmetic though, there's no need for the
> superfluous "unsigned".
>
I didn't said that your code needed an unsigned char... I said that,
when working on raw data, unsigned char* are good candidates for
generic pointers... (e.g. int* are very bad candidates).
>
> > T* p=static_cast<T*>(static_cast<void*>(my_char_pointer+offset));
>
>
> Ridiculous overkill. (Not to mention it doesn't take care of constness.)
>
It *takes care* of constness... This code is supposed to be put in a
particular context... Not as a generic dangerous, error prone function.
Back to your question:
> And again we have melodramatic use of "dangerous". There's nothing wrong
> with the way I use casts.
The mere interface of your function is *dangerous*!
If the caller pass a non-correctly aligned "bytes" argument, it will
have non-portable, implementation-specific results.
Again, where do you use this function?
Do you use it like that?
AdvPtr(p, sizeof(T)*index);
In that case, p+=index; is better...
I can't see any high-level useful application of your function.
Mhhh... If <cstdarg> didn't existed, I guess that your AdvPtr function
could be useful to implement this variable-argument mechanism, though
it would *not be portable*.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Tue, 18 Jul 2006 10:14:06 CST Raw View
Frederick Gotham wrote:
> ThosRTanner posted:
>
> > Is this a troll?
>
>
> Great way to start a conversation -- congratulations on the social skills.
Why, thank you. You are too kind.
>
> > Although I'd agree that there are a lot of cowboy programmers out there
> > who have apalling design and coding practices, in the same way that
> > there are cowboy builders, plumbers, ..., I think you will find that
> > expert C++ programmers get that way from learning the language, they
> > aren't born knowing the ins and outs of C++ programmers.
>
>
> The same can be said for any pursuit.
>
> A boxer shouldn't expect to win a title within his first month of training.
>
> A plumber shouldn't expect to be the best plumber in the city after his
> first month of training.
>
> A surgeon shouldn't expect to be top surgeon in his practice within his
> first month.
>
> A programmer shouldn't expect to be the best programmer in the world after
> his first month.
>
> Practise makes perfect -- programming is no exception.
>
Then why do you want a language that is only suitable for those who are
expert in that language? It is ultimately self defeating.
> > In general however, a language that is designed to make it difficult to
> > make mistakes and make it easy to spot where mistakes are likely is
> > infinitely preferable over the other. This is why high level languages
> > are preferable to assembly code - which in turn is prefereable to
> > programming the machine in hex codes.
>
>
> Yes, but how dumb do you want to go? C++ dumb, or Java dumb?
I don't know. I'd rather get the design right, and find it easy to
convert the design to the implementation. A language that doesn't have
so many pitfalls for the unwary is, in those terms, a better language.
A language where the compiler can't tell the difference between a
function call and a declaration has problems.
>
> > There are areas where C++ is NOT friendly to the novice, and causes
> > grief and pain - this is why coding standards evolve.
>
>
> Just because something is difficult at the start doesn't mean you should
> give up.
I wasn't suggesting people give up. I was merely pointing out that
there are places where C++ makes life un-necessarily difficult. Great
for book writers and pundits, but not so good for the rest of us.
> Learning to walk is hard. Learning to talk is hard. Learning to throw a
> ball is hard. Learning to read is hard. Learning to write is hard. Learning
> to perform a heart transplant is hard.
Walking, talking, throwing, reading, writing are tools. Peforming heart
transplants is not a tool.
Tools are meant to make things easier. In the long run, what sort of
tool is going to be more succesful, more frequently used. A tool that
only experts can use without causing damage, or a tool that many people
can use to do what they need.
>
>
> >> And who's to say if a cast is "inappropriate"... ?
> >
> > Or indeed necessary
>
>
> You either get a compile error or you don't.
>
>
> >> C was built on a foundation of programmers who are competent, not on
> >> holding the hands of beginners who aren't out of diapers yet. C++
> >> should build on this proud mentality.
> >
> > I have no doubt it is a proud mentality. Whether it is a mentality that
> > makes things better for others is rather open to question.
>
>
> I was able to learn C++. You were able to learn C++.
>
> I may have above average intelligence, but I'm no genius -- yet still I can
> program proficiently.
I realise the analogy can be carried to far, but do you just program
someone elses designs, or do you design and program? As far as I can
tell, getting the design right is the important bit. Coding to some
extent is like building from an architects plans. And I'd rather the
tools I used for coding my designs didn't involve me spending a lot of
time avoiding subtleties and vagaries.
>
> >> My efficient, fully-portable, Standard-compliant code contains many
> >> casts. Some are necessary to make the code compile. Some are necessary
> >> to suppress compiler warnings. But they're all there for a reason!
> > And all are somewhat dangerous.
>
>
> No more dangerous than eating fish. Watch for bones and you'll have no
> problem.
Or buy filleted fish.
> Of course, if you don't watch for bones, then it's your own problem.
>
>
> >> Why should expert programmers be burdened with unwieldy names? It
> >> insults human intelligence.
> > I'd find it pretty difficult to insult that level of intelligence.
>
>
> There are people in my college who employ use of a calculator to add two
> single-digit numbers.
And?
> >> Some may hold in derision my use of old-style casts, but I'll
> >> definitely prefer:
> >>
> >> int *pi = (int*)pc;
> >>
> >> over:
> >>
> >> int *pi = reinterpret_cast<int*>(const_cast<char*>(pc));
> >>
> > More fool you for using either of them. But at least the 2nd is
> > flagging to the tired eye that something pretty damn dangerous is going
> > on.
>
>
> Again the argument of "unnecessary" or "inappropriate" casts. This is
> ludicrous! Only very poor programmers mis-use casts. Since when do we
> accommodate the very poor programmers?
Any programmer who uses a cast without a large amount of documentation
surrounding it is more than poor.
> And again we have melodramatic use of "dangerous". There's nothing wrong
> with the way I use casts. Here's some code of mine which makes brilliant
> use of the feature known as casts. The code's objective is to increment a
> pointer by a specified number of bytes. Please let me know where you feel
> the danger lies:
>
> #include <cstddef>
>
> template<class T>
> inline void AdvPtr( T *&p, std::size_t const bytes )
> {
> p = reinterpret_cast<T*>(
> const_cast<char*>(
> reinterpret_cast<char const*>(p) + bytes
> )
> );
> }
Well, for a start, if p is a pointer to a T, why are you incrementing
by a number of bytes that is not a multiple of sizeof(T). In which
case, why not just use p += num_elems;
So what have we got:
1) Removing constness from a pointer is always dangerous. In this
situation it is safe, but only because you have a completely
unnecessary cast to a const pointer.
2) If bytes is not a multiple of sizeof(T), you are liable to end up
pointing into the middle of some data structure in an embarassing
fashion
3) If bytes is not a multiple of the alignment of T, you will turn p
into a non-aligned pointer, This will either crash or slow your system
down something chronic.
So basically, I'd be hard put to it to find what is right with this.
Cheers
Tom
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Richard Smith" <richard@ex-parrot.com>
Date: Tue, 18 Jul 2006 10:18:04 CST Raw View
Frederick Gotham wrote:
> Here's some code of mine which makes brilliant
> use of the feature known as casts. The code's objective is to increment a
> pointer by a specified number of bytes. Please let me know where you feel
> the danger lies:
>
> #include <cstddef>
>
> template<class T>
> inline void AdvPtr( T *&p, std::size_t const bytes )
> {
> p = reinterpret_cast<T*>(
> const_cast<char*>(
> reinterpret_cast<char const*>(p) + bytes
> )
> );
> }
Please, please, please tell me this is a wind up. Surely it's obvious
why this is dangerous? For a start, what if bytes is not a multiple of
the size (and/or alignment depending on the function's intended use) of
T? Either you started off with an inappropriately alligned pointer, or
you'll end up with one. An improvement would be to include an
assertion to that effect.
Second, the name itself it highly misleading. I'm sure most
programmers would infer from the function name that it simply did p +=
bytes -- i.e. that the second argument was a number of T objects to
iterate over. If you must have a function that does this, give it a
better name -- bytewise_advance perhaps? And giving a function as
dangerous as this a lengthy name is a positive thing -- I would hope
that any calls to such a function would be few and far between and
quickly abstracted in a safer interface.
Thirdly, what's with the const_cast? As far as I can see this is pure
obfuscation. If you don't add constness with the inner
reinterpret_cast, you don't need to remove it again. The presence of
this cast itself dangerous by virtue of misleading programmers into
thinking that this function somehow subverts the constness of the
object; it does not. And anything that unnecessarily misleads other
programmers is, to my mind, dangerous.
But I can't believe that this could possibly have been a serious
question: surely anyone who wrote code like that would find themselves
out of work faster than they could say "reinterpret_cast"?
--
Richard Smith
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Tue, 18 Jul 2006 15:20:05 GMT Raw View
Kuyper posted:
>> You either get a compile error or you don't.
>
> Yes, but that's hardly a useful criterion.
>
> In some cases, the reason why a cast is inappropriate only shows up at
> run time. In some cases, it only shows up when you port the code to a
> platform with unexpected (but legal) properties.
Again we're making allowances for stupid, non-portable code. It's the
programmer's responsibility to know how flexibly C++ can be implemented.
When reading posts on comp.lang.c++, etc., I stop reading as soon as I see
something like:
struct Arb {
int *p;
double i;
};
int main()
{
Arb obj;
memset(obj,0,sizeof obj);
}
This code is stupid and non-portable, plain and simple.
I'm against putting stabilisers on the wheels of C++ to accommodate brain-
amputee programmers.
> In some cases, the problem comes up only when someone who's not as
> familiar with the code as an idealist would like them to be makes a
> change to something.
I can't think of any such situation. (Unless you're talking about something
as dumb as:
int *p = reinterpret_cast<int*>(0,0);
>> I was able to learn C++. You were able to learn C++.
>
> From your comments, I suspect that you still have a lot to learn, of
> the kinds of things that aren't covered by ordinary textbooks.
Funny, I would consider my core knowledge of C++ to be quite extensive.
>> No more dangerous than eating fish. Watch for bones and you'll have no
>> problem.
>>
>> Of course, if you don't watch for bones, then it's your own problem.
>
> That analogy underestimates both the danger, and the difficulty of
> avoiding it.
I find it *extremely* easy to use casts properly.
I never make an unnecessary or inappropriate cast.
Although a code sample of mine may contain several instances of const_cast,
static_cast, reinterpret_cast, and even C-style casts, it's all fully-
portable and is absent of undefined behaviour.
Do they change the 100-metre sprint because babies fall over when they try
to stand up?
>> >> Some may hold in derision my use of old-style casts, but I'll
>> >> definitely prefer:
>> >>
>> >> int *pi = (int*)pc;
>> >>
>> >> over:
>> >>
>> >> int *pi = reinterpret_cast<int*>(const_cast<char*>(pc));
>> >>
>> > More fool you for using either of them. But at least the 2nd is
>> > flagging to the tired eye that something pretty damn dangerous is
>> > going on.
>>
>>
>> Again the argument of "unnecessary" or "inappropriate" casts. This is
>> ludicrous! Only very poor programmers mis-use casts. Since when do we
>> accommodate the very poor programmers?
>
> Well, if either version of the above is a true example of your code, I
> think it's quite likely that you're misusing casts.
Context is everything. Assertions made out of context are nothing.
> Not because such code is inherently wrong, but because the contexts in
> which such code would be correct are overwhelmingly less common than
> contexts where less-than-expert programmers mistakenly think that they
> are correct.
Indeed. But I'm not a less-than-expert programmer, and I'm not about to
dumb-down my own method of programming just so my code looks less
suspicious.
--
Frederick Gotham
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Tue, 18 Jul 2006 10:27:01 CST Raw View
Frederick Gotham wrote:
> I don't use unnecessary casts.
> I don't use inappropriate casts.
Then we should assume that message
<0iMsg.11333$j7.315456@news.indigo.ie> in
comp.lang.c++.moderated was a forgery. The message claims to be
from you, and contains the following code:
#define SomeKindOfCompileTimeAssert(expr) typedef char
Compass[(expr)?4:-4]
unsigned Amalg(unsigned char const * const p)
{
/* Firstly, ensure no padding: */
SomeKindOfCompileTimeAssert(
CHAR_BIT * sizeof(unsigned)
== std::numeric_limits<unsigned>::digits
);
return reinterpret_cast<unsigned const&>(*p);
}
It's hard to imagine a more inappropriate cast---as I pointed
out in my response there, it core dumps on my machine (and on
most non-Intel platforms), probably gives the wrong answer on an
Intel (and certainly gives the wrong answer on some other
machines) AND there is a very good perfectly portable perfectly
correct solution which doesn't use casts.
When you post code like this, or like your AdvPtr in the
previous posting, it makes it very hard to take any of your
claims seriously.
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Tue, 18 Jul 2006 10:23:52 CST Raw View
Frederick Gotham wrote:
> ThosRTanner posted:
> > Is this a troll?
> Great way to start a conversation -- congratulations on the
> social skills.
Aren't you the one who started it? With insinuations along the
lines of "not-so-apt" and "expert programmer" (with the
suggestion that people who need to write clear and readable code
aren't expert).
Whether you like it or not, you're arguing against proven
software engineering practice.
> > Although I'd agree that there are a lot of cowboy
> > programmers out there who have apalling design and coding
> > practices, in the same way that there are cowboy builders,
> > plumbers, ..., I think you will find that expert C++
> > programmers get that way from learning the language, they
> > aren't born knowing the ins and outs of C++ programmers.
> Practise makes perfect -- programming is no exception.
Actually, practice doesn't make perfect, at least where
programming (and most other human exploits) are concerned. No
matter how much you practice, you'll never be perfect.
> > In general however, a language that is designed to make it
> > difficult to make mistakes and make it easy to spot where
> > mistakes are likely is infinitely preferable over the other.
> > This is why high level languages are preferable to assembly
> > code - which in turn is prefereable to programming the
> > machine in hex codes.
> Yes, but how dumb do you want to go? C++ dumb, or Java dumb?
What's dumb about writing readable code? Java or C++?
(Actually, I don't quite get the comparison. It's a lot harder
to write robust, readable code in Java than in C++. Partially,
at least, because Java code is so full of casts, and they don't
stand out.)
> > There are areas where C++ is NOT friendly to the novice, and
> > causes grief and pain - this is why coding standards evolve.
> Just because something is difficult at the start doesn't mean
> you should give up.
Aren't there enough difficult things to learn without
artificially adding to the list? I'm paid to produce working
solutions, not to master all sorts of unnecessary trickery just
to prove that I can to something a lot of other people can't.
> >> And who's to say if a cast is "inappropriate"... ?
> > Or indeed necessary
> You either get a compile error or you don't.
??? If you use a cast, you'll almost never get a compiler
error. Even when it's unnecessary. And a lot of use of casts
won't give you a compiler error if you forget it; you'll just
get wrong results.
> >> C was built on a foundation of programmers who are
> >> competent, not on holding the hands of beginners who aren't
> >> out of diapers yet. C++ should build on this proud
> >> mentality.
> > I have no doubt it is a proud mentality. Whether it is a
> > mentality that makes things better for others is rather open
> > to question.
> I was able to learn C++. You were able to learn C++.
> I may have above average intelligence, but I'm no genius --
> yet still I can program proficiently.
For what definition of proficiently? In my mind, programming
proficiently means writing code which others can easily read and
maintain. Sometimes, a cast is necessary, but I've yet to see
any case where a type conversion (implicit or explicit) made
code more readable and easier to maintain.
> >> Some may hold in derision my use of old-style casts, but I'll
> >> definitely prefer:
> >> int *pi = (int*)pc;
> >> over:
> >> int *pi = reinterpret_cast<int*>(const_cast<char*>(pc));
> > More fool you for using either of them. But at least the 2nd
> > is flagging to the tired eye that something pretty damn
> > dangerous is going on.
> Again the argument of "unnecessary" or "inappropriate" casts.
> This is ludicrous! Only very poor programmers mis-use casts.
You posted an example of code in comp.lang.c++.moderated which
mis-used casts. Does this mean that you're a poor programmer?
Or only that there were contraints that, for one reason or
another, you hadn't taken into consideration?
In real life code, casts are rarely necessary, and usually only
at the lowest levels. Their presence is a sign that something
dangerous is going on. I want them visible.
> Since when do we accommodate the very poor programmers?
More insinuations. It would help if you'd present some facts.
I find code with the new style casts much easier to read and
maintain (and code without any casts even easier). Are you
saying that I'm a "very poor programmer"?
> And again we have melodramatic use of "dangerous".
Nothing melodramatic. Just a basic reality.
> There's nothing wrong with the way I use casts.
Except in your public postings in comp.lang.c++.moderated.
> Here's some code of mine which makes brilliant use of the
> feature known as casts. The code's objective is to increment
> a pointer by a specified number of bytes. Please let me know
> where you feel the danger lies:
> #include <cstddef>
> template<class T>
> inline void AdvPtr( T *&p, std::size_t const bytes )
> {
> p = reinterpret_cast<T*>(
> const_cast<char*>(
> reinterpret_cast<char const*>(p) + bytes
> )
> );
> }
Could you please tell me what the purpose of this function is?
About the only use I can find for it is to generate core dumps.
If you have code like this in anything other than the lowest
level of programming (say, in an operating system kernel, or a
garbage collector), then I think you have a problem. The first
thing I'd do about it is throw out all of the code which calls
this function, and then throw out the function.
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Tue, 18 Jul 2006 16:32:44 GMT Raw View
ThosRTanner posted:
>> Learning to walk is hard. Learning to talk is hard. Learning to throw a
>> ball is hard. Learning to read is hard. Learning to write is hard.
>> Learning to perform a heart transplant is hard.
>
> Walking, talking, throwing, reading, writing are tools. Peforming heart
> transplants is not a tool.
>
> Tools are meant to make things easier. In the long run, what sort of
> tool is going to be more succesful, more frequently used. A tool that
> only experts can use without causing damage, or a tool that many people
> can use to do what they need.
Wordplay.
>> No more dangerous than eating fish. Watch for bones and you'll have no
>> problem.
> Or buy filleted fish.
Filleted fish is more expensive in terms of money.
Dumbed-down programming languages are more expensive in terms of
efficiency.
>> There are people in my college who employ use of a calculator to add
>> two single-digit numbers.
> And?
Context: An example of a insult to human intelligence.
> Any programmer who uses a cast without a large amount of documentation
> surrounding it is more than poor.
Depends if she intends her code to be read by poor programmers.
> Well, for a start, if p is a pointer to a T, why are you incrementing
> by a number of bytes that is not a multiple of sizeof(T). In which
> case, why not just use p += num_elems;
>
> So what have we got:
> 1) Removing constness from a pointer is always dangerous. In this
> situation it is safe, but only because you have a completely
> unnecessary cast to a const pointer.
> 2) If bytes is not a multiple of sizeof(T), you are liable to end up
> pointing into the middle of some data structure in an embarassing
> fashion
> 3) If bytes is not a multiple of the alignment of T, you will turn p
> into a non-aligned pointer, This will either crash or slow your system
> down something chronic.
The topic of this thread is not the objective of my function, but rather
the successful use of casts.
--
Frederick Gotham
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: bop@gmb.dk ("Bo Persson")
Date: Tue, 18 Jul 2006 16:38:23 GMT Raw View
"Frederick Gotham" <fgothamNO@SPAM.com> skrev i meddelandet
news:iR5vg.11603$j7.319841@news.indigo.ie...
> kanze posted:
>
>
>> Actually, the original poster was complaining about C++ code
>> being too readable
>
>
> No, I was complaining about words taking too much horizontal
> screenspace.
The language design could make an attempt to choose short word, where
available. The original Ada designers did that, choosing task over
process, and limited over protected. But absolutely no proc, or prot,
or fmod.
In C++ we have an advantage over C that we overload functions, to
avoid things like fmod. That's good, and should be used.
Otherwise we could end up in the C marshes, and try to figure out why
one of fclose, fread, fmod, ftell, and fwrite doesn't take a FILE*
parameter. Not very obvious at all.
>
>
> Readability is great, but not at the expense of taking up half the
> screen.
Then you are lucky that this week there is a 20% discount on 24 inch
wide screen monitors.
http://accessories.us.dell.com/sna/productlisting.aspx?c=us&category_id=6198&cs=04&l=en&mnf=694
That's another option.
Bo Persson
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Tue, 18 Jul 2006 16:52:39 GMT Raw View
SuperKoko posted:
> For such very simple functions, usually, programmers write the function
> twice:
> template <class T>
> inline void AdvPtr(T*& p, std::size_t const bytes) {
> p = reinterpret_cast<T*>(
> reinterpret_cast<const char *>(p) + bytes);
> }
> template <class T>
> inline void AdvPtr(const T*& p, std::size_t const bytes) {
> p = reinterpret_cast<const T*>(
> reinterpret_cast<char *>(p) + bytes);
> }
I don't duplicate code.
I had actually started off with two functions, and strove to merge them --
and I was successful.
>> > Worst, actually, reinterpret_casting from a misaligned char*
>>
>>
>> No such thing as a misaligned char*.
>>
>>
> No, but there exists something such as a char* which is not enough
> aligned to be safely/portably converted to a T* where T is a type which
> might require alignment.
Correct.
The objective of the function is to increment a pointer by a specified
number of bytes -- it's the client's problem if they end up with a pointer
to a misaligned object.
One plausible use of it would be, (assuming we have an "alignof" operator):
AdvPtr(p, alignof(*p));
> So, I can't see any *portable* usage of this function with values of
> bytes not equal to a multiple of sizeof(T).
How about multiples of alignof(T)? It's common that an object's alignment
requirements are less than its size.
Anyway, the objective of my function isn't the topic here -- the topic is
the use of casts.
If you wish to discuss the function's objective, here's a relevant thread:
http://groups.google.ie/group/comp.lang.c++/browse_frm/thread/5ffe109aa07bf
d16/85e926012c055278?lnk=st&q=insubject%3Aalignof+author%
3AFrederick+author%3AGotham&rnum=1&hl=en#85e926012c055278
> Back to your question:
>> And again we have melodramatic use of "dangerous". There's nothing
>> wrong with the way I use casts.
>
> The mere interface of your function is *dangerous*!
> If the caller pass a non-correctly aligned "bytes" argument, it will
> have non-portable, implementation-specific results.
Which is why the caller shouldn't pass an incorrect value for "bytes".
Is array indexing dangerous? Nothing's to stop me writing:
int array[8];
array[242] = 4;
Quick! Let's ban array indexing!
It's *D* *A* *N* *G* *E* *R* *O* *U* *S*!
It's possible to decrement a pointer to before the first element of an
array.
Quick! Let's ban pointer decrementation!
It's *D* *A* *N* *G* *E* *R* *O* *U* *S*!
Signed integer arithmetic produces undefined behaviour upon overflow.
Quick! Let's ban signed integer arithmetic!
It's *D* *A* *N* *G* *E* *R* *O* *U* *S*!
Writing programs in C++ can result in undefined behaviour.
Quick! Let's move to Java!
C++ is *D* *A* *N* *G* *E* *R* *O* *U* *S*!
> Again, where do you use this function?
> Do you use it like that?
>
> AdvPtr(p, sizeof(T)*index);
>
> In that case, p+=index; is better...
> I can't see any high-level useful application of your function.
Again, that is not the topic here.
--
Frederick Gotham
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kuyper@wizard.net
Date: Tue, 18 Jul 2006 16:05:42 CST Raw View
Frederick Gotham wrote:
> Kuyper posted:
.
> I'm against putting stabilisers on the wheels of C++ to accommodate brain-
> amputee programmers.
I agree; but you're exaggerating the situation when you imply that the
feature we're talking about imposes costs as serious as putting
unnecessary stabilizers on wheels, and you're exaggerating grotesquely
when you imply that the only people who would benefit from this featue
are brain-amputees. The long names of the new conversion operators
impose a very minor cost. They help reduce (not elliminate) the making
of mistakes of a kind that, from my personal experience, are made by
programmers of all experience levels, though substantially less often
by experts than by novices.
> > In some cases, the problem comes up only when someone who's not as
> > familiar with the code as an idealist would like them to be makes a
> > change to something.
>
>
> I can't think of any such situation. (Unless you're talking about something
> as dumb as:
>
> int *p = reinterpret_cast<int*>(0,0);
The conditions determining whether a type conversion does what it's
intended to do safely and efficiently are often complex. Whether or not
those conditions are met can often depend at run time upon code that is
very distant from the site of the conversion. Ideally, a person can
verify that a given conversion is appropriate by looking either at
actual code that is near to the site of the conversion, or at
documention. In reality, programmers of only moderate levels of
competence don't always know what those requirements are. Real code is
often poorly documented. Even well-designed code may have been designed
around other constraints that force you to look far away from the site
of a conversion, to confirm the validity of that conversion, and in the
real world code design is often significantly less than perfect. In
reality, code changes must be made by the person who is available,
rather than the person that you would like to have available, and the
person who is available make not be sufficiently familiar with the
program to know how to find out everything he needs to know to confirm
the validity of a conversion.
For all of these reasos, any language feature that makes it easier to
notice and evaluate the validity of a conversion provides a distinct
advantage.
> >> I was able to learn C++. You were able to learn C++.
> >
> > From your comments, I suspect that you still have a lot to learn, of
> > the kinds of things that aren't covered by ordinary textbooks.
>
>
> Funny, I would consider my core knowledge of C++ to be quite extensive.
Core knowledge is something that's covered by ordinary textbooks.
Writing maintainable code is something that's often neglected in those
books. Most people either never learn to write maintainable code, or
start learning only after they've burned badly enough to appreciate how
important maintainability is. I think you haven't reached that point in
your career yet.
> I find it *extremely* easy to use casts properly.
>
> I never make an unnecessary or inappropriate cast.
The const_cast in your code sample served no useful purpose, and the
reinterpret_cast is needed only if your function takes arguments that
can cause undefined behavior either when the function is called, or
when it returns.
> Although a code sample of mine may contain several instances of const_cast,
> static_cast, reinterpret_cast, and even C-style casts, it's all fully-
> portable and is absent of undefined behaviour.
> Do they change the 100-metre sprint because babies fall over when they try
> to stand up?
The 100-meter sprint is designed to seperate the very best runners from
runners who are almost the very best. A programming language designed
only for the very best programmers is a programming language that will
die a quick and well-deserved death, because the very best of anything
is, by definition, rare. There aren't enough of the very best
programmers to fill all of the programming positions that need to be
filled.
.
> > Not because such code is inherently wrong, but because the contexts in
> > which such code would be correct are overwhelmingly less common than
> > contexts where less-than-expert programmers mistakenly think that they
> > are correct.
>
>
> Indeed. But I'm not a less-than-expert programmer, and I'm not about to
> dumb-down my own method of programming just so my code looks less
> suspicious.
In the unlikely event that you're as good as you say you are, you've
ensured that your code is unmaintainable by less competent programmers.
I wouldn't hire someone who wrote code like that (unless I absolutely
had to - which in itself is an example of the very same problem that
I'm describing).
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Frederick Gotham <fgothamNO@SPAM.com>
Date: Tue, 18 Jul 2006 16:57:59 CST Raw View
Kuyper posted:
> The const_cast in your code sample served no useful purpose, and the
> reinterpret_cast is needed only if your function takes arguments that
> can cause undefined behavior either when the function is called, or
> when it returns.
Did you analyse the code to see why the const_cast is indeed necessary? The
function should be able to work with:
(1) Pointer to non-const.
(2) Pointer to const.
As follows:
int *p1;
int const *p2;
AdvPtr(p1, sizeof *p1);
AdvPtr(p2, sizeof *p2);
If I were to remove the const_cast, then it would only work with "pointer
to const". Here's is the original code which works with both kinds of
pointer:
#include <cstddef>
template<class T>
inline void AdvPtr( T *&p, std::size_t const bytes )
{
p = reinterpret_cast<T*>(
const_cast<char*>(
reinterpret_cast<char const*>(p) + bytes
)
);
}
Here is the form with "const_cast" removed; it only works with "pointer to
const":
#include <cstddef>
template<class T>
inline void AdvPtr( T *&p, std::size_t const bytes )
{
p = reinterpret_cast<T*>(
reinterpret_cast<char const*>(p) + bytes
);
}
While we're playing the "Let's restrict perfectly-good-code game", here's
one that will only work for "pointer to non-const":
#include <cstddef>
template<class T>
inline void AdvPtr( T *&p, std::size_t const bytes )
{
p = reinterpret_cast<T*>(
reinterpret_cast<char*>(p) + bytes
);
}
--
Frederick Gotham
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Mon, 17 Jul 2006 09:00:27 CST Raw View
Frederick Gotham wrote:
> Seungbeom Kim posted:
> > template <class Target, class Source>
> > inline Target numeric_cast(Source x)
> > {
> > assert( x is in the range of Target );
> > return static_cast<Target>(x);
> > }
> > (I'm not sure how to express in C++ what I wrote inside assert( );
> assert( numeric_limits<Target>::max() >= x );
assert( std::numeric_limits< Target >::max() >= x
&& (! std::numeric_limits< Target >::is_signed
|| (std::numeric_limits< Target >::is_integer
? std::numeric_limits< Target >::min() >= x
: -std::numeric_limits< Target >::max() >= x)) )
;
If you want to be really general, you might want to throw in a
check for is_bounded (if is_bounded false, max() and min() are
not significant), and maybe is_specialized as well.
Since is_signed, is_integer, is_bounded and is_specialized are
all constant integral expressions (of type bool), you can
probably use some very simple template metaprogramming to make
the code more readable.
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Mon, 17 Jul 2006 09:01:50 CST Raw View
Frederick Gotham wrote:
> posted:
>
>
> > Therefore, the explicit cast operators were deliberately made long and
> > unwieldy, to discourage the unnecessary and inappropriate use of casts,
> > and to make it easier to locate them when they are used.
>
>
> I really don't understand this reasoning.
>
> A high-quality programming language like C++ should be designed for expert
> programmers, not for people learning to program. There's plenty of
> alternatives out there for the not-so-apt: Visual Basic, Java.
Is this a troll? Although I'd agree that there are a lot of cowboy
programmers out there who have apalling design and coding practices, in
the same way that there are cowboy builders, plumbers, ..., I think you
will find that expert C++ programmers get that way from learning the
language, they aren't born knowing the ins and outs of C++ programmers.
In general however, a language that is designed to make it difficult to
make mistakes and make it easy to spot where mistakes are likely is
infinitely preferable over the other. This is why high level languages
are preferable to assembly code - which in turn is prefereable to
programming the machine in hex codes.
There are areas where C++ is NOT friendly to the novice, and causes
grief and pain - this is why coding standards evolve.
> No expert programmer would use a cast unnecessarily, e.g.:
>
> int i;
>
> long j = (long)i; /* or static_cast if you prefer */
>
>
> And who's to say if a cast is "inappropriate"... ?
Or indeed necessary
> C was built on a foundation of programmers who are competent, not on
> holding the hands of beginners who aren't out of diapers yet. C++ should
> build on this proud mentality.
I have no doubt it is a proud mentality. Whether it is a mentality that
makes things better for others is rather open to question.
> My efficient, fully-portable, Standard-compliant code contains many casts.
> Some are necessary to make the code compile. Some are necessary to suppress
> compiler warnings. But they're all there for a reason!
And all are somewhat dangerous.
> Why should expert programmers be burdened with unwieldy names? It insults
> human intelligence.
I'd find it pretty difficult to insult that level of intelligence.
>
> Some may hold in derision my use of old-style casts, but I'll definitely
> prefer:
>
> int *pi = (int*)pc;
>
> over:
>
> int *pi = reinterpret_cast<int*>(const_cast<char*>(pc));
>
More fool you for using either of them. But at least the 2nd is
flagging to the tired eye that something pretty damn dangerous is going
on.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Mon, 17 Jul 2006 09:38:38 CST Raw View
Frederick Gotham wrote:
> James Kanze posted:
> > It's interesting to note that the author of those lines
> > actually posted such an error in comp.lang.c++.moderated a
> > day or two ago:-). A nice little pointer cast which will
> > provoke a core dump under certain conditions on my machine
> > (a Sun Sparc---hardly an exotic platform, unless you
> > consider anything but a PC exotic). As a solution to a
> > problem where I don't use a cast.
> Are you referring to the code in which I assume that the
> char[sizeof(int)] array is suitably aligned?
Yes.
> http://groups.google.ie/group/comp.lang.c++.moderated/browse_frm/thread/fe5cc
> 7fe957d113b/f744078a86d33fbc?lnk=st&q=alignment+group%3Acomp.lang.c%2B%
> 2B.moderated+author%3AFrederick+author%3AGotham&rnum=1&hl=en#f744078a86d33fbc
> Are you saying that, on your system, the code crashes if the
> char array isn't suitably aligned?
On my Sun Sparc, yes. On most non-Intel based systems, in fact.
On some word adressed machines, it will not crash, but will
simply access the wrong bytes. The bits which select the byte
in the word are simply ignored for word accesses.
The point, of course, is simply to point out that even the
experts DO make mistakes. Code should not be designed to be
read-only, since someone has to fix those mistakes (and even
without the mistakes, the code may have to evolve). There are
some exceptions, but generally, code will be read many more
times than it will be written. We, and the language, should
thus favor the reader. (If typing long names is a problem, my
editor supports abbreviations, so that each time you enter an
identifier rc, the editor will replace it on the fly with
reinterpret_cast. But IMHO, if you're using reinterpret_cast
often enough for typing time to be a problem, you're using it
far too often.
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: petebecker@acm.org (Pete Becker)
Date: Mon, 17 Jul 2006 16:25:23 GMT Raw View
ThosRTanner wrote:
>
> In general however, a language that is designed to make it difficult to
> make mistakes and make it easy to spot where mistakes are likely is
> infinitely preferable over the other.
Hence the stunning success of Pascal. <g>
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Frederick Gotham <fgothamNO@SPAM.com>
Date: Mon, 17 Jul 2006 12:16:45 CST Raw View
ThosRTanner posted:
> Is this a troll?
Great way to start a conversation -- congratulations on the social skills.
> Although I'd agree that there are a lot of cowboy programmers out there
> who have apalling design and coding practices, in the same way that
> there are cowboy builders, plumbers, ..., I think you will find that
> expert C++ programmers get that way from learning the language, they
> aren't born knowing the ins and outs of C++ programmers.
The same can be said for any pursuit.
A boxer shouldn't expect to win a title within his first month of training.
A plumber shouldn't expect to be the best plumber in the city after his
first month of training.
A surgeon shouldn't expect to be top surgeon in his practice within his
first month.
A programmer shouldn't expect to be the best programmer in the world after
his first month.
Practise makes perfect -- programming is no exception.
> In general however, a language that is designed to make it difficult to
> make mistakes and make it easy to spot where mistakes are likely is
> infinitely preferable over the other. This is why high level languages
> are preferable to assembly code - which in turn is prefereable to
> programming the machine in hex codes.
Yes, but how dumb do you want to go? C++ dumb, or Java dumb?
> There are areas where C++ is NOT friendly to the novice, and causes
> grief and pain - this is why coding standards evolve.
Just because something is difficult at the start doesn't mean you should
give up.
Learning to walk is hard. Learning to talk is hard. Learning to throw a
ball is hard. Learning to read is hard. Learning to write is hard. Learning
to perform a heart transplant is hard.
>> And who's to say if a cast is "inappropriate"... ?
>
> Or indeed necessary
You either get a compile error or you don't.
>> C was built on a foundation of programmers who are competent, not on
>> holding the hands of beginners who aren't out of diapers yet. C++
>> should build on this proud mentality.
>
> I have no doubt it is a proud mentality. Whether it is a mentality that
> makes things better for others is rather open to question.
I was able to learn C++. You were able to learn C++.
I may have above average intelligence, but I'm no genius -- yet still I can
program proficiently.
>> My efficient, fully-portable, Standard-compliant code contains many
>> casts. Some are necessary to make the code compile. Some are necessary
>> to suppress compiler warnings. But they're all there for a reason!
> And all are somewhat dangerous.
No more dangerous than eating fish. Watch for bones and you'll have no
problem.
Of course, if you don't watch for bones, then it's your own problem.
>> Why should expert programmers be burdened with unwieldy names? It
>> insults human intelligence.
> I'd find it pretty difficult to insult that level of intelligence.
There are people in my college who employ use of a calculator to add two
single-digit numbers.
>> Some may hold in derision my use of old-style casts, but I'll
>> definitely prefer:
>>
>> int *pi = (int*)pc;
>>
>> over:
>>
>> int *pi = reinterpret_cast<int*>(const_cast<char*>(pc));
>>
> More fool you for using either of them. But at least the 2nd is
> flagging to the tired eye that something pretty damn dangerous is going
> on.
Again the argument of "unnecessary" or "inappropriate" casts. This is
ludicrous! Only very poor programmers mis-use casts. Since when do we
accommodate the very poor programmers?
And again we have melodramatic use of "dangerous". There's nothing wrong
with the way I use casts. Here's some code of mine which makes brilliant
use of the feature known as casts. The code's objective is to increment a
pointer by a specified number of bytes. Please let me know where you feel
the danger lies:
#include <cstddef>
template<class T>
inline void AdvPtr( T *&p, std::size_t const bytes )
{
p = reinterpret_cast<T*>(
const_cast<char*>(
reinterpret_cast<char const*>(p) + bytes
)
);
}
--
Frederick Gotham
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: Mon, 17 Jul 2006 18:10:24 GMT Raw View
Pete Becker wrote:
> ThosRTanner wrote:
>
>>
>> In general however, a language that is designed to make it difficult to
>> make mistakes and make it easy to spot where mistakes are likely is
>> infinitely preferable over the other.
>
>
> Hence the stunning success of Pascal. <g>
I'm sure Pete would agree that the strong typeing of Pascal was not the
primary reason for Pascal failing to become a popular and successful
development language.
I think the primary reason was the lack of facilities for large- (or
even medium-) scale programming. (Brian Kernighan's views
notwithstanding:
http://www.cs.virginia.edu/~evans/cs655-S00/readings/bwk-on-pascal.html )
1. Standard Pascal did not allow separate compilation or user-defined
libraries. Each real-world Pascal implementation provided the facility
in some way, different for each compiler.
2. Standard Pascal forced a strict order on declarations, and had no
facility for including headers. (If header inclusion were allowed, you
would have had to split a header into pieces to keep the strict
declaration order.) Again, real-world compilers relaxed the strict
ordering rules and allowed header inclusion -- differently for each
compiler. BTW, the reason for the declaration order was to permit
creating a one-pass compiler -- the rules were not inspired by safer
progamming practice.
3. Standard Pascal did not allow ad-hoc creation of pointers. The only
use of a pointer was for heap data, and you could not do pointer
arithmetic. You could not take a pointer to a function, but you could
pass functions as strictly-typed function parameters. Again, real-world
compilers provided ad-hoc pointers and pointer arithmetic, but the
details varied.
The Pascal Committee could not agree on these facilities for real-world
programming, so Standard Pascal wound up with none. The resulting
language turned out to be what some of the Committee members thought all
programmers ought to want, but unfortunately was not what most
programmers actually wanted.
---
Steve Clamage, stephen.clamage@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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Mon, 17 Jul 2006 14:39:10 CST Raw View
Frederick Gotham wrote:
> And again we have melodramatic use of "dangerous". There's nothing wrong
> with the way I use casts. Here's some code of mine which makes brilliant
> use of the feature known as casts. The code's objective is to increment a
> pointer by a specified number of bytes. Please let me know where you feel
> the danger lies:
>
> #include <cstddef>
>
> template<class T>
> inline void AdvPtr( T *&p, std::size_t const bytes )
> {
> p = reinterpret_cast<T*>(
> const_cast<char*>(
> reinterpret_cast<char const*>(p) + bytes
> )
> );
> }
>
>
The const_cast is very inappropriate here.
It should be:
inline void AdvPtr( T *&p, std::size_t const bytes )
{
p = reinterpret_cast<T*>(
reinterpret_cast<char *>(p) + bytes
);
}
Now, I can't see any legitimate usage of this function!
bytes should always be a multiple of sizeof(T)... Otherwise, welcome
into the nigthmare of misalignment.
Worst, actually, reinterpret_casting from a misaligned char* to T* may
well produce a pointer that we don't expect, worst, it might even
produce an unspecified pointer (depends on the implementation-defined
reinterpret_cast to a type with a strictier type alignment).
And, if bytes is always a multiple of sizeof(T), this function can be
written easily as:
inline void AdvPtr(T*& p, std::size_t const bytes) {
p+= (bytes/sizeof(T));
}
But, normally, you should never have this "bytes" offset... It should
be:
inline void AdvPtr(T*& p, std::size_t const index) {
p+=index;
}
Well, it is simply +=
I know that, when programming low level things, it might be useful to
work on "raw" data, and, sometimes there is data mapped inside this raw
data.
In that case, there are only two good types of pointers for working on
this raw data:
character pointers (unsigned char* is prefered) or void*.
And, in that case, it might be legitimate to do things such as:
T* p=static_cast<T*>(my_void_pointer);
Or:
T* p=static_cast<T*>(static_cast<void*>(my_char_pointer+offset));
A reinterpret_cast might be used here, but personally, I prefer two
static_casts (or an implicit_cast followed by a static_cast).
But, such very low level things should be done seldomly... Almost
never.
A more legitimate, and common, reason of using casts is the connection
of a C++ program to a C library, containing callback functions with
void* context parameters.
In that case, static_cast can be used to downcast a void* pointer to a
MyContext*
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: petebecker@acm.org (Pete Becker)
Date: Mon, 17 Jul 2006 19:58:44 GMT Raw View
Steve Clamage wrote:
> Pete Becker wrote:
>
>> ThosRTanner wrote:
>>
>>>
>>> In general however, a language that is designed to make it difficult to
>>> make mistakes and make it easy to spot where mistakes are likely is
>>> infinitely preferable over the other.
>>
>>
>>
>> Hence the stunning success of Pascal. <g>
>
>
> I'm sure Pete would agree that the strong typeing of Pascal was not the
> primary reason for Pascal failing to become a popular and successful
> development language.
>
Nevertheless, it is a counterexample to the original assertion. Pascal
code is best written by a team of two programmers: one to write the code
and one to write the semicolons.
Seriously: Pascal is annoying in its attempts to enforce orthodoxy, and
that's separate from the specific problems that Steve mentions. I used
Turbo Pascal for several years. Moving from Pascal to C was a tremendous
relief.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Mon, 17 Jul 2006 20:44:12 GMT Raw View
SuperKoko posted:
> The const_cast is very inappropriate here.
It's there for a reason.
I don't use unnecessary casts.
I don't use inappropriate casts.
> It should be:
> inline void AdvPtr( T *&p, std::size_t const bytes )
> {
> p = reinterpret_cast<T*>(
> reinterpret_cast<char *>(p) + bytes
> );
> }
My original code works perfectly with:
(1) Pointer to non-const
(2) Pointer to const
Yours is restricted to:
(1) Pointer to non-const
> Worst, actually, reinterpret_casting from a misaligned char*
No such thing as a misaligned char*.
> I know that, when programming low level things, it might be useful to
> work on "raw" data, and, sometimes there is data mapped inside this raw
> data.
> In that case, there are only two good types of pointers for working on
> this raw data:
> character pointers (unsigned char* is prefered) or void*.
unsigned char* would indeed be preferable if you actually access the data at
the specified address.
If you're just doing pointer arithmetic though, there's no need for the
superfluous "unsigned".
> T* p=static_cast<T*>(static_cast<void*>(my_char_pointer+offset));
Ridiculous overkill. (Not to mention it doesn't take care of constness.)
--
Frederick Gotham
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kuyper@wizard.net
Date: Mon, 17 Jul 2006 19:25:21 CST Raw View
Frederick Gotham wrote:
> ThosRTanner posted:
.
> >> And who's to say if a cast is "inappropriate"... ?
> >
> > Or indeed necessary
>
> You either get a compile error or you don't.
Yes, but that's hardly a useful criterion.
In some cases, the reason why a cast is inappropriate only shows up at
run time. In some cases, it only shows up when you port the code to a
platform with unexpected (but legal) properties. In some cases, the
problem comes up only when someone who's not as familiar with the code
as an idealist would like them to be makes a change to something.
Any one of those characteristics would prevent a compiler error, though
a good compiler will at least issue warnings that help you avoid some
of the possible problems.
> >> C was built on a foundation of programmers who are competent, not on
> >> holding the hands of beginners who aren't out of diapers yet. C++
> >> should build on this proud mentality.
> >
> > I have no doubt it is a proud mentality. Whether it is a mentality that
> > makes things better for others is rather open to question.
>
> I was able to learn C++. You were able to learn C++.
>From your comments, I suspect that you still have a lot to learn, of
the kinds of things that aren't covered by ordinary textbooks.
> I may have above average intelligence, but I'm no genius -- yet still I can
> program proficiently.
The key point isn't whether it's possible to learn to program; the
question is whether it's unnecessarily diffiuclt to learn to program
well. Our economy needs a large number of competent C++ programmers,
far larger than the number of people who can actually learn to become
that competent; most C++ programming is done by people with far less
than perfect knowledge of the C++ language.
Designing the language around the attitude that it need only be
proficiently writeable, or easily readible, by the most competent
programmers, would be a serious mistake.
> >> My efficient, fully-portable, Standard-compliant code contains many
> >> casts. Some are necessary to make the code compile. Some are necessary
> >> to suppress compiler warnings. But they're all there for a reason!
> > And all are somewhat dangerous.
>
> No more dangerous than eating fish. Watch for bones and you'll have no
> problem.
>
> Of course, if you don't watch for bones, then it's your own problem.
That analogy underestimates both the danger, and the difficulty of
avoiding it.
> >> Some may hold in derision my use of old-style casts, but I'll
> >> definitely prefer:
> >>
> >> int *pi = (int*)pc;
> >>
> >> over:
> >>
> >> int *pi = reinterpret_cast<int*>(const_cast<char*>(pc));
> >>
> > More fool you for using either of them. But at least the 2nd is
> > flagging to the tired eye that something pretty damn dangerous is going
> > on.
>
>
> Again the argument of "unnecessary" or "inappropriate" casts. This is
> ludicrous! Only very poor programmers mis-use casts. Since when do we
> accommodate the very poor programmers?
Well, if either version of the above is a true example of your code, I
think it's quite likely that you're misusing casts. Not because such
code is inherently wrong, but because the contexts in which such code
would be correct are overwhelmingly less common than contexts where
less-than-expert programmers mistakenly think that they are correct.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Tue, 18 Jul 2006 06:55:54 CST Raw View
Pete Becker wrote:
> Steve Clamage wrote:
> > Pete Becker wrote:
> >
> >> ThosRTanner wrote:
> >>
> >>>
> >>> In general however, a language that is designed to make it difficult to
> >>> make mistakes and make it easy to spot where mistakes are likely is
> >>> infinitely preferable over the other.
> >>
> >>
> >>
> >> Hence the stunning success of Pascal. <g>
> >
> >
> > I'm sure Pete would agree that the strong typeing of Pascal was not the
> > primary reason for Pascal failing to become a popular and successful
> > development language.
> >
>
> Nevertheless, it is a counterexample to the original assertion. Pascal
> code is best written by a team of two programmers: one to write the code
> and one to write the semicolons.
I did say in general
> Seriously: Pascal is annoying in its attempts to enforce orthodoxy, and
> that's separate from the specific problems that Steve mentions. I used
> Turbo Pascal for several years. Moving from Pascal to C was a tremendous
> relief.
C++ with Gimpel lint (with strong type checking) is a much better
language to program in than C++ ...
Mind you C++ with an IDE is also a much better language than C++ with
an editor.
I wouldn't know about Pascal though. My path was Fortran -> Assembler
-> BCPL -> C -> C++ -> Java (OK, I'm learning Java, and some of the C++
I've learnt has helped, some has hindered).
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: musiphil@bawi.org (Seungbeom Kim)
Date: Thu, 13 Jul 2006 18:25:37 GMT Raw View
Steve Clamage wrote:
> Keith Thompson wrote:
>> fgothamNO@SPAM.com (Frederick Gotham) writes:
>>>
>>> unsigned long long const gdp =3D 12485725486486764U;
>>> ...
>>> unsigned long long const population =3D 297279178249U;
>>> ...
>>>
>>> unsigned gdp_per_capita =3D (unsigned)(gdp / population);
>=20
> But the cast, as many have noted, is generally not a good idea. In the
> original example, you might later decide that gdp_per_capita ought to b=
e
> a larger type. When (as in real code) the various declarations are
> spread far apart, you might not realize that the cast no longer matches
> the target type. You could wind up with an explicit narrowing conversio=
n
> that changes the value, but without the possibility of a compiler warni=
ng.
A safer option is to use boost::numeric_cast, which checks whether
the value can be preserved in the target type and throws an exception
otherwise.
In fact, I would also like a version in which a similar checking is done
only in debug builds, =E0 la boost::polymorphic_downcast: i.e.
template <class Target, class Source>
inline Target numeric_cast(Source x)
{
assert( x is in the range of Target );
return static_cast<Target>(x);
}
(I'm not sure how to express in C++ what I wrote inside assert( );
when I look into the implementation of boost::numeric::converter,
it seems too complicated for me to understand in a short time.)
--=20
Seungbeom Kim
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Frederick Gotham <fgothamNO@SPAM.com>
Date: Thu, 13 Jul 2006 16:21:05 CST Raw View
Seungbeom Kim posted:
> template <class Target, class Source>
> inline Target numeric_cast(Source x)
> {
> assert( x is in the range of Target );
> return static_cast<Target>(x);
> }
>
> (I'm not sure how to express in C++ what I wrote inside assert( );
assert( numeric_limits<Target>::max() >= x );
--
Frederick Gotham
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Fri, 14 Jul 2006 10:45:48 CST Raw View
Frederick Gotham wrote:
> Keith Thompson posted:
>
> > Most of the casts I've seen that are "necessary to suppress compiler
> > warnings" are actually unnecessary; rather than fixing errors, they
> > mask them. I'm not necessarily suggesting that that's the case with
> > *your* casts, but I'd be interested in seeing examples where such
> > casts are necessary and useful.
>
>
> Gladly.
>
> Let's say we have a 64-Bit unsigned integer to store the Gross Domestic
> Product of the USA for a given year. The units are US dollars:
>
> unsigned long long const gdp = 12485725486486764U;
>
> We also have a 64-Bit unsigned integer to store the population of the USA for
> a given year. The units are humans:
>
> unsigned long long const population = 297279178249U;
>
> Now let's say we have a 16-Bit unsigned integer to store the Gross Domestic
> Product per capita for a given year. The units are US dollars:
>
> unsigned gdp_per_capita = (unsigned)(gdp / population);
>
>
Using a C-style cast here is a bad idea, because C++ style cast are far
easier to search for (with grep or with any good text editor).
And, since a C++ program contains very few reinterpret_cast, it can be
very easy to port a C++ program, searching for all reinterpret_cast and
changing these non-portable constructs, or at least checking that they
work as expected on the new platform.
Here, even static_cast is not a very good idea.
You can use this template, though:
template <class TDestination, class TSource>
inline TDestination implicit_cast(const TSource& source) {
return source;
}
The name looks like an oxymoron... But I have not found any better
name.
Of course, if you like terseness, you can name it "icast" or "imcst" or
"icst"
James Dennett wrote:
> Frederick Gotham wrote:
> > A high-quality programming language like C++ should be designed for expert
> > programmers, not for people learning to program.
>
>
> I think that C++ should recognize that its user base includes
> people at various levels of expertise, from some of the experts
> who inhabit forums such as csc++ through good professional
> programmers, average professional programmers, weak professional
> programmers, hobbyists, and people who use C++ as a tool
> incidental to their primary line of work.
>
Yes, but only only advanced programmers who know what they are doing
and the rationale behind each cast actually use the C++-style casts :
Most beginners, students and occasionals C++ programmers use C-style
cast!
I think that C++-style casts have long names because:
1) It avoids potential name clashes with legacy code.
2) No abbreviation, means that it is easier for a beginner to spell it
right from the start.
Abbreviations are inconsistent and must be actively learnt.
Frederick Gotham wrote:
> static_cast
> dynamic_cast
> reinterpret_cast
>
>
> They take up a disproportionate amount of horizontal screen space, and are a
> lot less pleasant to have to type out (particularly "reinterpret_cast").
If you want to avoid typing in these "long" names you can use a
Good(TM) text editor such as Vim, add these lines
iabbrev scst static_cast
iabbrev dcst dynamic_cast
iabbrev rcst reinterpret_cast
In your .vimrc file or in an autocmd script loaded for C++ files.
1) You will not have to type the full names.
2) But your code will still be readable by any normal human being since
it will contain the expanded forms : static_cast & co.
For the horizontal screen space, you can put carriage returns after
each token, or use \<NEWLINE> inside any token.
kuyper@wizard.net wrote:
> Therefore, the explicit cast operators were deliberately made long and
> unwieldy, to discourage the unnecessary and inappropriate use of casts,
> and to make it easier to locate them when they are used.
I don't think so, even if it is in the FAQ of Bjarne Stroustrup's
homepage. I think it is more a joke on a side effect of this WG21's
choice.
IMHO, C++ mustn't (and actually *does not*, personally I type fast
enough on my keyboard to feel comfortable with reinterpret_cast) impose
a style, even if it allows bad programming styles. C++ gives to the
programmer the most freedom it can.
The C philosophy said: "Trust the programmer".
IMHO, the C++ philosophy is more like : "Trust the programmer when he
is explicit about his intents, and warn him when he does something that
he might not want to do". But C++ must not discourage the programmer
from doing what he wants.
In that sense, explicit casts are a C++ gift.
But a programmer is not more explicit when he writes reinterpret_cast
than reincast. In both cases, he knows what he does.
C-style casts are less "explicit", for two reasons:
1) Main reason : they have a large number of functions with only one
syntax while C++-style casts have more forms.
2) C-style casts are less easily visible for a code reader because they
are hidden behind a terse syntax, without any explicit keyword.
Don't forget that, a C programmer, even if he knows what he does when
he uses an explicit cast, might find uncomfortable point (2). Because
he will have to re-read his code, and maintain it.
So, being "explicit", is both a matter of "writing explicitly" and a
matter of "visibility when reading".
IMHO, C++ style casts have these 3 functions.
1) Accuracy of the cast (unlike C casts which are very large).
2) Being explicit when writing the code (arguably C-style casts share
that point too).
3) Being well-visible when reading the code.
I don't think that C++-style casts have any other function (such as
discouraging their usage).
Verbosity is not a problem for most people (Java is quite popular
though it is verbose).
Most people have no problem with that, and feel even more comfortable
with verbose identifiers than with terse UNIX/C/Perl-style
one-to-six-characters identifiers.
I admit that personally, I feel comfortable with short identifiers for
builtin language constructs (as in Perl), but I have no problem with
long identifiers.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kanze.james@neuf.fr (James Kanze)
Date: Fri, 14 Jul 2006 19:28:00 GMT Raw View
James Dennett wrote:
> Frederick Gotham wrote:
>> posted:
>>> Therefore, the explicit cast operators were deliberately
>>> made long and unwieldy, to discourage the unnecessary and
>>> inappropriate use of casts, and to make it easier to locate
>>> them when they are used.
>> I really don't understand this reasoning.
> It helps to reduce defect densities.
>> A high-quality programming language like C++ should be
>> designed for expert programmers, not for people learning to
>> program.
> I think that C++ should recognize that its user base includes
> people at various levels of expertise, from some of the experts
> who inhabit forums such as csc++ through good professional
> programmers, average professional programmers, weak professional
> programmers, hobbyists, and people who use C++ as a tool
> incidental to their primary line of work.
Realistically, if C++ can only be used by language experts, then
it won't be used at all. In most projects, most of the experts
are domain experts; it's not unusual for me to be the only
technical expert for several projects at a time.
One of the things I've see with real experts is that they
realize that not everyone can, or should be a language expert,
and they use the language accordingly. And while a non-expert
may not be able to come up with some of the things they do, a
non-expert will be able to understand them.
>> There's plenty of alternatives out there for the not-so-apt:
>> Visual Basic, Java.
>> No expert programmer would use a cast unnecessarily, e.g.:
>> int i;
>> long j =3D (long)i; /* or static_cast if you prefer */
> Innumerable bugs in code written by professionals have been
> caused by casts that should not have been present.
It's interesting to note that the author of those lines actually
posted such an error in comp.lang.c++.moderated a day or two
ago:-). A nice little pointer cast which will provoke a core
dump under certain conditions on my machine (a Sun
Sparc---hardly an exotic platform, unless you consider anything
but a PC exotic). As a solution to a problem where I don't use
a cast.
--=20
James Kanze kanze.james@neuf.fr
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Sat, 15 Jul 2006 04:28:33 GMT Raw View
James Kanze posted:
> It's interesting to note that the author of those lines actually
> posted such an error in comp.lang.c++.moderated a day or two
> ago:-). A nice little pointer cast which will provoke a core
> dump under certain conditions on my machine (a Sun
> Sparc---hardly an exotic platform, unless you consider anything
> but a PC exotic). As a solution to a problem where I don't use
> a cast.
Are you referring to the code in which I assume that the char[sizeof(int)]
array is suitably aligned?
http://groups.google.ie/group/comp.lang.c++.moderated/browse_frm/thread/fe5cc
7fe957d113b/f744078a86d33fbc?lnk=st&q=alignment+group%3Acomp.lang.c%2B%
2B.moderated+author%3AFrederick+author%3AGotham&rnum=1&hl=en#f744078a86d33fbc
Are you saying that, on your system, the code crashes if the char array isn't
suitably aligned?
--
Frederick Gotham
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "bjarne" <bjarne@gmail.com>
Date: Fri, 14 Jul 2006 23:52:36 CST Raw View
SuperKoko wrote:
>
> kuyper@wizard.net wrote:
> > Therefore, the explicit cast operators were deliberately made long and
> > unwieldy, to discourage the unnecessary and inappropriate use of casts,
> > and to make it easier to locate them when they are used.
>
> I don't think so, even if it is in the FAQ of Bjarne Stroustrup's
> homepage. I think it is more a joke on a side effect of this WG21's
> choice.
It is not a joke:
http://www.research.att.com/~bs/bs_faq2.html#static-cast
You can find equivalent comments in D&E.
That reason was mentioned in committee emails long before the design
was finalized.
-- Bjarne Stroustrup; http://www.research.att.com/~bs
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: krixel@qed.pl ("Krzysztof Zelechowski")
Date: Sat, 15 Jul 2006 12:41:50 GMT Raw View
assert(Target(x) =3D=3D x);
Uzytkownik "Seungbeom Kim" <musiphil@bawi.org> napisal w wiadomosci=20
news:e94rko$92e$1@news.Stanford.EDU...
In fact, I would also like a version in which a similar checking is done
only in debug builds, =E0 la boost::polymorphic_downcast: i.e.
template <class Target, class Source>
inline Target numeric_cast(Source x)
{
assert( x is in the range of Target );
return static_cast<Target>(x);
}
(I'm not sure how to express in C++ what I wrote inside assert( );
when I look into the implementation of boost::numeric::converter,
it seems too complicated for me to understand in a short time.)
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Mon, 17 Jul 2006 08:59:54 CST Raw View
"Krzysztof Zelechowski" wrote:
> assert(Target(x) == x);
You may get an implementation defined signal before the assert
trips (which probably doesn't matter). You may also fail to
trip even when you should, if the conversion is between signed
and unsigned types, e.g. Target is unsigned int, Source is int,
and the value of x is -3.
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Tue, 11 Jul 2006 18:10:01 GMT Raw View
posted:
> Therefore, the explicit cast operators were deliberately made long and
> unwieldy, to discourage the unnecessary and inappropriate use of casts,
> and to make it easier to locate them when they are used.
I really don't understand this reasoning.
A high-quality programming language like C++ should be designed for expert
programmers, not for people learning to program. There's plenty of
alternatives out there for the not-so-apt: Visual Basic, Java.
No expert programmer would use a cast unnecessarily, e.g.:
int i;
long j = (long)i; /* or static_cast if you prefer */
And who's to say if a cast is "inappropriate"... ?
C was built on a foundation of programmers who are competent, not on
holding the hands of beginners who aren't out of diapers yet. C++ should
build on this proud mentality.
My efficient, fully-portable, Standard-compliant code contains many casts.
Some are necessary to make the code compile. Some are necessary to suppress
compiler warnings. But they're all there for a reason!
Why should expert programmers be burdened with unwieldy names? It insults
human intelligence.
Some may hold in derision my use of old-style casts, but I'll definitely
prefer:
int *pi = (int*)pc;
over:
int *pi = reinterpret_cast<int*>(const_cast<char*>(pc));
--
Frederick Gotham
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Keith Thompson <kst-u@mib.org>
Date: Wed, 12 Jul 2006 10:15:16 CST Raw View
fgothamNO@SPAM.com (Frederick Gotham) writes:
[snip]
> And who's to say if a cast is "inappropriate"... ?
>
> C was built on a foundation of programmers who are competent, not on
> holding the hands of beginners who aren't out of diapers yet. C++ should
> build on this proud mentality.
>
> My efficient, fully-portable, Standard-compliant code contains many casts.
> Some are necessary to make the code compile. Some are necessary to suppress
> compiler warnings. But they're all there for a reason!
Most of the casts I've seen that are "necessary to suppress compiler
warnings" are actually unnecessary; rather than fixing errors, they
mask them. I'm not necessarily suggesting that that's the case with
*your* casts, but I'd be interested in seeing examples where such
casts are necessary and useful.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: jdennett@acm.org (James Dennett)
Date: Wed, 12 Jul 2006 15:16:04 GMT Raw View
Frederick Gotham wrote:
> posted:
>
>
>> Therefore, the explicit cast operators were deliberately made long and
>> unwieldy, to discourage the unnecessary and inappropriate use of casts,
>> and to make it easier to locate them when they are used.
>
>
> I really don't understand this reasoning.
It helps to reduce defect densities.
> A high-quality programming language like C++ should be designed for expert
> programmers, not for people learning to program.
I think that C++ should recognize that its user base includes
people at various levels of expertise, from some of the experts
who inhabit forums such as csc++ through good professional
programmers, average professional programmers, weak professional
programmers, hobbyists, and people who use C++ as a tool
incidental to their primary line of work.
> There's plenty of
> alternatives out there for the not-so-apt: Visual Basic, Java.
>
> No expert programmer would use a cast unnecessarily, e.g.:
>
> int i;
>
> long j = (long)i; /* or static_cast if you prefer */
Innumerable bugs in code written by professionals have been
caused by casts that should not have been present.
> And who's to say if a cast is "inappropriate"... ?
A specification, a test suite, a coding standard, or a language
rule, for example.
> C was built on a foundation of programmers who are competent, not on
> holding the hands of beginners who aren't out of diapers yet. C++ should
> build on this proud mentality.
Many features of C would also be unnecessary if programmers
made no mistakes. const-correctness, for example. Or
function prototypes. C++ could abandon type-safe linkage
if we never made mistakes. Most type checking could be
discarded.
> My efficient, fully-portable, Standard-compliant code contains many casts.
> Some are necessary to make the code compile. Some are necessary to suppress
> compiler warnings. But they're all there for a reason!
>
> Why should expert programmers be burdened with unwieldy names? It insults
> human intelligence.
Most good programmers accept that they make mistakes, and
embrace tools and techniques that help to reduce the
frequency of those mistakes.
> Some may hold in derision my use of old-style casts, but I'll definitely
> prefer:
>
> int *pi = (int*)pc;
>
> over:
>
> int *pi = reinterpret_cast<int*>(const_cast<char*>(pc));
I'd want to see a comment for why constness is discarded. It
usually (though not always) indicates a defect, or at least a
week design.
I'm happy for C++ to continue to try to develop in a manner that
helps professionals and hobbyists to write code that is more
correct. Reducing the need for C-style casts is one small way
of moving in that direction; using less cryptic names for new
facilities is another.
-- James
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kuyper@wizard.net
Date: Wed, 12 Jul 2006 10:17:41 CST Raw View
Frederick Gotham wrote:
> posted:
>
>
> > Therefore, the explicit cast operators were deliberately made long and
> > unwieldy, to discourage the unnecessary and inappropriate use of casts,
> > and to make it easier to locate them when they are used.
>
>
> I really don't understand this reasoning.
>
> A high-quality programming language like C++ should be designed for expert
> programmers, not for people learning to program. There's plenty of
> alternatives out there for the not-so-apt: Visual Basic, Java.
>
> No expert programmer would use a cast unnecessarily, e.g.:
Most of the people who program in C++ are not experts. Most of the code
I've had to deal with in my job that wasn't written by me contains many
poorly written spots, and inappropriate use of casts is one of the most
popular kinds of defects. Also, it's not as if this is a major
inconvenience; the longer names can be partially justified simply by
the fact they're easier to search for. If you've ever had the
misfortune of having to track down all the places where a variable with
a name like 'i' is used, you start to appreciate the advantages of
longer identifiers.
> int i;
Perhaps you haven't had that misfortune yet.
>
> long j = (long)i; /* or static_cast if you prefer */
>
>
> And who's to say if a cast is "inappropriate"... ?
An expert can give you an answer to that which is many pages long.
Here's a few general categories of problems: A cast is inappropriate if
it produces the wrong result under circumstances the programmer failed
to consider. A cast is inappropriate if it causes an unnecessarily
wasteful extra step. A cast is inappropriate if it masks a defect due
the fact that the object being converted to the correct type should
have been declared with that type in the first place.
> C was built on a foundation of programmers who are competent, not on
> holding the hands of beginners who aren't out of diapers yet. C++ should
> build on this proud mentality.
C++ was deliberately designed to make it easier to avoid many of those
errors that your hypothetical "expert" programmers would never make,
but which real world programmers make all the time. For example, the
concept of constructors and destructors, and the rules that call for
them to be automatically invoked, make it a lot easier to avoid
problems associated with bookend code such as malloc()/free() and
fopen()/fclose().
> Why should expert programmers be burdened with unwieldy names? It insults
> human intelligence.
I think you're overrating human intelligence, if you take this as an
insult. Human intelligence is messy, inaccurate, and unreliable. Good
engineering practice, including the design of programming languages,
takes that into consideration.
> Some may hold in derision my use of old-style casts, but I'll definitely
> prefer:
>
> int *pi = (int*)pc;
>
> over:
>
> int *pi = reinterpret_cast<int*>(const_cast<char*>(pc));
Let me join the people who deride you for that choice.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Wed, 12 Jul 2006 19:38:29 GMT Raw View
Keith Thompson posted:
> Most of the casts I've seen that are "necessary to suppress compiler
> warnings" are actually unnecessary; rather than fixing errors, they
> mask them. I'm not necessarily suggesting that that's the case with
> *your* casts, but I'd be interested in seeing examples where such
> casts are necessary and useful.
Gladly.
Let's say we have a 64-Bit unsigned integer to store the Gross Domestic
Product of the USA for a given year. The units are US dollars:
unsigned long long const gdp = 12485725486486764U;
We also have a 64-Bit unsigned integer to store the population of the USA for
a given year. The units are humans:
unsigned long long const population = 297279178249U;
Now let's say we have a 16-Bit unsigned integer to store the Gross Domestic
Product per capita for a given year. The units are US dollars:
unsigned gdp_per_capita = (unsigned)(gdp / population);
--
Frederick Gotham
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: petebecker@acm.org (Pete Becker)
Date: Wed, 12 Jul 2006 19:45:34 GMT Raw View
James Dennett wrote:
> Frederick Gotham wrote:
>
>> posted:
>>
>>
>>> Therefore, the explicit cast operators were deliberately made long and
>>> unwieldy, to discourage the unnecessary and inappropriate use of casts,
>>> and to make it easier to locate them when they are used.
>>
>>
>>
>> I really don't understand this reasoning.
>
>
> It helps to reduce defect densities.
>
Yup. If you rewrite a piece of code and replace all identifiers with
longer ones, you've got fewer defects per character. (Sorry, couldn't
resist.)
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: brok@rubikon.pl (Bronek Kozicki)
Date: Wed, 12 Jul 2006 21:18:46 GMT Raw View
Frederick Gotham wrote:
> A high-quality programming language like C++ should be designed for expert
> programmers, not for people learning to program.
mistake. Literally everyone programming in some language is, at some stage,
just a person "learning the language". Language that is too difficult to learn
will quickly become niche language, and (I guess) most people here do not want
that.
B.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: pavel_vozenilek@yahoo.co.uk ("Pavel Vozenilek")
Date: Wed, 12 Jul 2006 22:10:20 GMT Raw View
"Pete Becker" wrote:
>> [longer identifiers] helps to reduce defect densities.
>>
>
> Yup. If you rewrite a piece of code and replace all identifiers with
> longer ones, you've got fewer defects per character. (Sorry, couldn't
> resist.)
>
A very deep collection of scholar studies and recommendations about
identifiers can be found in book "The New C Standard" by Derek M. Jones
(online http://www.knosof.co.uk/cbook/cbook.html), chapter 6.4.2.1.
Influence of identifier length on error rates is covered here as well.
/Pavel
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kst-u@mib.org (Keith Thompson)
Date: Wed, 12 Jul 2006 23:53:30 GMT Raw View
fgothamNO@SPAM.com (Frederick Gotham) writes:
> Keith Thompson posted:
>> Most of the casts I've seen that are "necessary to suppress compiler
>> warnings" are actually unnecessary; rather than fixing errors, they
>> mask them. I'm not necessarily suggesting that that's the case with
>> *your* casts, but I'd be interested in seeing examples where such
>> casts are necessary and useful.
>
> Gladly.
>
> Let's say we have a 64-Bit unsigned integer to store the Gross Domestic
> Product of the USA for a given year. The units are US dollars:
>
> unsigned long long const gdp = 12485725486486764U;
>
> We also have a 64-Bit unsigned integer to store the population of
> the USA for a given year. The units are humans:
>
> unsigned long long const population = 297279178249U;
Last I heard, the C++ standard doesn't support long long or unsigned
long long (though I understand that's likely to change).
> Now let's say we have a 16-Bit unsigned integer to store the Gross Domestic
> Product per capita for a given year. The units are US dollars:
>
> unsigned gdp_per_capita = (unsigned)(gdp / population);
(unsigned int is *at least* 16 bits, of course, but it happens that
the result, 42000, is guaranteed to fit in an unsigned int.)
What warning does the cast inhibit? I don't get a warning with or
without the cast. (I do get warnings on the literals, depending on
command-line options.) The cast specifies an explicit conversion;
without it, there's still an implicit conversion. There's no obvious
reason why adding or removing the cast should affect whether there's a
warning.
There are a few cases where casts are appropriate. Certain mixed
arithmetic expressions, where you need to override the default
conversions, are one example. Your code above, where you use a cast
to specify a conversion that would have happened implicitly anyway, is
not, IMHO, a good example.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: Thu, 13 Jul 2006 04:23:09 GMT Raw View
Keith Thompson wrote:
> fgothamNO@SPAM.com (Frederick Gotham) writes:
>
>>
>> unsigned long long const gdp = 12485725486486764U;
>> ...
>> unsigned long long const population = 297279178249U;
>> ...
>>
>> unsigned gdp_per_capita = (unsigned)(gdp / population);
>
> What warning does the cast inhibit?
Some compilers warn about implicit "narrowing" conversions, sometimes by
default, sometimes as an option. Such warnings are reasonable, because
narrowing conversions can turn data into trash. Explicit conversions
(using a cast) get no warning.
A major problem with such warnings is that many of the <stdio.h>
functions (for example) return char values in an int, so as to be able
to return EOF to indicate error. Perfectly safe code like this
char ch;
while( (int c=getc()) != EOF ) {
ch = c; // implicit narrowing conversion
...
}
is subject to a warning. Programmers don't want warnings about safe
code, and insert casts to eliminate the warnings.
But the cast, as many have noted, is generally not a good idea. In the
original example, you might later decide that gdp_per_capita ought to be
a larger type. When (as in real code) the various declarations are
spread far apart, you might not realize that the cast no longer matches
the target type. You could wind up with an explicit narrowing conversion
that changes the value, but without the possibility of a compiler warning.
In my example, you might change from using char to using wchar_t or
char16_t, and forget to change the cast in
ch = (char)c; // oops!
If you used new-style casts (e.g. static_cast) instead of a C-style
cast, you could at least grep for casts in your code from time to time
to evaluate whether they are still correct.
In general, I tend toward the view that casts are the wrong answer. The
new-style casts were deliberately given long and distinctive names so
that they stand out -- any cast is potentially dangerous. In the
original example, I would look more closely at whether I need to use
different types, and whether I can isolate casts to one module that
addresses portability issues.
---
Steve Clamage, stephen.clamage@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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]