- Unsigned fixed point multiply refresher - 3 Updates
- C++ exceptions are broken. - 4 Updates
- Most efficient way to insert an item into sorted stl list container ??? - 5 Updates
- Use of decltype - 2 Updates
"Öö Tiib" <ootiib@hot.ee>: Mar 11 03:47PM -0800 On Friday, 11 March 2016 10:25:26 UTC+2, David Brown wrote: > not), but you should try to avoid the risk - weird things can happen if > the compiler uses inlining and constant propagation to pre-calculate > results. C does use two's complement. Section 7.18.1.1 paragraph 1 of the C99 standard: The typedef name intN_t designates a signed integer type with width N, no padding bits, and a two's complement representation. So if 'int32_t' compiles then it must be two's complement in conforming implementation. |
David Brown <david.brown@hesbynett.no>: Mar 13 12:06AM +0100 On 12/03/16 00:47, 嘱 Tiib wrote: > N, no padding bits, and a two's complement representation. > So if 'int32_t' compiles then it must be two's complement in conforming > implementation. C (and C++) can use several signed integer formats - the details are implementation defined. But you are right that the intN_t types must use two's complement. However, C (and C++) explicitly makes signed arithmetical overflow undefined behaviour, even when you are using types that must be two's complement. I was not very accurate in my wording, but the point is that you should always avoid any possible signed integer overflow to avoid undefined behaviour, even though the instructions used by the compiler will likely be two's complement arithmetic instructions that will probably give you the answer you expect. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 13 12:38AM +0100 On 13.03.2016 00:06, David Brown wrote: > implementation defined. But you are right that the intN_t types must > use two's complement. However, C (and C++) explicitly makes signed > arithmetical overflow undefined behaviour, Not quite. C++ only makes overflow UB for types where "the result is not mathematically defined or not in the range of representable values for its type". This does not apply to unsigned types because there the result is always in range. And more generally it does not apply to an integer type T where numeric_limits<T>::is_modulo is true. With Visual C++ (Windows) all integer types, signed and unsigned, have is_modulo true. With MinGW g++ 5.1.0 (a version of g++ for Windows), all signed integer types have is_modulo false even with use of the flag `-fwrapv`, or at least my hasty but not entirely complete testing right now says so. That said, due to an ill-conceived way of specifying optimizations, by changing the semantics of floating point types via compilation options instead of having different but layout-compatible types, the g++ standard library does in general not report the properties of floating point types correctly. This means that with g++ std::numeric_limits cannot be trusted in general, only in special cases. And I do not know how to detect the presence of g++'s `-fwrapv` or `-ftrapv` semantics in some more reliable compiler-specific way. :( > integer overflow to avoid undefined behaviour, even though the > instructions used by the compiler will likely be two's complement > arithmetic instructions that will probably give you the answer you expect. I agree, when the code must be portable between compilers. Cheers!, - Alf |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 12 07:11PM On 09/03/2016 14:25, James K. Lowden wrote: > find any mention of "downgrading". I also don't understand how it > *could* happen, since the compiler generates exception-handling > instructions, and the language per se doesn't define logic_error. Typically when constructing an exception derived from std::logic_error a std::string object is created for the exception message which can cause std::bad_alloc (a std::runtime_error exception) to be thrown replacing the originally intended exception. > intended -- a logic error could have been avoided by the programmer, > whereas a runtime error could not. Depending on the situation, though, > either one can leave the user high and dry. In general std::logic_error is more serious then std::runtime_error because you can often recover from a std::runtime_error but a std::logic_error exception is often a sign that something is seriously screwed and the only safe course of action is to terminate the process. I treat std::logic_error based exceptions as fatal conditions because of this. /Flibble |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 12 02:46PM -0600 On 09/03/2016 14:25, James K. Lowden wrote: > find any mention of "downgrading". I also don't understand how it > *could* happen, since the compiler generates exception-handling > instructions, and the language per se doesn't define logic_error. Typically when constructing an exception derived from std::logic_error a std::string object is created for the exception message which can cause std::bad_alloc (a std::runtime_error exception) to be thrown replacing the originally intended exception. > by the library. I guess you mean that -- assuming they're used as > intended -- a logic error could have been avoided by the programmer, > whereas a runtime error could not. Depending on the situation, though, > either one can leave the user high and dry. In general std::logic_error is more serious then std::runtime_error because you can often recover from a std::runtime_error but a std::logic_error exception is often a sign that something is seriously screwed and the only safe course of action is to terminate the process. I treat std::logic_error based exceptions as fatal conditions because of this. /Flibble -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
Hergen Lehmann <hlehmann.expires.5-11@snafu.de>: Mar 12 04:50PM -0600 Am 12.03.2016 um 21:46 schrieb Mr Flibble: > because you can often recover from a std::runtime_error but a > std::logic_error exception is often a sign that something is seriously > screwed and the only safe course of action is to terminate the process. I don't see any basis for that assumption. std::logic_error includes stuff like std::domain_error (which is not even used by the STL) or std::invalid_argument, which might be some completely harmless rejection of input data. On the other hand, std::runtime_error includes std::system_error, which might be quite hazardous depending on which system operation did fail. Hergen -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
"Öö Tiib" <ootiib@hot.ee>: Mar 12 03:05PM -0800 On Saturday, 12 March 2016 21:12:00 UTC+2, Mr Flibble wrote: Leigh, can you please check why your posts appear twice in comp.lang.c++? > std::string object is created for the exception message which can cause > std::bad_alloc (a std::runtime_error exception) to be thrown replacing > the originally intended exception. That is indeed so, but 'bad_alloc' is also typically unrecoverable fatal and on border of 'logic_error'. It can be that platform was picked that is incapable of handling the task under hand or input was accepted that is outside of capabilities of platform or software is leaking resources so it will run out sooner or later. The reason why it is 'runtime_error' is perhaps because the system might be ran out of resources because of some other software did exhaust the available memory. Also that situation is not recoverable by software on its own. > screwed and the only safe course of action is to terminate the process. > I treat std::logic_error based exceptions as fatal conditions because > of this. Yes but if you threat 'bad_alloc' as 'logic_error' too then no harm done? |
Bob Langelaan <bobl0456@gmail.com>: Mar 11 08:25PM -0800 Clearly one way to do so is by using the merge member function of the list container class to merge the item into the sorted list. My question is: Is there a more efficient way to do it? Thanks in advance, Bob |
Ian Collins <ian-news@hotmail.com>: Mar 12 05:48PM +1300 On 03/12/16 17:25, Bob Langelaan wrote: > Clearly one way to do so is by using the merge member function of the > list container class to merge the item into the sorted list. My > question is: Is there a more efficient way to do it? The usual way to insert into a set is with set::insert. If you know where or roughly where, use the overloads with a hint parameter. -- Ian Collins |
bartekltg <bartekltg@gmail.com>: Mar 12 07:12AM +0100 On 12.03.2016 05:25, Bob Langelaan wrote: > Clearly one way to do so is by using the merge member function of the > list container class to merge the item into the sorted list. My > question is: Is there a more efficient way to do it? You can find the place for the new item manually and insert it. list<int> bla{23,465,123,76,77}; bla.sort(); int foo = 76; int bar = 100; bla.insert( upper_bound(bla.begin(),bla.end(),foo ),foo ); bla.insert( upper_bound(bla.begin(),bla.end(),bar ),bar ); for (auto it: bla) cout<<it<<endl; Results: 23 76 76 77 100 123 465 It can be a bit faster (not much if your compilator has done good job with merging), but still it is O(n) time! It this operation is a bottleneck, You should consider different container better suited for you needs. Probably std::set, as Ian have said. best Bartek |
Bob Langelaan <bobl0456@gmail.com>: Mar 12 12:35AM -0800 On Friday, March 11, 2016 at 10:13:04 PM UTC-8, bartekltg wrote: > Probably std::set, as Ian have said. > best > Bartek Thanks. That is exactly what I was looking for :) |
"K. Frank" <kfrank29.c@gmail.com>: Mar 12 10:14AM -0800 Hello Bob! On Saturday, March 12, 2016 at 3:35:37 AM UTC-5, Bob Langelaan wrote: > > best > > Bartek > Thanks. That is exactly what I was looking for :) Two comments: First, you may also want to look at std::multiset if there is the possibility that your list may contain duplicates (and you want to preserve that information). Second, you might NOT want a container that has efficient (i.e., log(n)) insertion time if you insert rarely, but read / traverse / look up frequently. If you insert rarely, append / sort (at n log(n)) could be overall more efficient if it lets you use a container that is more efficient for the rest of your use case. (Also, if you insert in bunches, then several appends followed by a sort can win overall.) Best. K. Frank |
Paul <pepstein5@gmail.com>: Mar 12 01:09AM -0800 On Friday, March 11, 2016 at 10:01:17 PM UTC, Alf P. Steinbach wrote: > Disclaimer: I have not checked that. > Also there was something about double parenthesis. > They crammed too much into one thing, old g++ typeof was more practical. Thanks. The actual problem was experienced with a std::vector<std::pair<std::string, int> >; However, I tried to find and post the simplest example of the anomalous (to me) behaviour. I tried to post my question (as opposed to the example) in an abstract way to encompass a variety of types. With the above pair example, + doesn't work because there's no such operator. I like the value_type solution. typedef is fine too, but I have trouble remembering whether it should be typedef int PseudonymForInt; or typedef PseudonymForInt int; (The first is correct, I think. Thanks to all on this thread. Paul |
"Öö Tiib" <ootiib@hot.ee>: Mar 12 04:02AM -0800 On Saturday, 12 March 2016 11:09:32 UTC+2, Paul wrote: > typedef is fine too, but I have trouble remembering whether it should > be typedef int PseudonymForInt; or typedef PseudonymForInt int; > (The first is correct, I think. The 'using' alias syntax is slightly more intuitive than 'typedef'. See: using Name = std::string; using Weight = int; using NameWeight = std::pair<Name, Weight>; using NameWeights = std::vector<NameWeight>; NameWeights x{{"foo",42},{"bar",13}}; std::sort(begin(x), end(x), std::greater<NameWeight>()); Also if those constructs with 'decltype' and 'value_type' (and 'remove_reference' and 'const_reverse_iterator' etc.) turn code lines into too verbose then use local alias: template<typename Container> void reverse_stable_sort(Container& c) { using Element = typename Container::value_type; std::stable_sort(begin(c), end(c), std::greater<Element>()); } |
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