Tuesday, December 23, 2014

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

Ian Collins <ian-news@hotmail.com>: Dec 24 11:49AM +1300

Mr Flibble wrote:
>> blocking and cancellation points.
 
> My platforms include Windows and POSIX. For I/O I use boost.asio which
> is non-blocking.
 
Isn't boost.asio normally used as an alternative to threads+blocking I?O?
 
> For "system()" I don't invoke processes that block for
> any significant amount of time. If none of your threads block for more
> than, say, a second then thread cancellation remains trivial.
 
Sometimes one doesn't have a choice!
 
> The key to writing non-blocking code is getting your head around the
> concept of splitting up work into manageable chunks.
 
That's fine for your own code, but when using third party or system
interfaces, you don't have a choice.
 
--
Ian Collins
mathewji <itoneymathew@gmail.com>: Dec 22 04:52PM -0800

working on question - "Find a pair of values so that the pre-condition of this version of area holds, but the post-condition doesn't."
 
Code:
 
int area(int length, int width)
{
// calculate area of a rectangle;
// pre-conditions: length and width are positive
// post-condition: returns a positive value that is the area
{
if (length <= 0 || width <= 0)
error("area() pre-condition");
int a = length*width;
if (a <= 0)
error("area() post-condition");
return a;
}
}
Richard Damon <Richard@Damon-Family.org>: Dec 22 09:12PM -0500

On 12/22/14 7:52 PM, mathewji wrote:
> return a;
> }
> }
 
Hint, by "ideal" math, this can't happen (the product of two positive
numbers is always positive), so what has probably happened?
 
Note that the answer will be implementation dependent (and depend on
behavior not promised by the standard), but some can be specified using
information provided by the standard.
mathewji <itoneymathew@gmail.com>: Dec 22 06:15PM -0800

Richard, have a less cryptic answer? :-)
Richard Damon <Richard@Damon-Family.org>: Dec 22 11:47PM -0500

On 12/22/14 9:15 PM, mathewji wrote:
> Richard, have a less cryptic answer? :-)
 
As I said, the mathematically defined behavior of multiplying two
positive numbers is always another positive number. The C standard
provides conditions when the program doesn't need to follow that defined
behavior. There are limits in mathematics is C.
 
The fact that your exercise is asking you this, you must have studied it
already.
 
Once you figure the basic conditions that allow this, figuring out a
particular case will be much simpler.
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Dec 22 11:27PM -0700

On Mon, 22 Dec 2014 16:52:36 -0800 (PST), mathewji
> return a;
> }
>}
 
Hint: What numbers can be represented by a variable declared "int"?
 
Louis
mathewji <itoneymathew@gmail.com>: Dec 23 04:23AM -0800

I do understand that the product of two positive ints (pre-condition) will never be a negative number. So the post-condition of this code could never happen? But the question kind of implies that two unknowns could result in getting past pre to post.
David Brown <david.brown@hesbynett.no>: Dec 23 01:59PM +0100

On 23/12/14 13:23, mathewji wrote:
> I do understand that the product of two positive ints (pre-condition)
> will never be a negative number. So the post-condition of this code
> could never happen?
 
That is true in ordinary maths - but maths in C++ (and most programming
languages) does not entirely follow the rules of "real" mathematics. An
"int" in C++ has a specific size or range. Think about what that range
is, and what happens as your input values get closer to the limits.
 
(As others have done, I am trying to give you hints rather than a
finished answer.)
 
Richard Damon <Richard@Damon-Family.org>: Dec 23 08:51AM -0500

On 12/23/14 7:23 AM, mathewji wrote:
> will never be a negative number. So the post-condition of this code
> could never happen? But the question kind of implies that two
> unknowns could result in getting past pre to post.
 
The product of two mathematical positive integers is always positive.
C++ does not promise the same for "int".
 
See <climits>/<limits.h>
mathewji <itoneymathew@gmail.com>: Dec 23 06:46AM -0800

