The following program should print a line like token1=(nil) save_ptr=0xbfd44dbb and execute successfully, but when it is compiled with "gcc -O2" it will print token1=(nil) save_ptr=0xc0ffee and segfault in the second call to strtok_r. The reason is that the optimized version of strtok_r in string/bits/string2.h, __strtok_r_1c, does not always set its *__nextp argument: if the remainder of the string is empty or consists only of delimiters, then it returns without setting it. This behavior does not show up when compiling without optimization, as the optimized version of strtok_r is not used in that case. This is with glibc 2.7-3 and GCC 4.1.3 on a Debian GNU/Linux i386 (unstable) platform. I believe that this behavior is contrary to SUSv3, which states: "In the first call to strtok_r(), s points to a null-terminated string, sep to a null-terminated string of separator characters, and the value pointed to by lasts is ignored. The strtok_r() function shall return a pointer to the first character of the first token, write a null character into s immediately following the returned token, and update the pointer to which lasts points." #include <stdio.h> #include <string.h> int main (void) { char string[] = ":::"; char *save_ptr = (char *) 0xc0ffee; char *token1, *token2; token1 = strtok_r (string, ":", &save_ptr); printf("token1=%p save_ptr=%p\n", token1, save_ptr); token2 = strtok_r (NULL, ":", &save_ptr); return 0; }
Fixed in cvs.