- iostream formatting of special numbers - 10 Updates
- Mutually exclusive execution for threads, OK with g++ but not MSVC - 10 Updates
- static vs. runtime polymorphism - 1 Update
- Instantiate different definition of ctor from template parameter - 1 Update
- bool foo = [](){}; - 1 Update
"Öö Tiib" <ootiib@hot.ee>: Apr 15 03:19AM -0700 > Does the standard say anything about the format of the output of > special numeric values, like NaNs and Infs, when formatted by > iostreams? No. Also it is possible for example that in conforming implementation std::strtod and istream>> parse infs and nans differently. > I'm writing the iostream routines for some numeric routines. Basically ... avoid istream>> and ostream<<. These are slow and behave non-portably. > Or have I just managed to miss the specification? No. If you need text transmission between different modules then use some well-established serialization language like xml, json or yaml. These have standardized specifications and well-performing and -tested libraries for generating and parsing can be found. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Apr 15 08:56AM -0400 > Does the standard say anything about the format of the output of > special numeric values, like NaNs and Infs, when formatted by > iostreams? The behavior of to_string() for floating point arguments is defined in terms of the C standard library function sprintf() with "%f" or "%Lf" format specifiers (24.3.4p7). I'm fairly certain the specifications for <iostream> cross-references to_string() somehow, but I'm in a bit of a hurry, so I'll let someone else track down the precise specification. You have to cross-reference the C standard to find out what that means for those special values: "A double argument representing an infinity is converted in one of the styles [-]inf or [-]infinity — which style is implementation-defined. A double argument representing a NaN is converted in one of the styles [-]nan or [-]nan(n-char-sequence) — which style, and the meaning of any n-char-sequence, is implementation-defined. The F conversion specifier produces INF, INFINITY, or NAN instead of inf, infinity, or nan, respectively." (C 7.21.6.1p8). While the output is partially implementation-defined, there are parts you can rely on. However, I see no way to determine from inside your program where the implementation-defined n-char-sequence ends. |
Daniel <danielaparker@gmail.com>: Apr 15 06:23AM -0700 On Monday, April 15, 2019 at 6:19:13 AM UTC-4, Öö Tiib wrote: > Basically ... avoid istream>> and ostream<<. > These are slow and behave non-portably. Agreed, for the non-portably. There's also the issue of how many decimal digits to preserve, to avoid losing precision. You could set that to std::numeric_limits::max_digits10 (generally 17), but then you won't have shortest representations for many numbers. > json or yaml. These have standardized specifications and > well-performing and -tested libraries for generating and > parsing can be found. Agreed, but ... The json data format doesn't support nan/inf/-inf, it suggests that these be reported as null. One or two json decoders/encoders support conversion to strings "nan", "inf", "-inf", and back, but this is non standard and non interoperable. The yaml data format does support "nan", "inf", "-inf", but I think it's fair to say it's not nearly as well established as json or xml. Another alternative would be one of the JSON like binary format such as CBOR that supports nan, inf, and -inf. Daniel |
jameskuyper@alumni.caltech.edu: Apr 15 12:20PM -0700 On Monday, April 15, 2019 at 8:56:18 AM UTC-4, James Kuyper wrote: > format specifiers (24.3.4p7). I'm fairly certain the specifications for > <iostream> cross-references to_string() somehow, but I'm in a bit of a > hurry, so I'll let someone else track down the precise specification. Correct citation, but not relevant. Sorry. The relevant citation is for num_put::do_put(), whose behavior for floating point types is defined in terms of passing "%f" to printf() (26.4.2.2.2p2 and p5). ostream::operator<<() for floating point types is defined in terms of calling do_put() (27.5.2.2p1). The rest of what I wrote is still relevant: |
Robert Wessel <robertwessel2@yahoo.com>: Apr 15 03:16PM -0500 On Mon, 15 Apr 2019 03:19:03 -0700 (PDT), 嘱 Tiib <ootiib@hot.ee> wrote: >json or yaml. These have standardized specifications and >well-performing and -tested libraries for generating and >parsing can be found. You've got it backwards. I have a library/class with types that should support the normal iostream functions. Thus I have to implement them, and need to handle things like Infs and NaNs. IOW, I'm trying to figure out what users of this library might be expecting in those cases. |
Robert Wessel <robertwessel2@yahoo.com>: Apr 15 04:20PM -0500 On Mon, 15 Apr 2019 12:20:39 -0700 (PDT), >> While the output is partially implementation-defined, there are parts >> you can rely on. However, I see no way to determine from inside your >> program where the implementation-defined n-char-sequence ends. Thank you, that's very helpful. To which version of the C++ standard are you referencing? All of the relevant information ("punt to printf definition") in C++17 appears to be in 25.2.2.2.2 (not 26.x), and I'm not sure what 27.5.2.2 is supposed to be referring to. It's probably not a great idea, but I'm toying with the idea of using sprintf() to generate the local forms of those (on first use, and then saving them). |
jameskuyper@alumni.caltech.edu: Apr 15 02:41PM -0700 > >> Does the standard say anything about the format of the output of > >> special numeric values, like NaNs and Infs, when formatted by > >> iostreams? ... > implement them, and need to handle things like Infs and NaNs. > IOW, I'm trying to figure out what users of this library might be > expecting in those cases. The requirement that I mentioned which cross-references the C standard only applies to float, double, and long double. If you're defining your own type to work with those routines, it's up to you to decide what you want, but it would probably be best to use the behavior for those types as inspiration. That being the case, you should understand the purpose of the "[-]nan(n-char-sequence)" option. std::nan("n-char-sequence") is defined as equivalent to std::strtod("NAN(n-char-sequence)"). The behavior of std::istream::operator>>() is defined in terms of std::strtod(), so C++ users can also use that function to achieve the same result. The behavior of std::strtod() for such strings is implementation- defined. For many implementations, calling strtod() with a suitable n- char-sequence will create a NaN which, when printed out, displays the same n-char-sequence - but the C standard fails to mandate such a connection. For an implementation that pre#defines __STDC_IEC_559__ the C standard does recommend for the <math.h> functions that "If a function with one or more NaN arguments returns a NaN result, the result should be the same as one of the NaN arguments (after possible type conversion), except perhaps for the sign." (C F10p13). On many implementations, the same is true of ordinary floating point math operations. The net result is that if a NaN in the inputs of a calculation is responsible for the fact that the result of the calculation is also a NaN, then the n-char- sequence can be used to determine which input NaN was responsible for that result. You get to choose whether you want to implement your types to allow the same kind of tracing - I'd recommend doing so. |
jameskuyper@alumni.caltech.edu: Apr 15 02:58PM -0700 > On Mon, 15 Apr 2019 12:20:39 -0700 (PDT), > jameskuyper@alumni.caltech.edu wrote: > >On Monday, April 15, 2019 at 8:56:18 AM UTC-4, James Kuyper wrote: ... > >> program where the implementation-defined n-char-sequence ends. > Thank you, that's very helpful. > To which version of the C++ standard are you referencing? I'm referring to n4762.pdf, the latest draft of the C++ standard that I have access to. It's dated 2018-07-07, making it more recent than C++17, which means it may include things that are not yet official, but nothing I mentioned in my message falls in that category. > relevant information ("punt to printf definition") in C++17 appears to > be in 25.2.2.2.2 (not 26.x), and I'm not sure what 27.5.2.2 is > supposed to be referring to. My mistake. In n4762.pdf, that should have been 27.7.5.2.2p1. In the draft version that most closely resembles the official C++2017 standard, n4659.pdf, the corresponding section is 30.7.5.2.2p1. > It's probably not a great idea, but I'm toying with the idea of using > sprintf() to generate the local forms of those (on first use, and then > saving them). When your other message referred to "types that should support the iostream requirements", I assumed that they were types you had to implement from scratch. If using sprintf() is an option, that satisfies the relevant requirements automatically, without you having to worry about the details, which is a lot simpler. I'd recommend that approach. |
Robert Wessel <robertwessel2@yahoo.com>: Apr 15 05:22PM -0500 On Mon, 15 Apr 2019 14:41:37 -0700 (PDT), >own type to work with those routines, it's up to you to decide what you >want, but it would probably be best to use the behavior for those types >as inspiration. The types in question will interoperable with normal floats, but are not actual floats in the sense of float/double/long double. But I am trying to follow the normal C++ behavior with these. I *think* I have Inf, NaN and zero handling under control in computational situations (although I'm basically following the IEEE FP rules, signed zeros excluded, not so much the C/C++ specs.). There's probably some open issues with when SNaNs actually signal in some of the semi-numerical functions. >char-sequence will create a NaN which, when printed out, displays the >same n-char-sequence - but the C standard fails to mandate such a >connection. strtod(NAN()) may be suitable as-is, as are the INF() cases. An implementation where those don't generate the same string as printf and iostream is probably classifiable as a bit perverse. Probably need to do some testing. It would probably force a final commitment to requiring C++11... >that result. >You get to choose whether you want to implement your types to allow the >same kind of tracing - I'd recommend doing so. We're not planning to support NaN payloads, although I'm willing to reconsider. It would only be a modest change. While I can see the theoretical benefit for being able to backtrack sources, I've never seen anyone actually use the facility for such. Of course then I have to pick a payload size, and figure out how inter-operate with floats. There seems to be a bit of a definitional issue with the NaN-string conversions, they appear to allow a NaN payload of zero, which for a QNaN would acually make it an Inf. Not my issue, though. |
Robert Wessel <robertwessel2@yahoo.com>: Apr 15 05:26PM -0500 On Mon, 15 Apr 2019 14:58:23 -0700 (PDT), >implement from scratch. If using sprintf() is an option, that satisfies >the relevant requirements automatically, without you having to worry >about the details, which is a lot simpler. I'd recommend that approach. They are ("from scratch"). I was thinking of hacking out the local representation by feeding a NaN or Inf float to sprintf. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Apr 15 09:10AM -0400 On 4/12/19 3:37 AM, Alf P. Steinbach wrote: >>> $use_cppx( is_empty ); >> You understand that this is a C++ newsgroup, right? > As I understand it you indicate that in your opinion the above is not C++. The meaning of your syntax is certainly not specified by the C++ standard. Any such use of '$' outside of a character or string literal is a C++ syntax error. You should not expect people monitoring comp.lang.c++ to know what it means in whatever context does allow you to use that syntax. It's also unreasonable to try to teach them that syntax. If you're posting here, you should post using standard C++ syntax, even if you normally use something else. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 15 04:04PM +0200 On 15.04.2019 15:10, James Kuyper wrote: > to use that syntax. It's also unreasonable to try to teach them that > syntax. If you're posting here, you should post using standard C++ > syntax, even if you normally use something else. It's not a non-standard syntax (though the $ is a non-standard token form -- syntax is one level up from that), it's an ordinary macro. It would be quite some work to rewrite the macro calls before posting, and ~zero work for a reader here to grok it. One simply does not include all the relevant parts of Boost if the code uses Boost, say. One doesn't expect to get helpful responses from people who fail to relate to some Boost functionality and need that source code posted in the group. The same for the above; it's sheer lunacy to require all library source code posted, instead of referenced. Therefore, unless there's a reasonable request for a pared down example (as was in one response), I just provide a link to some library that defines the macros, or other stuff used in the code. Re "whatever context does allow you", that's quite misleading. I don't know any environment where a compiler does not by default accept the above. Such an environment might exist, but your statement indicates that instead of being exceedingly rare, possibly non-existing, it's common, and that's very misleading and can't be based on actual experience. Cheers!, - Alf |
jameskuyper@alumni.caltech.edu: Apr 15 08:38AM -0700 On Monday, April 15, 2019 at 10:04:33 AM UTC-4, Alf P. Steinbach wrote: > > syntax, even if you normally use something else. > It's not a non-standard syntax (though the $ is a non-standard token > form -- syntax is one level up from that), it's an ordinary macro. The standard uses the notation described in 4.3 "Syntax Notation" to describe the rules for valid identifiers (5.10p1). I feel comfortable referring to violations of those rules as syntax errors - the standard doesn't provide any other simple term for referring to such violations. ... > Re "whatever context does allow you", that's quite misleading. I don't > know any environment where a compiler does not by default accept the > above. Any compiler that enforces C++ rules governing the characters permitted in identifiers should, at an absolute minimum, issue a diagnostic for such code when invoked in a fully conforming mode. I don't normally use any compiler in a non-conforming mode. > ... Such an environment might exist, but your statement indicates > that instead of being exceedingly rare, possibly non-existing, it's > common, and that's very misleading and can't be based on actual experience. Since I know what characters are permitted in identifiers, I never use the ones that aren't. It's therefore entirely possible that the compilers I've used tolerate characters that are not permitted, and might even be non-conforming by reason of failing to issue the mandatory diagnostic when they do so. That's not a sign of lack of experience, merely a failure on my part to exceed the limits of what's permitted, just for the joy of finding out what happens when I do. That's the same reason I don't have much experience with how compilers deal with division by 0, or how they deal with bit-wise operations on negative values. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 15 05:46PM +0200 > just for the joy of finding out what happens when I do. That's the same > reason I don't have much experience with how compilers deal with > division by 0, or how they deal with bit-wise operations on negative values. A claim of in-experience! In support of your view. But you're just adding noise in order to drown out the earlier exchange. You have no point, just a dislike. Cheers!, - Alf |
"Öö Tiib" <ootiib@hot.ee>: Apr 15 08:51AM -0700 > just for the joy of finding out what happens when I do. That's the same > reason I don't have much experience with how compilers deal with > division by 0, or how they deal with bit-wise operations on negative values. AFAIK $ was not allowed in identifiers until C++11. C++11 started to allow "and other implementation-defined characters" in identifiers. I'm in doubt that it is violation of standard not to diagnose presence of "other implementation-defined characters" in identifiers. |
jameskuyper@alumni.caltech.edu: Apr 15 09:29AM -0700 On Monday, April 15, 2019 at 11:46:12 AM UTC-4, Alf P. Steinbach wrote: > On 15.04.2019 17:38, jameskuyper@alumni.caltech.edu wrote: ... > > reason I don't have much experience with how compilers deal with > > division by 0, or how they deal with bit-wise operations on negative values. > A claim of in-experience! Yes, I routinely relevant disclaim experience that others might have expected me to have. Don't you? > In support of your view. Er, no? It was the C++ standard that I was using to support my view; explaining my inexperience was merely part of an explanation of why I cannot directly address your assertion that compilers which do this are commonplace. ... > You have no point, just a dislike. It's true that I dislike non-conformance with applicable and authoritative standards. However, my point was about the standard, not my dislike. My point would have been equally valid (and almost identically written), if I had been an enthusiastic supporter of this extension. |
Paavo Helde <myfirstname@osa.pri.ee>: Apr 15 07:39PM +0300 On 15.04.2019 17:04, Alf P. Steinbach wrote: > It's not a non-standard syntax (though the $ is a non-standard token > form -- syntax is one level up from that), it's an ordinary macro. > It would be quite some work to rewrite the macro calls before posting, If these are really macros, then a simple preprocessor run would get rid of them. > and ~zero work for a reader here to grok it. You must be kidding. Zero work for downloading and studying whatever framework/library is defining these macros? And for what purpose? |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 15 07:55PM +0200 On 15.04.2019 18:39, Paavo Helde wrote: >> It would be quite some work to rewrite the macro calls before posting, > If these are really macros, then a simple preprocessor run would get rid > of them Then you get some zillions of tons of code from the standard library added. But I guess I could write a simple name transformer. Will consider. >> and ~zero work for a reader here to grok it. > You must be kidding. Zero work for downloading and studying whatever > framework/library is defining these macros? And for what purpose? Well, `using` statements aren't exactly complex or rocket science. They're just annoyingly needlessly impractically verbose in C++. And the committee drags its feet, going by quarter-measures, where C++17 just allows you to not redundantly repeat the word `using` for each item. Cheers!, - Alf |
jameskuyper@alumni.caltech.edu: Apr 15 11:14AM -0700 On Monday, April 15, 2019 at 11:51:19 AM UTC-4, Öö Tiib wrote: > On Monday, 15 April 2019 18:38:45 UTC+3, james...@alumni.caltech.edu wrote: ... > > division by 0, or how they deal with bit-wise operations on negative values. > AFAIK $ was not allowed in identifiers until C++11. C++11 started > to allow "and other implementation-defined characters" in identifiers. I don't currently have access to older versions of the standard, but you're right about C++2011 and C++2014, but in C++2017 that part was removed, and it's not present in the latest draft I have access to (n4762.pdf, 2018-07-07), either. > I'm in doubt that it is violation of standard not to diagnose presence of > "other implementation-defined characters" in identifiers. Diagnostics are sometimes mandatory, but never prohibited. In the context of older versions of C++, I would have emphasized the greater portability of identifiers that don't rely upon the "other ..." option. |
jameskuyper@alumni.caltech.edu: Apr 15 11:28AM -0700 On Monday, April 15, 2019 at 12:29:52 PM UTC-4, james...@alumni.caltech.edu wrote: ... > Yes, I routinely relevant disclaim experience that others might have > expected me to have. Let me re-write that: I routinely disclaim relevant experience that others might expect me to have, if I don't actually have it. |
"Öö Tiib" <ootiib@hot.ee>: Apr 15 07:30AM -0700 On Saturday, 13 April 2019 19:42:31 UTC+3, bitrex wrote: > overloaded derived class methods through a base class pointer, in theory > to an "infinite" number of overloads in various derived classes. And has > the usual vtable + dynamic dispatch overhead. Note that when compiler can figure most derived type of object out compile time then it can call virtual methods directly or even inline those. > constraint somewhere I guess or you're just talking about regular > virtual based runtime polymorphism, again) that it works only with a > limited subset of potential subclasses designed expressly for that purpose. I do not know. The other way of dynamic polymorphism is to use function pointers. Bonuses compared with virtual method calls: * calls are cheaper by one level of indirection. * bigger flexibility since pointers can be re-directed during object's life-time. Minuses: * Object is bigger taking function pointer per "method". * Object's initialization code is bigger by setting these up. * Compilers tend to not optimize calls through function pointers. > virtualization "in disguise." I have read a bit about the "Visitor" > pattern which seems relevant to my question but don't know enough to > know for sure. Thanks Visitor pattern is double-dispatch pattern. Two virtual dispatches joined together for to find the right spot in visitor/visitable square. It means that technically we are paying *more* for adding new operations to visitables without modifying the classes of visitables. I am unsure if that was what you needed. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Apr 15 08:40AM -0400 On 4/13/19 7:14 AM, Bonita Montero wrote: > _theoretically_ shouldn't memcpy()'d. But in this case there > arent any complex members so that you won't get into trouble > with any compiler. "For any object (other than a base-class subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char. If the content of the array of char or unsigned char is copied back into the object, the object shall subsequently hold its original value." (3.9p2). It goes on to give memcpy() as an example of how such a copy could be performed. Note that this guarantee is tied to "trivially copyable type", not POD type. Trivially copyable classes are not allowed to have non-trivial copy, move, copy-assignment or move-assignment, constructors (9p6) - but other user-defined constructors are permitted. POD classes includes classes that are merely trivial, but not necessarily trivially copyable (9p10). |
James Kuyper <jameskuyper@alumni.caltech.edu>: Apr 15 07:56AM -0400 On 4/12/19 12:40 PM, Ben Bacarisse wrote: ... > bool from a pointer, and the application of ! to a pointer, use the > standard conversions, which is what you and Juha (and almost everyone!) > calls implicit conversions. As I understand it, "implicit conversions" should mean those conversions that can occur without requiring any explicit conversion operator: a C-style cast or one of the named casts. The C++ standard doesn't define an "implicit conversion", but it does define an "implicit conversion sequence" (13.3.3.1). Standard conversion sequences are only a subset of implicit conversion sequences. |
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:
Post a Comment