- What does "ill-formed" mean? - 3 Updates
- template madness - 5 Updates
- template madness - 2 Updates
Juha Nieminen <nospam@thanks.invalid>: Sep 08 05:00PM Seems like a relatively simple question, but I couldn't find clear answers. The standard mentions a lot the notion of something being "ill-formed", but it's not clear to me what exactly that means, and especially how it's different from undefined behavior or implementation defined. (The closest thing I could find is that if something is "ill-formed" a diagnostic from the compiler is required. Except that doesn't always seem to be the case either...) |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Sep 08 06:22PM +0100 > (The closest thing I could find is that if something is "ill-formed" > a diagnostic from the compiler is required. Except that doesn't always > seem to be the case either...) My starting point would be the definitions at the start of the standard. (Sorry if that's obvious.) 1.3.9 ill-formed program program that is not well formed 1.3.26 well-formed program C ++ program constructed according to the syntax rules, diagnosable semantic rules, and the One Definition Rule (3.2). Does this not fit all the situations you are seeing? It does match, pretty well, what you said was the closest thing you could find (so it's probably what yo are starting from too) but you did not say what the exceptions were so I can't be sure. -- Ben. |
"Öö Tiib" <ootiib@hot.ee>: Sep 08 12:17PM -0700 On Saturday, 8 September 2018 20:00:47 UTC+3, Juha Nieminen wrote: > (The closest thing I could find is that if something is "ill-formed" > a diagnostic from the compiler is required. Except that doesn't always > seem to be the case either...) The diagnostic is required for ill-formed program unless standard explicitly states that diagnostic is not required in particular situation. As for the difference between "ill-formed; no diagnostic required" and "undefined behavior", there isn't any to my knowledge. I suspect the inconsistency is because some authors of standard did think that all errors are undefined behavior unless said otherwise and others that all errors require diagnostic unless said otherwise. Both schools of language lawyers have otherwise tried to be as explicit as they can. |
"Öö Tiib" <ootiib@hot.ee>: Sep 08 03:01AM -0700 On Friday, 7 September 2018 15:02:21 UTC+3, Jorgen Grahn wrote: > > feature. > Why? I don't define my own std::printf() just because I never use the > %g format specifier. That was rhetorical, tongue in cheek? > More seriously, shipping with assert() enabled may be something you > dislike, but it doesn't violate the semantics of assert() itself. > Unlike many other common assert usage patterns. It is important reason of having our own "crash unless" instead of "assert". It can't be turned off without erasing it. Therefore it will indeed guarantee behavior. It guarantees that its arguments are evaluated. When the assumption fails then it guarantees to report about failure and to cause real crash instead of undefined behavior (that it most likely guards against). Also it guarantees that code reviewers, compilers and static analyzing tools see always actual [[ noreturn ]] function call there and therefore can not whine that variable might be used without initialization or pointer that might be null is dereferenced or array might be accessed out of bounds. Case where we really *prefer* undefined behavior to guaranteed crash is actually ultra rare and so deserves lengthy comment why. Why? No tongue in cheek here. |
"Öö Tiib" <ootiib@hot.ee>: Sep 08 03:04AM -0700 On Friday, 7 September 2018 15:58:25 UTC+3, Scott Lurndal wrote: > *snort* mmap is portable to a very large number of platforms - there > is only one that it is not directly portable to (but could be shimmed > on windows). All platforms that lack virtual memory also lack mmap. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Sep 08 05:11PM +0200 On 08.09.2018 12:01, Öö Tiib wrote: > On Friday, 7 September 2018 15:02:21 UTC+3, Jorgen Grahn wrote: [snip] > [[ noreturn ]] function call there and therefore can not whine that > variable might be used without initialization or pointer that might > be null is dereferenced or array might be accessed out of bounds. Hm, [[noreturn]] for a macro that normally does return? auto foo( int x ) -> std::string { CRASH_UNLESS( x == 42 ); // This function always has UB except when x is 42. // Diagnostic silenced by the [[noreturn]] nature of CRASH_UNLESS } > Case where we really *prefer* undefined behavior to guaranteed crash > is actually ultra rare and so deserves lengthy comment why. Why? > No tongue in cheek here. I like the idea of well-defined behavior. Cheers!, - Alf |
Paavo Helde <myfirstname@osa.pri.ee>: Sep 08 07:21PM +0300 > For instance, if assert(a<b) would > be triggered, I'd want information about the current values of a and b. In an interpreted language supporting such assert would be easy. If an assert fails, the interpreter will take the assert expression, parse it into a syntax tree, evaluate each tree node and output the values to the log file or include them in the error message as appropriate. In principle one should be able to do the same in C++ as the asserted expression is known at compile time; the compiler could generate code for calculating the subexpressions and outputting their values. Alas, I'm afraid C++ introspection features are not yet advanced enough that this task could be done in standard C++. Maybe there is some development happening or planned along these lines? |
"Öö Tiib" <ootiib@hot.ee>: Sep 08 11:53AM -0700 On Saturday, 8 September 2018 18:11:18 UTC+3, Alf P. Steinbach wrote: > > variable might be used without initialization or pointer that might > > be null is dereferenced or array might be accessed out of bounds. > Hm, [[noreturn]] for a macro that normally does return? Sorry for being ambiguous, I meant that CRASH_UNLESS to be usually a macro that expands to something like that: #define CRASH_UNLESS(EX) (void)((EX) || (report_and_crash(#EX, __FILE__ \ , __LINE__),false)) It is a macro because of __FILE__ and __LINE__ and to achieve that [[noreturn]] function report_and_crash is called only when the expression EX evaluates to false. |
ram@zedat.fu-berlin.de (Stefan Ram): Sep 08 03:06PM >run-time context in which it failed. For instance, if assert(a<b) would >be triggered, I'd want information about the current values of a and b. >And I almost always want it to perform needed clean-up. I would use »assert« mainly for assertions that should never be false if I write my code correctly and should not be checked at all in production code. Assertions whose negation I deem to be impossible ("can't happen"). For those cases, the biggest gain already is realized when one is made aware of them should they ever happen. This is what one can accomplish with »assert« in an unobtrusive and time-saving manner. If I would write if( a >= b ) { ::std::cout << "assertion failed!\na = " << a << ", b = " << b << '\n'; throw my_usual_assertion_failure_exception; } this would distract from the actual code and might be so much effort for that case of something that I never expect to happen that I'd rather omit it alltogether. Usually, I can still insert such code after observing a failed »assert« at this location. |
ram@zedat.fu-berlin.de (Stefan Ram): Sep 08 04:01PM >I would use »assert« mainly for assertions that should never >be false if I write my code correctly and should not be Quotation: |C and C++ provide an assertion facility in <assert. h> that |encourages adding pre- and post-condition tests. Since a |failed assertion aborts the program, these are usually |reserved for situations where a failure is really unexpected |and there's no way to recover. from "The Practice of Programming" by Brian W. Kernighan and Rob Pike |
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