- string_view problem - 1 Update
- Overload by return type - 4 Updates
- How to deal with running out of stack space? - 1 Update
- string_view problem - 4 Updates
- Undefined Behaviour - 1 Update
ram@zedat.fu-berlin.de (Stefan Ram): Jun 26 05:32PM >"Effects: Determines the lowest position xpos, if possible, such that >both of the following conditions C++ and boost now use the "Effects: " label, which is good, because it makes clear which effects a call has. OTOH, it is sad to see this used incorrectly by authors writing for both boost and C++. The whole process of the determination of a result should be described either without a label or under the label "Returns: ", because this has nothing to do with an effect. An effect is everything that is /changed/ by the call, excluding internal operations that only can be observed indirectly via the value (result) of the call. A /correct/ example (written by me for this post): //! <b>Effects</b>: prints "example". //! <b>Returns</b>: the value of pi, determined by //! evaluating atan2( 1, 1 ) and multiplying it by 4. double f() { ::std::cout << "example"; return 4 * atan2( 1, 1 ); } But it is even better not to talk about implementation details as much as possible: //! <b>Effects</b>: prints "example". //! <b>Returns</b>: the value of pi double f() { ::std::cout << "example"; return 4 * atan2( 1, 1 ); } . |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 25 04:37PM -0700 On Saturday, June 22, 2019 at 6:56:25 AM UTC-4, David Brown wrote: > individual using them (they work far better when combined with "kill > thread" or "kill sub-thread" features). But they are totally > ineffective at keeping bad posts, or bad posters, out of the group. You shouldn't criticize something as ineffectual without taking into consideration what effect it was intended to achieve. Not seeing Rick's posts is an achievable goal. As you yourself admit above, keeping bad posts out of the group is not. Keith set his goal accordingly, and his killfile is fairly effective at achieving that goal. |
Keith Thompson <kst-u@mib.org>: Jun 25 05:38PM -0700 > posts is an achievable goal. As you yourself admit above, keeping bad > posts out of the group is not. Keith set his goal accordingly, and his > killfile is fairly effective at achieving that goal. Exactly. But its effectiveness is limited by people who insist on replying to, and quoting, Rick's spam. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
rick.c.hodgin@gmail.com: Jun 25 05:46PM -0700 On Tuesday, June 25, 2019 at 8:38:56 PM UTC-4, Keith Thompson wrote: > Exactly. But its effectiveness is limited by people who insist on > replying to, and quoting, Rick's spam. It wouldn't be hard to add a filter based on content. Anywhere you see "Rick C. Hodgin" or "Hodgin" even, delete the entire post. It doesn't have to come from me. It could just mention me any- where and be deleted. Thunderbird's email/news client has this ability. -- Rick C. Hodgin |
David Brown <david.brown@hesbynett.no>: Jun 26 06:33PM +0200 On 26/06/2019 01:37, James Kuyper wrote: > posts is an achievable goal. As you yourself admit above, keeping bad > posts out of the group is not. Keith set his goal accordingly, and his > killfile is fairly effective at achieving that goal. Yes, I agree - which was the point of my post. I had said Keith's methods were ineffectual, but I had been thinking about different goals - my post explained that. Keith's method is reasonable effective for his goals, though not quite as good as he would like. They would work better when combined with "kill sub-thread" features, but I assume he has good reason for not using such tools. His methods would work reasonably if everyone followed them, but I don't think that is a realistic prospect. This is an open group. Posters and posts that people don't like is the cost of that. If we are able to minimise that cost, either for the group as a whole or for individuals, great. |
David Brown <david.brown@hesbynett.no>: Jun 26 06:26PM +0200 On 25/06/2019 21:53, Scott Lurndal wrote: > In order to make a limit register work, you need a dedicated instruction to adjust > the stack pointer - you can't use the ADD instruction as we do today (unless you > generate code to test against the limit, like Microsoft does). I was suggesting it as a feature in the hardware, in the cpu ISA. Then you could make it a dedicated instruction or a special feature of add instructions targeting the dedicated SP register. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 25 09:58PM -0400 On 6/25/19 4:05 AM, Ralf Goertz wrote: ... > As an aside: What find algorithm does basic_string::find() use? Does it > do something more sophisticated than the naïve way? As it normally is, the standard is silent on the algorithm used, defining only the results. There's many different overloads for find(), and several variant of find, but they are all specified in a fashion similar, in this regard, to the first one: "Effects: Determines the lowest position xpos, if possible, such that both of the following conditions obtain: — pos <= xpos and xpos + str.size() <= size(); — traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str." (21.4.7.2p1). The algorithm used is chosen by the implementor, and therefore depends upon which implementation you are using. |
Ralf Goertz <me@myprovider.invalid>: Jun 26 10:41AM +0200 Am Tue, 25 Jun 2019 17:39:58 +0200 > cout << tester << endl; > } > However, since it's UB it's not /guaranteed/ to produce garbage. Okay, but shouldn't the compiler warn about that? I mean it's fairly obvious (at least after having read how string_view is constructed). > https://en.cppreference.com/w/cpp/algorithm/search>. But this > newfangled stuff isn't necessarily available with any particular > compiler yet. Thanks, I changed to std::boyer_moore_searcher. That indeed sped up the program considerably (after interchanging corpus and pattern). Now I could also use vector<char> instead of string which also had a very noticable effect. Together, the "9 9" case is 1 second compared to the 2.5 seconds before. |
Juha Nieminen <nospam@thanks.invalid>: Jun 26 12:11PM > string const tester=permuter+permuter.substr(0,permuter.size()-1); //* If you are aiming for the utmost extreme speed and optimization, lines like this should *immediately* ring alarm bells in your head. std::string uses dynamic memory allocation, and lines like that are doing them in droves. This is especially problematic when you are just dealing with byte arrays of fixed sizes (with the size being determined before the algorithm even begins), which usually means you can get away with just one or a handful of allocations, and no dynamic allocations of any kind during the execution of the algorithm (other than, possibly, adding the result to some dynamic data container, which usually isn't a problem). Dynamic memory allocation is notoriously inefficient for many reasons, and using pre-allocated non-size-changing buffers over and over is often the best approach. Doing dynamic allocations in the inner loops of your computationally heavy algorithms is going to kill the efficiency. (There are situations where it simply can't be avoided, but if you can avoid it, you should.) |
Ralf Goertz <me@myprovider.invalid>: Jun 26 02:42PM +0200 Am Wed, 26 Jun 2019 12:11:57 -0000 (UTC) > of your computationally heavy algorithms is going to kill the > efficiency. (There are situations where it simply can't be avoided, > but if you can avoid it, you should.) That's what I did now. (See also my answer to Alf.) The relevant changes are the following: size_t const size=permuter.size(); vector<char> tester(size*2-2); do { bool found(false); boyer_moore_searcher b(permuter.begin(),permuter.end()); for (int i=0;i<result.size();++i) { copy(result[i].begin()+1,result[i].end(), tester.begin()); copy(result[i].begin() ,result[i].end()-1,tester.begin()+size-1); if (b(tester.begin(),tester.end()).first!=tester.end()) { found=true; break; } } if (!found) { result.push_back(permuter); if (result.size()==bin) { cout<<bin<<endl; bin<<=1; } } } while (next_permutation(permuter.begin()+1,permuter.end())); |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Jun 25 11:15PM -0700 > also others might learn something or at least be guided to think > about something if you explain the practical utility of the > distinction. Ah, this is a good comment. I should explain the difference between the two categories of errors. I hadn't thought of it in just those terms before. To identify the two categories let's use the terms "program error" and "execution error". A "program error" is one that depends only on the state of the abstract machine, and includes things like dereferencing a null pointer and other similar items like those listed in Annex J.2 of the C standard. (The C++ standard doesn't have a list like J.2 in the C standard AFAICT.) The term "program error" corresponds to what I believe is meant by the term "undefined behavior" in the C and C++ standards, if we gloss over the cases of compile-time error that don't ever get to the abstract machine (for example, a source file not ending in a newline). An "execution error" is one that depends in some way on the state of the actual machine during execution (perhaps in addition to depending on the state of the abstract machine, but the key element is some dependence on the state of the actual machine). "Execution errors" include things like stack overflow, running out of swap space, or a failing logic path in the CPU. In all cases of "execution error" there is (by definition) some aspect that is not addressed by the language definition. I don't mean not /defined/ by the standard, but not referred to at all in any normative text. For example, many computer systems have ECC memory chips, but the standards don't consider such things at all. An uncorrected two-bit memory error is an "execution error", because it depends on stuff outside what the language definition talks about. Probably the most important difference between "program errors" and "execution errors" is this: for "program errors", we know what they depend on and in all cases can revise the program source to avoid any actual or potential "program errors". For example, before dereferencing a pointer value the program could check to see if the value is a null pointer (and not do the dereference, obviously). In contrast, for "execution errors" we may not know what they depend on, and worse, /whatever/ they depend on is outside what the C or C++ standards address; hence there is no guarantee about whether or what program change might fix it, or for which systems the fix would apply. In this sense we could say that "execution errors" are _worse_ than undefined behavior, because unlike "program errors" there are no guarantees (and certainly no portable guarantees) about what program changes will alleviate the problem. > mostly at run time and sometimes detectable in at least global > view of things at build time, one wouldn't be able to draw the > same conclusion? Almost any program that runs reliably might be a good example here. To give a concrete example, consider the following trivial program: int main( int argc, char *argv[] ){ char a[4096] = { 0 }; return a[ 4000 ]; } Assuming I haven't made any stupid mistakes, the program has no "program errors". It has well-defined behavior and is portable to all conforming hosted C implementations (and probably C++ also but I'm not as familiar with the C++ standard as I am with the C standard). But these statements don't apply to "execution errors". If run, for example, after setting the stack space limit to 1K, it might fail. If we run the program today on an unloaded system and tomorrow on a very heavily loaded system it might work today and not work tomorrow. Or it might work on system X but not work on system Y, even if they have exactly the same hardware but perhaps different versions of the OS (ubuntu 16 and ubuntu 18, let's say). The problem is we don't know, and nothing in the language standards will help us, because (by definition) "execution errors" are things that depend on aspects outside of what the C and C++ standards address. Does this help clarify what I'm trying to get at? |
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