- Comparison to std::numeric_limits<double>::max() - 11 Updates
- Long identifiers, poor readability - 10 Updates
- Long identifiers, poor readability - 3 Updates
- I correct a typo, please read again - 1 Update
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. |