I was able to locate:
 
/*
* Maximum and minimum values for ints.
*/
#define INT_MAX 2147483647
#define INT_MIN (-INT_MAX-1)
 
Inside of limits.h
isonil11@gmail.com: Dec 23 07:08AM -0800

W dniu wtorek, 23 grudnia 2014 01:52:53 UTC+1 użytkownik mathewji napisał:
> return a;
> }
> }
 
In C++ it is impossible to find such values. Signed integer overflow is undefined behavior:
 
Paragraph 5/4 of the C++11 Standard
"If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined."
 
Integer overflow does not guarantee that the result will be negative, so there is no defined case where post-condition doesn't hold. (The only case is where undefined behavior occurs, but it's undefined - so basically anything can happen).
mathewji <itoneymathew@gmail.com>: Dec 23 07:21AM -0800

Got past pre to post with, 2147483647 and 2. Thx!
scott@slp53.sl.home (Scott Lurndal): Dec 23 05:08PM


> postcondition: average( j, k ) is the smallest (nearest to
> minus infinity) of all the long long values that are closest
> to the mathematical value of (j+k)/2.
 
return (j>>1)+(k>>1);
Victor Bazarov <v.bazarov@comcast.invalid>: Dec 23 12:57PM -0500

On 12/23/2014 12:40 PM, Stefan Ram wrote:
 
> int main( void ){ printf( "%lld\n", average( 3, 3 )); }
 
> prints:
 
> 2
 
What if we do something like
 
{ return (j>>1)+(k>>1)+(((j&1)+(k&1))>>1); }
 
?
 
V
--
I do not respond to top-posted replies, please don't ask
Paavo Helde <myfirstname@osa.pri.ee>: Dec 23 12:16PM -0600

ram@zedat.fu-berlin.de (Stefan Ram) wrote in
 
> I don't know whether there is a portable guarantee that all
> long long values can be represented in a long double, but I
> doubt that there is such a guarantee.
 
The guarantees given by the C standard are all for *minimum* required
values, so there is even no guarantee that all possible values of char can
be represented by distinct values in a long double, not to speak about long
long, on any given platform. This would be impossible for example if char
and long double are both 64-bit.
 
OTOH, I think all *guaranteed* values of (signed and insigned) char, short,
int and long are guaranteed as to be represented by distinct values in
double and long double - the guarantee for ULONG_MAX is 4294967295 which
has 10 decimal digits, and DBL_DIG and LDBL_DIG are guaranteed to be at
least 10 (are these the correct macros to use?)
 
The guarantee for long long is much larger (2^64-1) which clearly does not
fit into 10 digits.
 
Cheers
Paavo
ram@zedat.fu-berlin.de (Stefan Ram): Dec 23 04:17PM

>Got past pre to post with, 2147483647 and 2. Thx!
 
Good. Now write (this addresses all readers of this post,
not just mathewji) a function
 
long long average( long long j, long long k );
 
precondition: LLONG_MIN <= j, k <= LLONG_MAX
 
postcondition: average( j, k ) is the smallest (nearest to
minus infinity) of all the long long values that are closest
to the mathematical value of (j+k)/2.
 
The function should be coded in such a way that the
postcondition is true under every C implementation.
 
For example:
 
average( LLONG_MAX, LLONG_MAX ) == LLONG_MAX
average( LLONG_MAX - 1, LLONG_MAX - 1 ) == LLONG_MAX - 1
average( LLONG_MIN, LLONG_MIN ) == LLONG_MIN
average( LLONG_MIN, LLONG_MAX ) == should usually be a value near 0
average( LLONG_MAX, LLONG_MIN ) == should usually be a value near 0
average( j, j ) = j
average( 2, 3 ) = 2
average( -2, -3 ) = -3
average( 2, 4 ) = 3
average( -2, -4 ) = -3
 
(The implementation written can choose another means to choose a
value: For example, instead of »smallest« above, also the
»largest« value might be chosen, so that average( 2, 3 ) is 3.
This choice has to be documented.)
 
~~~~~~~~~~~~~~
 
Extra points are given when floating-point types are not used
in the implementation. The following program prints »0« here:
 
#include <stdio.h>
#include <limits.h>
int main( void )
{ printf( "%g\n", ( double )LLONG_MAX - ( double )( LLONG_MAX - 5 )); }
 
which shows that double can't represent all the long long
values anyways. And this
 
#include <stdio.h>
#include <limits.h>
int main( void )
{ printf( "%Lg\n", ( long double )LLONG_MAX - ( long double )( LLONG_MAX - 5 )); }
 
prints »1.13305e-317« here. But it is possible that my C
implementation is buggy with regard to some floating point
calculations as I observed before. I just tested it with
another compiler, and it printed »0« for the first program
and »5« for the second.
 
I don't know whether there is a portable guarantee that all
long long values can be represented in a long double, but I
doubt that there is such a guarantee.
ram@zedat.fu-berlin.de (Stefan Ram): Dec 23 05:26PM

>ram@zedat.fu-berlin.de (Stefan Ram) writes:
>>long long average( long long j, long long k );
>return (j>>1)+(k>>1);
 
That's quite good, but possibly it does not always
give the expected result:
 
#include <stdio.h>
#include <limits.h>
 
long long average( long long const j, long long const k )
{ return (j>>1)+(k>>1); }
 
int main( void )
{ printf( "%lld\n", LLONG_MAX );
printf( "%lld\n", average( LLONG_MAX, LLONG_MAX )); }
 
9223372036854775807
9223372036854775806
ram@zedat.fu-berlin.de (Stefan Ram): Dec 23 05:40PM

>>return (j>>1)+(k>>1);
>That's quite good, but possibly it does not always
>give the expected result:
 
Or, even simpler:
 
#include <stdio.h>
 
long long average( long long const j, long long const k )
{ return (j>>1)+(k>>1); }
 
int main( void ){ printf( "%lld\n", average( 3, 3 )); }
 
prints:
 
2
"Tobias Müller" <troplin@bluewin.ch>: Dec 23 06:36AM


> Debugging can be done with a public variable as well, just set up a data
> breakpoint on the needed memory address, with a suitable condition.
 
Data breakpoints are not nearly as convenient as 'normal' breakpoints IME.
Often they are valid only in a single run, especially if ASLR is turned on
(now standard on Windows).
Also data breakpoints are only valid for a _single_ instance of the class.
While code breakpoints break for _every_ instance.
 
Tobi
Paavo Helde <myfirstname@osa.pri.ee>: Dec 23 01:46AM -0600

=?UTF-8?Q?Tobias=20M=C3=BCller?= <troplin@bluewin.ch> wrote in
news:1569487410440962347.836952troplin-bluewin.ch@news.eternal-september.
org:
 
>> condition.
 
> Data breakpoints are not nearly as convenient as 'normal' breakpoints
> IME.
 
That's true, but this is more of a tool problem.
 
> Often they are valid only in a single run, especially if ASLR is
> turned on (now standard on Windows).
 
... or if multiple threads and dynamic allocation are in play.
 
> Also data breakpoints are only valid for a _single_ instance of the
> class. While code breakpoints break for _every_ instance.
 
Often, a specific instance is what I want. Also, tracking every instance
would be in principle also possible for a tool, it amounts to adding a
special breakpoint in each constructor of the class which adds a new data
breakpoint in the constructed object. One potential problem with this
approach is that IIRC the number of hardware data breakpoints is very
limited and emulating them via protected virtual memory pages may turn
the program rather slow.
 
On the other hand, data breakpoints can be really helpful in tracking
down some obscure errors, like the initialization function of PHP DLL
writing over some bytes in some static data array in another totally
unrelated library.
 
Cheers
Paavo
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: