Monday, June 8, 2015

Digest for comp.lang.c++@googlegroups.com - 25 updates in 5 topics

ram@zedat.fu-berlin.de (Stefan Ram): Jun 08 03:58AM

>function that takes an argument of const vector<int>&.
>Is there a way to somehow directly supply the variable to the
>function without using a copy?
 
You can cast the object, but this might mean that the cast
or call will have undefined behaviour or in the best case
will behave as if each unsigned was reinterpret as an int.
 
Under some implementations this might be acceptable when all
the unsigned objects have values that can be represented as
an int.
 
For example, one implementation gave:
 
#include <iostream>
#include <ostream>
#include <vector>
#include <climits>
 
int main()
{ ::std::vector< unsigned >v{ 0, 1, INT_MAX,( unsigned )INT_MAX +( unsigned )1 };
for( unsigned u : v )::std::cout << u << '\n';
auto const &w( *reinterpret_cast< ::std::vector< int >* >( &v ) );
for( int i : w )::std::cout << i << '\n'; }
 
0
1
2147483647
2147483648
0
1
2147483647
-2147483648
ram@zedat.fu-berlin.de (Stefan Ram): Jun 08 03:21PM

>Ugh. Even:
>for (size_t i = str.size(); i+1 > 0; --i)}
 
#include <climits>
 
And what is the value of i+1,
when str.size() == SIZE_MAX?
ram@zedat.fu-berlin.de (Stefan Ram): Jun 08 04:10PM

Newsgroups: comp.lang.c++,comp.lang.c
 
>#include <climits>
>And what is the value of i+1,
>when str.size() == SIZE_MAX?
 
. Maybe we can get rid of the addition by:
 
for( size_t i = str.size() - 1; i !=( size_t )-1; --i )
 
?
 
Newsgroups: comp.lang.c++,comp.lang.c
ram@zedat.fu-berlin.de (Stefan Ram): Jun 08 05:49PM

> Never compare doubles for
>equality unless they are both assigned from the same object originally.
 
What about the following example?
 
void print_reciprocal( double const x )
{ if( x )::std::cout << 1/x;
else ::std::cout << "undefined";
::std::cout << '\n'; }
 
>Of course. Integer, long, bool, char. There is rational, too. Oh, did
>you mean 'float' or 'double' or 'long double'? Then, no.
 
Or possible he wants to download
a decimal floating point library.
ram@zedat.fu-berlin.de (Stefan Ram): Jun 08 06:05PM

>come with Vec constructors inherited from vector when Vec and
>vector have entirely different names? Perhaps I should ask,
>what exactly the line means?
 
12.9 Inheriting constructors [class.inhctor]
 
...
 
1 A using-declaration (7.3.3) that names a constructor
implicitly declares a set of inheriting constructors.
 
....
 
7.3.3 The using declaration [namespace.udecl]
 
If a using-declaration names a constructor (3.4.3.1), it
implicitly declares a set of constructors in the class
in which the using-declaration appears
 
...
ram@zedat.fu-berlin.de (Stefan Ram): Jun 08 06:22PM

>I am not sure I understand that statement. Downloading "a decimal
>floating point library" is well-defined, but what's it got to do with
>the problem of imprecision of doubles?
 
The imprecision is often visible for the layman or in
financial application only when it differs from everyday
imprecision.
 
That is, with fractions numerals with only a few digits
after the dot. A most famous example being
 
#include <iostream>
#include <ostream>
 
int main(){ ::std::cout << 0.1 + 0.2 - 0.3 << '\n'; }
 
5.55112e-017
 
This kind of imprecision can be defeated with /decimal/
floating point arithmetics.
 
mysql> SELECT 0.1 + 0.2 - 0.3;
+-----------------+
| 0.1 + 0.2 - 0.3 |
+-----------------+
| 0.0 |
+-----------------+
1 row in set (0.00 sec)
Doug Mika <dougmmika@gmail.com>: Jun 08 10:49AM -0700

I found the following improvement of our vector class in my book. It performs range checking when accessing vector. The thing that confuses me about this short little improvement is the line:
using vector<T>::vector;
 
How is it that this line lets our Vec class all of the sudden come with Vec constructors inherited from vector when Vec and vector have entirely different names? Perhaps I should ask, what exactly the line means?
 
Here's the short program:
 
template<typename T> class Vec : public std::vector<T> {
public:
using vector<T>::vector;
 
T& operator[](int i) //range check
{ return vector<T>::at(i); }
const T& operator[](int i) const
{ return vector<T>::at(i); }
};
legalize+jeeves@mail.xmission.com (Richard): Jun 08 06:10PM

[Please do not mail me a copy of your followup]
 
Doug Mika <dougmmika@gmail.com> spake the secret code
 
>I found the following improvement of our vector class in my book.
 
It's not an improvement. std::vector<> already has range-checked
access through the use of the at() member function.
 
All this is doing is making operator[] a synonym for at(), forcing all
accesses to be range-checked.
 
This is actually a step backwards.
 
C++'s std::vector<> has a non-range checked accessor and a
range-checked accessor because C++ follows the philosophy of "don't pay
for what you don't use". If you don't need range-checked accessing,
then you shouldn't have to pay the cost of range checking every access
and you use operator[]. If you want range-checked accessing, then you
can decide to pay the cost and use at().
 
Making operator[] do range-checking is simply going to confuse *any*
reader of your code because they are culturally trained that
at is for range checking and operator[] is for unchecked access.
 
>template<typename T> class Vec : public std::vector<T> {
>public:
> using vector<T>::vector;
 
This is a "using declaration"
<http://en.cppreference.com/w/cpp/language/using_declaration>
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 08 02:15PM -0400

On 6/8/2015 1:49 PM, Doug Mika wrote:
> I found the following improvement of our vector class in my book. It
performs range checking when accessing vector. The thing that confuses
me about this short little improvement is the line:
> using vector<T>::vector;
 
> How is it that this line lets our Vec class all of the sudden come
with Vec constructors inherited from vector when Vec and vector have
entirely different names? Perhaps I should ask, what exactly the line means?
> const T& operator[](int i) const
> { return vector<T>::at(i); }
> };
 
A constructor is a function whose name [for the purposes of syntax]
coincides with the name of the class. In a class template, the name of
a c-tor coincides with the name of the template (IOW, you don't need the
template args for the syntax). So, "vector<T>::vector" is the name of
all constructors of the class vector<T>. Declaring c-tors in the
'using' declaration like you did *inherits* the constructors in C++11
(see [class.inhctor] section).
 
Now you know.
 
V
--
I do not respond to top-posted replies, please don't ask
Peng Yu <pengyu.ut@gmail.com>: Jun 07 08:39PM -0700

Suppose that I have a variable of vector<unsigned>, and a function that takes an argument of const vector<int>&.
 
One thing to pass this variable to this function is to create a copy (with type vector<int>) of the variable, but this involes the extra copying.
 
Is there a way to somehow directly supply the variable to the function without using a copy?
 
Regards,
Peng
legalize+jeeves@mail.xmission.com (Richard): Jun 08 06:05PM

[Please do not mail me a copy of your followup]
 
Peng Yu <pengyu.ut@gmail.com> spake the secret code
 
>Is there a way to somehow directly supply the variable to the function
>without using a copy?
 
No. An unsigned can hold positive integer values that don't fit into
an int.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 08 07:12PM +0100

On 08/06/2015 04:58, Stefan Ram wrote:
> 1
> 2147483647
> -2147483648
 
You know it is UB yet you still suggest it? It is never acceptable to
deliberately invoke UB. Mate, I am sorry but if you wrote such code for
me you would be fired.
 
/Flibble
Christopher Pisz <nospam@notanaddress.com>: Jun 08 11:49AM -0500

I've run into the problem where I compare two different values of type
double and they are different by a tiny bit because of the way floating
point numbers are represented.
 
With all the new standard stuff, is there any representation that
guarantees to be exact to a certain precision?
 
I could write my own code and call it for comparisons with some
precision argument, that's what I did in 2008...
 
 
--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 08 01:31PM -0400

On 6/8/2015 12:49 PM, Christopher Pisz wrote:
> I've run into the problem where I compare two different values of type
> double and they are different by a tiny bit because of the way floating
> point numbers are represented.
 
Are you stepping again on the same rake? Never compare doubles for
equality unless they are both assigned from the same object originally.
 
> With all the new standard stuff, is there any representation that
> guarantees to be exact to a certain precision?
 
Of course. Integer, long, bool, char. There is rational, too. Oh, did
you mean 'float' or 'double' or 'long double'? Then, no.
 
> I could write my own code and call it for comparisons with some
> precision argument, that's what I did in 2008...
 
It's time for you to re-read the well-known article:
http://www.google.com/search?q=%22What+Every+Computer+Scientist+Should+Know+About+Floating-Point+Arithmetic%22
 
V
--
I do not respond to top-posted replies, please don't ask
Marcel Mueller <news.5.maazl@spamgourmet.org>: Jun 08 07:44PM +0200

On 08.06.15 18.49, Christopher Pisz wrote:
> point numbers are represented.
 
> With all the new standard stuff, is there any representation that
> guarantees to be exact to a certain precision?
 
Any floating point representation is exact as long as the mantissa is
long enough. double as well as float as well as a decimal float class.
But rational numbers must not be periodic in the specific number system.
I.e. nothing but the prime factor 2 and 5 (decimal float only) in the
denominator.
 
And most algorithms that compare floating point numbers to anything else
but singular values are broken by design.
 
> I could write my own code and call it for comparisons with some
> precision argument, that's what I did in 2008...
 
There are many big decimal or big float implementations around. Some of
them keep track of the accuracy. But they are not part of the standard
library.
And none of them replaces the know how about numeric. Many algorithms
can be tweaked for one or more orders of magnitude more accuracy simply
by carefully dealing with the residuals.
 
 
Marcel
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 08 06:49PM +0100

On 08/06/2015 18:31, Victor Bazarov wrote:
>> guarantees to be exact to a certain precision?
 
> Of course. Integer, long, bool, char. There is rational, too. Oh, did
> you mean 'float' or 'double' or 'long double'? Then, no.
 
In modern C++ we should avoid using 'int', 'short' and 'long' as they
are not portable or safe. Instead use the typedefs from <cstdint>.
 
/Flibble
legalize+jeeves@mail.xmission.com (Richard): Jun 08 06:04PM

[Please do not mail me a copy of your followup]
 
Victor Bazarov <v.bazarov@comcast.invalid> spake the secret code
 
>It's time for you to re-read the well-known article:
>http://www.google.com/search?q=%22What+Every+Computer+Scientist+Should+Know+About+Floating-Point+Arithmetic%22
 
Beat me to it :)
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 08 02:09PM -0400

On 6/8/2015 1:49 PM, Stefan Ram wrote:
> { if( x )::std::cout << 1/x;
> else ::std::cout << "undefined";
> ::std::cout << '\n'; }
 
What about that example? Do you know that NaN can cause a problem when
used in an expression? And it compares unequal to itself, even. The
behaviour of that code is only defined for a subset of 'double' values,
IOW, in general it's undefined.
 
>> you mean 'float' or 'double' or 'long double'? Then, no.
 
> Or possible he wants to download
> a decimal floating point library.
 
I am not sure I understand that statement. Downloading "a decimal
floating point library" is well-defined, but what's it got to do with
the problem of imprecision of doubles?
 
V
--
I do not respond to top-posted replies, please don't ask
gwowen <gwowen@gmail.com>: Jun 08 05:52AM -0700

On Friday, June 5, 2015 at 9:41:32 PM UTC+1, Mr Flibble wrote:
> std::cout << std::endl;
> }
 
> /Flibble
 
Ugh. Even:
 
for (size_t i = str.size(); i+1 > 0; --i)}
 
}
 
even better than that monstrosity. "Idioms" that arise to work around braindead design choices (e.g. an unsigned type as a decreasing index).
 
The real solution -- that results in actually readable code rather than reliance on an ugly "idiom" -- is simply use an unsigned type for decreasing index unless you can absolutely help it. 31 bits of indices are enough for anyone.
Mel <mel@zzzzz.com>: Jun 08 04:03PM +0300

On Mon, 8 Jun 2015 05:52:49 -0700 (PDT), gwowen <gwowen@gmail.com>
wrote:
> On Friday, June 5, 2015 at 9:41:32 PM UTC+1, Mr Flibble wrote:
> > On 05/06/2015 19:25, Doug Mika wrote:
> > > I found this on a discussion group, and it said that the
following will cause an infinite loop, but why?
 
> for (size_t i = str.size(); i+1 > 0; --i)}
 
 
> }
 
 
> even better than that monstrosity. "Idioms" that arise to work
around braindead design choices (e.g. an unsigned type as a
decreasing index).
 
Nope, it is not better as indice have to be subtracted..
 
