Monday, April 30, 2018

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

Tim Rentsch <txr@alumni.caltech.edu>: Apr 29 10:16PM -0700


> The failure you see of std::numeric_limits<double>::max()
> to compare equal to itself [...] (probably) does not violate
> the letter of the c++ standard.
 
What leads you to think the C++ standard allows this? Are
there any specific citations you can offer that support
this view? AFAICT the C and C++ standards admit no leeway,
and the comparison must give a result of equal.
Tim Rentsch <txr@alumni.caltech.edu>: Apr 29 10:41PM -0700

> number does not have an exact representation in binary. It will
> probably yield different results when loaded into either a 64-bit or a
> 80-bit register.
 
None of those things matter. The Standard requires a particular
value be returned, however the implementation chooses to do it.
 
> Add some minor optimizer bugs and one can easily
> imagine that there might be problems when comparing this number with
> itself, even if it should work by the letter of the standard.
 
If you don't trust your compiler, get a different compiler.
 
If you think it's important to run sanity checks be sure the
compiler doesn't have bugs, by all means do so.
 
But don't give in to superstitious programming practices. Insist
on solid understanding and a rational decision process, not murky
justifications based on uncertainty and fear. Anyone promoting
voodoo programming principles should be encouraged to change
occupations from developer to witchdoctor.
Juha Nieminen <nospam@thanks.invalid>: Apr 30 05:57AM

>> 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.00000000000000000000
>> 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.00000000000000000000
 
> The two numbers are the same to the last digit.
 
If you want to print two floating point numbers in order to see if they
are bit-by-bit identical, you shouldn't print the in decimal. Conversion
to decimal may cause rounding errors (because floating point values are
internally represented in terms of powers of 2, while decimal is in
terms of powers of 10).
 
Either print the raw byte values of the floating point variable (eg.
in binary format), or use std::printf with the format specifier "%a"
which prints it in hexadecimal. (This is a bit-by-bit accurate
representation because converting from base-2 to base-16 can be
done losslessly, without need for rounding.)
 
There might have been an equivalent to "%a" for std::ostream, but
I don't remember now if there was.
Andrea Venturoli <ml.diespammer@netfence.it>: Apr 30 10:05AM +0200

On 04/27/18 08:44, Andrea Venturoli wrote:
> Hello.
> ...
 
First off, thanks to anyone who got intersted in the matter.
I wrote to the clang-dev mailing list and received a precise answer.
 
 
 
 
I'll try to summarize everything here:
 
_ my first assumption that comparing std::numeric_limts<double>::max()
to itself was failing was wrong; the problem was another;
 
_ BTW, this comparing must work (or it would be a bug in the
compiler/system/etc...);
 
_ my real problem was that:
a) I had enabled FP exceptions (in particular overflow);
b) with optimizations on, the compiler would speculatively execute a
branch that would not run under proper program flow and such a branch
generated an FP exception.
 
_ My code was deemed as problematic because, in order to enable
exceptions (or use anything from <cenv>), the compiler should be
informed (by using #pragma STDC FENV_ACCESS on). Failure to do this will
let the optimizer take wrong assumptions.
 
_ BTW, I found some sources which say the above actually is C++
standard, some say it's C standard (possibly inherited by C++ or not),
some say it's an extension a compiler might support. I don't have access
to C++ standard.
 
_ In any case, Clang does not support that #pragma, so there's right now
no way to get FP exception to play nicely with optimizations.
There's work going on, but no estimate on the release.
 
 
 
bye
av.
Paavo Helde <myfirstname@osa.pri.ee>: Apr 30 11:10AM +0300

On 30.04.2018 8:41, Tim Rentsch wrote:
>> imagine that there might be problems when comparing this number with
>> itself, even if it should work by the letter of the standard.
 
> If you don't trust your compiler, get a different compiler.
 
That's not about my compiler. I need the code to be compiled by
different compilers and we do not have time or resources to test them
all, especially those which have not yet been written.
 
> If you think it's important to run sanity checks be sure the
> compiler doesn't have bugs, by all means do so.
 
Thanks, our software has a huge suite of automatic unit and integration
tests. With their help we recently located and eliminated a randomly
flipping bit in the physical memory of the testing server which the
memory diagnostic tools failed to diagnose.
 
> justifications based on uncertainty and fear. Anyone promoting
> voodoo programming principles should be encouraged to change
> occupations from developer to witchdoctor.
 
What one man calls superstitious hunch, another man calls experience. I
would not have written a direct comparison with
std::numeric_limits<double>::max() because I have had some experience
with compiler/optimizer bugs and where are the murky corners. As it came
out else-thread my suspicions were justified, the problem indeed appears
to be a bug in the compiler, triggered indeed by the presence of
std::numeric_limits<double>::max() in the code (albeit the bug was a
different and more interesting one from what I had imagined).
 
I get payed for writing software working as reliably as possible in the
real world. This has a lot to do with anticipating and avoiding or
working around any bugs or problems in the
standards/OS-es/compilers/toolchains/third-party libraries, etc.
Tim Rentsch <txr@alumni.caltech.edu>: Apr 30 04:42AM -0700


> I found some sources which say the above actually is C++ standard,
> some say it's C standard (possibly inherited by C++ or not), some
> say it's an extension a compiler might support.
 
Support is required in ISO C, implementation-defined in C++.
 
> I don't have access to C++ standard.
 
Get free draft here:
 
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf
"James R. Kuyper" <jameskuyper@verizon.net>: Apr 30 08:58AM -0400

On 04/30/2018 01:57 AM, Juha Nieminen wrote:
...
> done losslessly, without need for rounding.)
 
> There might have been an equivalent to "%a" for std::ostream, but
> I don't remember now if there was.
 
Starting with C++2011, if str.flags() has both ios_base::fixed and
ios_base::scientific set at the same time, that's equivalent to %a or
%A, depending upon whether ios_base::uppercase is also set.
(24.4.2.2.2p5 - Table 76).
"James R. Kuyper" <jameskuyper@verizon.net>: Apr 30 09:29AM -0400

On 04/29/2018 04:12 PM, Paavo Helde wrote:
...
 
> From here you can clearly see there might be problems. This constant is
> specified in decimal and I believe there is a fair chance this number
> does not have an exact representation in binary.
 
True. But keep in mind that this definition is intended to be used only
by a particular implementation of C++ - one that provides the <limits>
and <cfloat> headers that you're looking at. The implementor has a
responsibility for making sure that the this particular floating point
constant will be converted BY THAT IMPLEMENTATION to the particular
floating point value which represents the maximum possible double value.
It can be proven, following the rules governing the interpretation of
floating point constants, that there do exist constants for which that
would be true. I would expect the implementor to choose the shortest
such constant.
 
This is complicated by the fact that some implementations of C++
(including, for some reason, some of the most popular ones on Windows)
consist of a compiler created by one vendor, combined with a C++
standard library created by a different vendor. However, if the compiler
and the library don't work together to interpret DBL_MAX correctly, then
that combination of compiler and library does not constitute a fully
conforming implementation of C++. Neither vendor should endorse using
their products together unless they've made sure that they do, together,
qualify as fully conforming (at least, when the appropriate options are
chosen). You shouldn't use them together unless at least one of the two
vendors has endorsed using them together.
 
If you don't have good reason to believe that an implementor has
bothered checking whether their implementation actually conforms (at
least, when you've chose the options that are supposed to make it
conform), then whether or not DBL_MAX is exactly the maximum finite
value for a double is going to be the least of your problems.
"James R. Kuyper" <jameskuyper@verizon.net>: Apr 30 10:02AM -0400

On 04/30/2018 04:05 AM, Andrea Venturoli wrote:
...
> let the optimizer take wrong assumptions.
 
> _ BTW, I found some sources which say the above actually is C++
> standard, some say it's C standard (possibly inherited by C++ or not),
 
The STDC FENV_ACCESS pragma is defined by the C standard. The entire C
standard library was incorporated by reference into the C++ standard,
with precisely specified modifications, but for the rest of the C
language, it's incorporated into the C++ standard only if the C++
standard explicitly says so. What it says about this pragma is that
support for it is implementation-defined.
 
> some say it's an extension a compiler might support. ...
 
"Implementation-defined" is a marginally stronger requirement than
"supportable extension": an implementation's documentation is required
to specify whether or not it's supported, and the standard specifies
what it means if supported.
 
> ... I don't have access
> to C++ standard.
 
The final draft of C++2017 is almost identical to the final approved
standard, and is a LOT cheaper:
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf>
Manfred <noname@invalid.add>: Apr 30 04:17PM +0200

On 4/28/2018 2:35 PM, Andrea Venturoli wrote:
> On 04/28/18 11:42, Tim Rentsch wrote:
[...]
> }
 
> Prints '1' and value of A on -O0.
> Prints '1' and then fails on -O1.
[...]
>> exception before the conditional move can take effect.
 
> That's my hypotesis too.
 
>>> Is this just my opinion or a bug worth reporting?
 
This is definitely a bug worth reporting:
n4659 sec. 8.16 (Conditional operator) p.1:
 
"... The first expression is contextually converted to bool (Clause 7).
It is evaluated and if it is true, the result of the conditional
expression is the value of the second expression,
otherwise that of the third expression. Only one of the second and third
expressions is evaluated. ..."
 
The relevant part is that "Only one of the second and third expressions
is evaluated.", so A*2 should /not/ be evaluated.
clang is definitely wrong here.
 
Manfred <noname@invalid.add>: Apr 30 10:32PM +0200

On 4/30/2018 7:41 AM, Tim Rentsch wrote:
> justifications based on uncertainty and fear. Anyone promoting
> voodoo programming principles should be encouraged to change
> occupations from developer to witchdoctor.
 
The fact that comparing floating point values with == is inherently
brittle is a *fact*, and there is nothing superstitious with it.
 
Floating point programming has its own peculiarities; knowing that ==
comparisons are to be avoided is one of them.
Juha Nieminen <nospam@thanks.invalid>: Apr 30 05:43AM

> When examined in isolation, yes. However, this pattern does often
> repeat and it becomes a tedious pain in the neck.
 
Code readability requires following coding conventions. Writing namespace
prefixes can be a good coding convention.
Paavo Helde <myfirstname@osa.pri.ee>: Apr 30 09:03AM +0300

On 29.04.2018 20:45, Jouko Koski wrote:
>> this alternative should work?
 
> I thought I was asking the question. :-) Well, the ultimate goal is to
> improve readability
 
One thing you forget here is that readability depends on the reader.
What is easily recognized by one reader might not be recognized by another.
 
If I am familiar with the codebase and know there is no custom string
class there, then seeing a type name string automatically means this
must be a std::string. If I am not familiar with the codebase, then it
is not so clear at all.
 
When I see an identifier like socket in some foreign or long-forgotten
code I am just trying to debug this is not readable at all. What does it
mean, how do I construct one? Man socket says it is a function.
 
I will need to figure out somehow that it is a
boost::asio::ip::tcp::socket (or then something else). If I read this
code once in 5 years, I would like to have it all spelled out. If I read
and write this code each day, then I want it to be shortened to just
socket. The readability goals are different.
"Jouko Koski" <joukokoskispam101@netti.fi>: Apr 30 12:02PM +0300

"Vir Campestris" wrote:
> Two things:
 
> Why would I want to limit the line to 80 chars? My screen is bigger than
> that, and has been for 20 years at least.
 
80 may not be the exact value, but longer lines tend to deteriorate
readability, and that is fairly universal. Then, team members may be
reading code on paper or on their smartphones, and there are still old
vga projectors out there. Some people may be visually impaired or just
prefer to use the ample horizontal space for placing the working
windows side by side.
 
> std::list<
> IpAddress
 
> >;
 
Line folding tend to break the visual flow. Folding convention and
indentation do matter. Sometimes it may be insightful to replace all
printable characters in a source file (or in any text, for the matter!)
with X characters, and assess if the pattern still communicates
structure, function, and intent.
 
> Apparently the Linux kernel standard is to stop excessive nesting. so
> why doesn't it limit nesting instead?
 
Well, it does, doesn't it?
 
--
Jouko
Ian Collins <ian-news@hotmail.com>: Apr 30 09:55PM +1200

On 04/30/2018 08:53 AM, Vir Campestris wrote:
 
> Two things:
 
> Why would I want to limit the line to 80 chars? My screen is bigger than
> that, and has been for 20 years at least.
 
Some of us have very wide screens, but like to look at multiple files
side by side. Screen size and line length are unrelated.
 
--
Ian.
Tim Rentsch <txr@alumni.caltech.edu>: Apr 30 05:17AM -0700

>> That resembles noise.
 
> Two things:
 
> Why would I want to limit the line to 80 chars?
 
There are good human factors reasons to limit lines to somewhere
in the neighborhood of 75 characters. It's no accident that
paper is taller than it is wide.
 
> My screen is bigger than that, and has been for 20 years at least.
 
Not really a good argument. Just because something can be done
doesn't mean it's a good idea to do it. Also there are other
output media to consider: even if you are happy to view code
only on your wide screen, other people want to look at code
using different media.
 
> std::list<
> IpAddress
 
> >;
 
If it were important to write this declaration on more than one
line, I would be inclined to take more advantage of horizontal
space, reducing the amount of vertical space used:
 
using ResolverMap =
std::map< std::string, std::list< IpAddress > >
;
 
or perhaps
 
using ResolverMap =
std::map<
std::string,
std::list< IpAddress >
 
;
"James R. Kuyper" <jameskuyper@verizon.net>: Apr 30 10:15AM -0400

On 04/29/2018 04:53 PM, Vir Campestris wrote:
...
> Why would I want to limit the line to 80 chars? My screen is bigger than
> that, and has been for 20 years at least.
 
Because scanning a long line is hard work for your eyes. There's a
reason why newspaper columns are so narrow: they're about the maximum
width that your eyes can see at one time without scanning left-to-right.
You can read a newspaper column scanning only in the vertical direction.
Books and magazines typically are wider, because it's not necessary to
completely avoid horizontal scanning. However, anything larger than
about 80 characters puts excess strain on your eye muscles - which is
why 80 characters was a popular choice for both printers and display
screens.
scott@slp53.sl.home (Scott Lurndal): Apr 30 03:09PM

>about 80 characters puts excess strain on your eye muscles - which is
>why 80 characters was a popular choice for both printers and display
>screens.
 
And here I always though it was to match 80-column cards. And note
that printers were generally 132 columns before consumer (cheap)
printers became widely available.
"James R. Kuyper" <jameskuyper@verizon.net>: Apr 30 11:31AM -0400

On 04/30/2018 11:09 AM, Scott Lurndal wrote:
 
> And here I always though it was to match 80-column cards. And note
> that printers were generally 132 columns before consumer (cheap)
> printers became widely available.
 
I'm giving part of the reason why (among other things) 80-column cards
became more popular than other sizes, and why 80 column printers became
more popular than 132 column ones.
scott@slp53.sl.home (Scott Lurndal): Apr 30 03:40PM

>> printers became widely available.
 
>I'm giving part of the reason why (among other things) 80-column cards
>became more popular than other sizes
 
Hm. Given that interpreted cards (i.e. cards with column content printed on them)
were generally quite rare, particularly in the first half of the 20th
century, I'm not sure that eyestrain had anything to do with the choice
of 80-columns for cards.
 
 
>, and why 80 column printers became
>more popular than 132 column ones.
 
Again, I can't see (pun unintended) that. I can see that when
using 8.5x11 paper in a printer, portrait mode printing at 10cpi
(a readable size for most) yields 80 columns - so I think the
relationship is more about using 8.5 inch wide paper than 80 columns per-se.
"James R. Kuyper" <jameskuyper@verizon.net>: Apr 30 11:40AM -0400

On 04/30/2018 11:16 AM, Stefan Ram wrote:
> also have a higher resolution, so sometimes more characters
> fit into the same width when the width is measured by the
> arc width it has for the eye (i.e., measured in degrees).
 
Your eyes have much higher resolution in the fovea than in peripheral
areas, and that resolution is needed when reading densely packed text.
This isn't immediately obvious, because whenever you try to pay
attention to a part of your field of view that is not currently
projected onto your fovea, your eyes automatically move to project it
onto that area, creating the illusion that we can see at high resolution
across our entire field of view.
 
> that a slideshow with pictures or a movie should not use the
> full width of the screen but be restricted to an area of
> smaller width.
 
As a general rule, film makers keep things that require high resolution
viewing near the center of the field of view; the edges tend to be
occupied by images for which the lower resolution of our our peripheral
vision is sufficient, either because they don't have much fine detail,
or because the fine detail isn't important.
ram@zedat.fu-berlin.de (Stefan Ram): Apr 30 02:58PM

>Because scanning a long line is hard work for your eyes. There's a
>reason why newspaper columns are so narrow: they're about the maximum
>width that your eyes can see at one time without scanning left-to-right.
 
I also prefer long lines sometimes.
 
Today, we prefer longer identifiers, so lines become long
by the longer identifiers without becoming more complex.
 
For example, from my "real" code,
 
int result = de.dclj.ram.algorithm.gregorian.YearMonthDay.difference( yearParameter, monthParameter, dayParameter ).plus( 6 ).mod( 7 );
 
(140 characters). You might attack this line for several
stylistic reasons, but I believe splitting it into several
lines will not help much.
 
If narrow newspaper columns help reading that much, then why
are book pages usually /not/ split into several narrow columns?
 
Another example, would be a small Java block to interchange
the value of two variables:
 
{ final var tmp = a; a = b; b = tmp; }
 
. This helps to see the block as a "unit". Also "a; a" and
"b; b" - as with domino pieces - help to check the right
order of statements. It can be identified by the brain as a
"chunk" to interchange two values.
 
(In Java, one cannot write a function nor a macro to
swap to variables.)
 
However, Usenet is deemed by me to be a special place for
which I usually format all my lines to contain 72 characters
at most. So, for Usenet, I'd write:
 
int result =
de.dclj.ram.algorithm.gregorian.YearMonthDay.difference
( yearParameter, monthParameter, dayParameter ).plus( 6 ).mod( 7 );
 
. PS: In my previous post I added a wrong reference to the
"References:" header line, so that it appeared as if I had
responded to a post of yours while in the body I responded
to Jouko only. Sorry for that!
ram@zedat.fu-berlin.de (Stefan Ram): Apr 30 03:04PM

>If narrow newspaper columns help reading that much, then why
>are book pages usually /not/ split into several narrow columns?
 
(PS: I now have seen that this already was addressed by James.)
ram@zedat.fu-berlin.de (Stefan Ram): Apr 30 03:16PM

>about 80 characters puts excess strain on your eye muscles - which is
>why 80 characters was a popular choice for both printers and display
>screens.
 
However long a line is, it always will fit into the screen
(when editing). Today's Screens are somewhat wider but they
also have a higher resolution, so sometimes more characters
fit into the same width when the width is measured by the
arc width it has for the eye (i.e., measured in degrees).
 
And if there would be such a strain, this also would imply
that a slideshow with pictures or a movie should not use the
full width of the screen but be restricted to an area of
smaller width.
 
Some people intentionally roll their eyes from side to side
and call this "ophthalmic gymnastics". It also sometimes
is reported to help to find a memory of something in the
brain.
 
A real problem with adjusted paragraphs (right-aligned) is
that it can be hard to find the beginning of the next line
when lines are too wide because all lines look the same.
This, however, does not apply to source code.
Juha Nieminen <nospam@thanks.invalid>: Apr 30 05:58AM

> I correct a typo, please read again:
 
Could you please stop spamming?
 
If the topic is C++, then it's fine, but just stop spamming the same
thing over and over.
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: