Saturday, March 12, 2016

Digest for comp.lang.c++@googlegroups.com - 14 updates in 4 topics

"Öö 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: