This is the mail archive of the
mailing list for the pthreas-win32 project.
Re: pthread.h is breaking programs that use strtok_r and rand_r
- From: "John E. Bossom" <drifting at pioneerwireless dot ca>
- To: pthreads-win32 at sourceware dot org
- Date: Sat, 26 Feb 2011 21:56:51 -0500
- Subject: Re: pthread.h is breaking programs that use strtok_r and rand_r
- References: <83CE6FF8F6C9B2468A618FC2C512672605A0446E29@USMBX1.msg.corp.akamai.com> <4D69A52B.email@example.com>
Quoting Ross Johnson <Ross.Johnson@homemail.com.au>:
They may have been much more useful back in 1996 however I've removed
them from the current CVS trunk.
rand_r was used in two tests.
On 29/12/2010 5:33 AM, Lubashev, Igor wrote:
First of all, thanks for a great project!
I do have some issues to report, though.
Header pthread.h is expected to be included by client code, but it
is breaking client code that uses strtok_r and rand_r. Yes, these
macros are not defined on Windows, but people trying to write
portable code will likely provide their definitions for these POSIX
functions. Unfortunately, if pthread.h is included after the
headers providing these definitions, pthread.h will break client
code. The definitions for these macros in pthread.h are not
1. pthread.h's definition for strtok_r:
#define strtok_r( _s, _sep, _lasts ) ( *(_lasts) = strtok(
(_s), (_sep) ) )
It completely ignores _lasts field, which is not standard
compliant. Standard requires: "Different strings may be parsed
concurrently using sequences of calls to strtok_r() that specify
different saveptr arguments."
--- Test program on Windows:
#define strtok_r strtok_s
/* #include<pthread.h> */
char str1 = "A day";
char str2 = "A night";
char *save1, *save2;
strtok_r(str1, " ",&save1);
strtok_r(str2, " ",&save2);
printf("%s and %s\n", strtok_r(NULL, " ",&save1), strtok_r(NULL,
The result is expected: "day and night"
However, if I uncomment #include<pthread.h>, the result is: "(null)
Windows already has a compatible function called strtok_s.
#define strtok_r strtok_s
2. pthread.h's definition for rand_r:
#define rand_r( _seed ) ( _seed == _seed ? rand() : rand() )
It completely ignores the _seed. The standard requires rand_r to
use its seed as its state. User code can rely on a deterministic
initial seed to receive a deterministic sequence of pseudo-random
numbers. This is very useful in debugging, for example. Moreover,
rand_r output is not supposed to affect or be affected by calls to
rand or rand_r with a different seed address.
In general, it is a very bad form for pthread.h to define and drop
into client's global scope macros that are not related to pthreads
and are likely to collide on names with client's own macros or
I hope the next release of pthread-win32 will address these issues.
- Igor Lubashev