The following code runs well under gcc 11.2.1:
// test.c
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv){
char *msg;
unsigned int val;
msg = "1024 2048 4096 13";
while(*msg != '\0'){
val = strtoul(msg, &msg, 10);
printf("%u\n",val);
}
return 0;
}
gcc -Wall -o test.bin test.c
$ ./test.bin
1024
2048
4096
13
Regarding the function strtoul,
unsigned long int strtoul(const char *str, char **endptr, int base)
(See notes on Update below.)
Is it correct to pass references to the same object in str and endptr? Or is it just a lucky coincidence that it did not explode in my face?
The reference manuals to stdlib do not mention that (for example).
Update:
- In the comments and answer it is referenced the C standard. Here a link to its draft: ISO N2310.
- In this document, the first argument of the
strtoulfunction is callednptras opposed tostrwhich is the name used in this question. The answer and discussion below mostly usesnptr. - Section 6.7.3.1 contains the formal definition of the type qualifier
restrict. - Section 7.22.1.3 contains the description of
strtoul()
Other than the
restrictqualifiers, neither the documentation forstrtoul, in C 2018 7.22.1.4, nor the documentation for using the standard library generally, in 7.1.4, state any prohibition on*endptrpointing to the same memory thatnptrdoes (whereendptrandnptrare the second and first arguments ofstrtoul, respectively), nor do they state any relaxation of the specification under this condition (for example, there is no assertion that the behavior would be undefined if such a condition holds).So we just need to consider the
restrictqualifiers.strtoulis declared asunsigned long int strtoul(const char * restrict nptr, char ** restrict endptr, int base). Using the formal definition ofrestrictin 6.7.3.1 and considering therestrictonnptrfirst, 6.7.3.1 4 tells us that, if the memory pointed to bynptror any is modified by any means, then every other lvalue used to access it shall be based onnptr. This condition is satisfied becausestrtoulwill not modify the string thatnptrpoints to.Considering the
restrictonendptr, we observe the memory it points to is indeed modified, asstrtoulstores a value to that memory. Then 6.7.3.1 4 requires that every other lvalue used to access that memory shall be based onendptr. This condition is satisfied becausestrtouldoes not access the bytes representingmsgother than throughendptr.Therefore, the routine should function as specified in 7.22.1.4 even if it is called with
strtoul(msg, &msg, 10).