- Usenet group for compiler development - 2 Updates
- Undefined Behaviour - 5 Updates
- an alternative to finally - 4 Updates
- vector<>::erase-behaviour - 2 Updates
- Remove the last argument from a parameter pack - 1 Update
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Apr 09 03:43PM -0400 Is there a Usenet group explicitly devoted to literal C or C++ compiler development? Specifically in the areas of optimization techniques? TYIA. -- Rick C. Hodgin |
Philipp Klaus Krause <pkk@spth.de>: Apr 09 10:54PM +0200 Am 09.04.19 um 21:43 schrieb Rick C. Hodgin: > Is there a Usenet group explicitly devoted to literal C or C++ compiler > development? Specifically in the areas of optimization techniques? > TYIA. Not specific to C/C++ or optimization: comp.compilers |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Apr 09 02:23AM -0700 > There is no way to say that the program itself, without considering > its invocation, has UB or no UB. It has the potential for UB. For some > input. My apologies for the long delay in responding. Clearly programs that depend on one or more input values may have undefined behavior for some particular sets of input values. But that doesn't mean all programs may exhibit undefined behavior. Note several points: (A) The program shown depends on an external input; (B) The value of the external input is held in the variable 'n', which is represented in the abstract machine; (C) The circumstance of undefined behavior arises from evaluating the '/' operator; and (D) The division operation has undefined behavior because there is an explicit stipulation of undefined behavior when the denominator has the value zero. Now consider this program: #include <stdio.h> unsigned ss( unsigned, unsigned ); int main(){ printf( " result is %u\n", ss( -1, 0 ) ); return 0; } unsigned ss( unsigned n, unsigned r ){ return n ? ss( n-1, r + n*n ) : r; } There is no external input. Moreover all of the program's constituent elements are well defined: no 'shall' clauses are violated, there are no explicit stipulations of undefined behavior, and there is an explicit definition of behavior for each program construct. In particular the behavior of the function call is defined, with no qualifying statement about memory being available. Do you agree with all that? If not which part(s) do you not agree with? (My comments here are meant to apply to both C and C++, with the same conclusions in the two cases. If you think there are any differences between the two please say what those are and why.) |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Apr 09 03:27AM -0700 Tiib <ootiib@hot.ee> writes: My apologies for the long delay in responding. I am snipping nearly everything in an effort to refocus the discussion. > Can you specifically show how my answers to your questions > did not address what was asked? Let me try to clarify by starting afresh and simplifying. First I would like to ask questions about C. The second part will consider the same questions about C++. First question: please consider this program (and remember we are starting considering the C language): int main(){ return (((0))); } Is the semantics for this program (A) well-defined, (B) undefined, or (C) other? Please answer with "A", "B", or "C". Second question: please consider this program, compiled in an environment where size_t is 64 bits and the program is accepted with no complaints from the compiler or linker: int main(){ char a[1000000000]; return 0; } Does the C standard impose requirements for what status is returned? Please answer "yes" or "no". Third question: please consider this program: #include <stdio.h> unsigned ss( unsigned, unsigned ); int main(){ printf( " result is %u\n", ss( -1, 0 ) ); return 0; } unsigned ss( unsigned n, unsigned r ){ return n ? ss( n-1, r + n*n ) : r; } (a) Does any construct in this program violate a 'shall' requirement? If so then which construct and which 'shall'? (b) Does any construct in this program encounter any explicit statement of undefined behavior? If so then which construct and which explicit undefined behavior? (c) Does every construct in this program have a passage or passages in the C Standard defining its behavior? If not then which constructs do not? (d) For those constructs that have passages defining the behavior, are any definitions only partially defined? If so then which constructs and which passages define those constructs? For all of the above subquestions, please answer "yes" or "no" to the first part, and for any second parts give references that are specific, explicit, direct, and unambiguous. For C++: same questions as above, but consider for programs in C++ rather than in C. Are there any differences in the answers between C and C++? If so then which questions? >>> I indeed do not understand how what I wrote can be perceived >>> as some sort of gibberish. I didn't say your writing was gibberish. What I did say is it didn't answer my questions. Am I right in thinking that English is not a first language for you? If so, my compliments, I am terrible with trying to speak other languages. In your writing though I do sometimes have trouble understanding, largely I think due to the style of construction, which I find somewhat long, convoluted, and indirect. It would help if you would go in the direction of short, simple, and direct. Try limiting your sentences to ten words or less. Does that make sense? |
Paavo Helde <myfirstname@osa.pri.ee>: Apr 09 02:06PM +0300 On 9.04.2019 12:23, Tim Rentsch wrote: > ss( unsigned n, unsigned r ){ > return n ? ss( n-1, r + n*n ) : r; > } FWIW, this program appears to compile and run properly in MSVC 2017 Release x64 build, and produces output: result is 2147483648 |
"Öö Tiib" <ootiib@hot.ee>: Apr 09 07:13AM -0700 On Tuesday, 9 April 2019 13:27:37 UTC+3, Tim Rentsch wrote: > } > Is the semantics for this program (A) well-defined, (B) undefined, > or (C) other? Please answer with "A", "B", or "C". A > } > Does the C standard impose requirements for what status is > returned? Please answer "yes" or "no". yes > } > (a) Does any construct in this program violate a 'shall' > requirement? If so then which construct and which 'shall'? no > (b) Does any construct in this program encounter any explicit > statement of undefined behavior? If so then which construct > and which explicit undefined behavior? no > (c) Does every construct in this program have a passage or > passages in the C Standard defining its behavior? If not > then which constructs do not? yes > behavior, are any definitions only partially defined? > If so then which constructs and which passages define > those constructs? no > programs in C++ rather than in C. Are there any > differences in the answers between C and C++? If so > then which questions? Not to my knowledge. May be there are some tiny issue somewhere that I did not notice but it does not matter. > long, convoluted, and indirect. It would help if you would > go in the direction of short, simple, and direct. Try limiting > your sentences to ten words or less. Does that make sense? Yes, I learned some English only after having some skill in three other languages. I do not think the issue is in language. So conforming implementations of C and C++ should accept and execute those programs within their resource limits. On case of exceeding these limits the behavior is undefined. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 09 05:05PM +0200 On 09.04.2019 11:23, Tim Rentsch wrote: > ss( unsigned n, unsigned r ){ > return n ? ss( n-1, r + n*n ) : r; > } A bit off-topic, but about such code if it /really/ had appeared anywhere: actually summing the squares is one needless complication and one introduction of needless inefficiency, and doing that summing via recursion, even tail recursion, is another such needless complication and needless possible inefficiency. Instead just `return (n*(n + 1)*(2*n + 1))/6`. That said, I never fully groked the pattern of the formulas of the sums of k'th powers, so have to google for k>1... :( > function call is defined, with no qualifying statement about > memory being available. Do you agree with all that? If not > which part(s) do you not agree with? I agree. It's UB with most (all?) implementations because it exceeds implementation limit on stack space. Now I don't recall exactly what the discussion was about, or what positions were held by whom, but there are some points I think are relevant. First, C++17 §4.1/2.1: <<If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute that program.>> where the word "execute" has attached a (non-normative) note, <<"Correct execution" can include undefined behavior, depending on the data being processed; see Clause 3 and 4.6.>> This is where the UB in your example would come from: when the code exceeds the resource limits, the implementation isn't obliged to execute it correctly. Since the standard places no requirements on what happens then, for incorrect execution, that's formally UB. Secondly, the standard is imperfect. It has the surface appearance of a formal document, but it relies on common sense and practicality in a number of places. For example, if one just defines /not/ blinking the NumLock light for a millisecond as a "diagnostic", then a compiler can do that non-blink and then accept any language extensions whatsoever. > (My comments here are meant to apply to both C and C++, with the > same conclusions in the two cases. If you think there are any > differences between the two please say what those are and why.) Well, at this late point it could help if you would state what the conclusion you arrived at, is. I'm sorry, I'm getting old, and today had my third kidney stone trying to take me on. I gave it a bunch of painkillers to chew on, but that had only marginal effect. Happily it gave up after just half an hour or so, but possibly deviously, with the intent and actual effect that when I arrived at the doctor's I was all fine. Cheers!, - Alf |
"Öö Tiib" <ootiib@hot.ee>: Apr 09 12:17AM -0700 On Monday, 8 April 2019 16:10:31 UTC+3, Bonita Montero wrote: > } > I think that's very handy for emulating finally. Is there already > a class like invoke_on_destruct in the C++ standard-library? I've never needed generic scope guards, but can try something randomly: #include <iostream> #include <memory> #include <string> // some ugly macros to get unique_ptr useful #define TP1(X, Y) X ## Y #define TP2(X, Y) TP1(X, Y) #define DEFER(CAPTURE,CODE) \ auto TP2(LMB,__LINE__) = [CAPTURE]() CODE; \ std::unique_ptr<decltype(TP2(LMB,__LINE__)), void(*) \ (decltype(TP2(LMB,__LINE__))*)> TP2(DEFERER,__LINE__) \ (&TP2(LMB,__LINE__), [](auto* p) {(*p)();}) // usage int main () { std::string str( "hello world" ); DEFER(&str, { std::cout << str << " 1" << std::endl; }); std::cout << "doing some stuff\n"; DEFER(&str, { std::cout << str << " 2" << std::endl; }); std::cout << "doing more stuff\n"; return 0; } output: doing some stuff doing more stuff hello world 2 hello world 1 Perhaps these macros confuse it more than help. |
Juha Nieminen <nospam@thanks.invalid>: Apr 09 12:35PM > I think that's very handy for emulating finally. Is there already > a class like invoke_on_destruct in the C++ standard-library? This is a really ugly hack, but you can abuse std::unique_ptr for the same purpose... int main() { std::unique_ptr<void, void(*)(void*)> finally ((void*)1, [](void*) { std::cout << "finally!\n"; }); std::cout << "test\n"; } Yeah, it's really ugly and cringey, but it works... |
Bonita Montero <Bonita.Montero@gmail.com>: Apr 09 02:56PM +0200 > std::cout << "test\n"; > } > Yeah, it's really ugly and cringey, but it works... The problem is here that you won't have a capture. |
Paavo Helde <myfirstname@osa.pri.ee>: Apr 09 04:18PM +0300 On 9.04.2019 15:56, Bonita Montero wrote: >> } >> Yeah, it's really ugly and cringey, but it works... > The problem is here that you won't have a capture. Capture is easy to add: #include <iostream> #include <functional> #include <memory> int main() { int x = 1; std::unique_ptr<void, std::function<void(void*)>> finally ((void*)1, [&x](void*) { std::cout << "finally x is " << x << "\n"; }); std::cout << "test\n"; x = 2; } |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Apr 09 03:45AM -0700 > an extension of a pointer that when working on a sequence always points > to a GIVEN item, and the invalidation rules tells you when that > assumption no longer holds. There is a key idea here, which I don't remember having seen before. Thank you for giving this explanation. |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Apr 09 03:56AM -0700 >>>>>>>> On 01/04/2019 13:31, Paavo Helde wrote: >>>>>>>>> On 1.04.2019 14:22, Tiib wrote: >>>>>>>>>> On Monday, 1 April 2019 11:42:06 UTC+3, Paavo Helde wrote: [..considering .erase() on a vector..] >> std::vector::erase_and_move_assign() then you could argue that >> identity is no longer lost as that is the intention. > Grudgingly, I have to admit this actually makes sense. Thanks! Looking at the passages in the C++ standard that refer to "object identity", ISTM that the phrase is basically isomorphic to where the object is, i.e., its address. I'm not looking to convince anyone but I thought some people might be interested to hear another take on the question. |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Apr 09 03:40AM -0700 >> [...] > Could you please stop replying to my posts. I find your condescension > and overall weirdness unappealing. TIA. The newsgroup is a public forum. I'm sorry if my comments came across as condescending; that doesn't match my mindset while I was writing nor my opinion of you generally. |
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