--
Press any key to continue or any other to quit
David Brown <david.brown@hesbynett.no>: Jun 08 03:22PM +0200

On 08/06/15 15:03, Mel wrote:
> around braindead design choices (e.g. an unsigned type as a decreasing
> index).
 
> Nope, it is not better as indice have to be subtracted..
 
Do you mean you need to write this?
 
for (size_t i = str.size(); i + 1 > 0; --i) {
std::cout << str[i - 1];
}
 
It's a little inconvenient, but IMHO it is still better than the "arrow
idiom". But for such code, I'd rather write:
 
size_t i = str.size();
while (i--) {
std::cout << str[i];
}
 
(Yes, I know that "--i" is more common in C++, and "i--" looks like C -
but it's find to use it when it makes sense.)
 
If I see a "for" loop that doesn't have all three sections (or even
worse, has multiple comma-separated sub-sections), I usually switch to a
while loop.
gwowen <gwowen@gmail.com>: Jun 08 08:11AM -0700

On Monday, June 8, 2015 at 2:22:54 PM UTC+1, David Brown wrote:
 
> for (size_t i = str.size(); i + 1 > 0; --i) {
> std::cout << str[i - 1];
> }
 
Actually, somewhere between the two...
 
Either
for (size_t i = str.size(); i > 0; --i) {
std::cout << str[i - 1];
}
 
or
 
for (size_t i = str.size()-1; i+1 > 0; --i) {
std::cout << str[i];
}
 
 
 
> It's a little inconvenient, but IMHO it is still better than the "arrow
> idiom".
 
I agree.
 
> while (i--) {
> std::cout << str[i];
> }
 
That's better. I may even go for:
while (i) {
i -= 1;
std::cout << str[i];
}
 
but that's just personal preference. (I have a thing against testing ++i or i++ because although I know the difference, I have to consciously recall it, and that makes the code less readable. I assume YM does V.)
 
> If I see a "for" loop that doesn't have all three sections (or even
> worse, has multiple comma-separated sub-sections), I usually switch to a
> while loop.
 
Me too. I don't care for piling up multiple non-trivial termination/initialisation conditions inside the for(...), though I'm OK with relatively trivial things like
 
for(i = 0, a = &arr1, b=&arr2 ; i < 10 ; ++i, ++a, ++b)
{
 
}
gwowen <gwowen@gmail.com>: Jun 08 09:04AM -0700

On Monday, June 8, 2015 at 4:21:14 PM UTC+1, Stefan Ram wrote:
 
> #include <climits>
 
> And what is the value of i+1,
> when str.size() == SIZE_MAX?
 
If you ever manage to find a system on which one can generate a string with
 
str.size() == SIZE_MAX;
 
we can both find out. Disregarding address-space exhaustion (extremely likely,but I guess not totally theoretically impossible), the need store the terminating the null character for str.c_str() means you'd have an object of size SIZE_MAX + 1. So, NOT A THING.
 
So until then, its a total irrelevance to the act of programming; an "Angels on the head of a pin" question.
 
... shakes head sadly ...
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 08 05:35PM +0100

On 08/06/2015 17:10, Stefan Ram wrote:
 
> . Maybe we can get rid of the addition by:
 
> for( size_t i = str.size() - 1; i !=( size_t )-1; --i )
 
> ?
 
Just use the arrow idiom as it works, has no horrible casts, doesn't
involve modulo arithmetic that you have to scratch your head to work out
what it is doing and is more efficient than gwowen's nonsense.
 
/Flibble
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 08 12:38PM -0400

On 6/8/2015 11:11 AM, gwowen wrote:
> std::cout << str[i];
> }
 
> but that's just personal preference. (I have a thing against testing
++i or i++ because although I know the difference, I have to consciously
recall it, and that makes the code less readable. I assume YM does V.)
 
Idiosyncrasy? When I see
 
i -= 1;
 
instead of
 
--i;
 
I can only think, as an old lady puts it, "everybody has their own
cockroaches in their head". Consciously recall what about what? It's a
decrement, FCOL, and nothing else.
 
There is no difference between --i and i-- if that's _the entire_
statement, is there? Of course, there is no difference between those
and i-=1 , as well. Yet I've seen people define such a useful function:
 
void decrement(int & i) { --i; }
 
and I always wondered as to their motivation (or sanity, for that
matter). But don't let's go exploring those murky depths, please.
 
V
--
I do not respond to top-posted replies, please don't ask
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: