Path: csiph.com!news.mixmin.net!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c Subject: Re: string to size_t Date: Mon, 19 Dec 2022 11:20:07 -0800 Organization: A noiseless patient Spider Lines: 55 Message-ID: <867cyn19qw.fsf@linuxsc.com> References: <87r0wvs291.fsf@nosuchdomain.example.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader01.eternal-september.org; posting-host="ff406b04d09b824d6c1109f51ef0323b"; logging-data="444493"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+RmEyWg5Q9ZoxtoilntprZl+m6lGV7ftk=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:82WtXLiQPaqH3DMmV720pdMD4p4= sha1:lEp4VVJLPolcbhJCAVKHvGAWCLc= Xref: csiph.com comp.lang.c:168597 Keith Thompson writes: > O?uz writes: > >> I wrote the function below for converting a string to size_t without >> manually calculating its value digit by digit. It first converts the >> string to intmax_t, and if the conversion fails due to a range error >> and SIZE_MAX doesn't fit into an intmax_t, it tries again with >> uintmax_t. In both cases, if the result is less than zero it >> fails. And on success it populates *result with the result. >> >> It works on my machine and a couple others I tried, but I'm not sure >> if it's good C, or a good idea at all. What do you think about it? >> >> int >> strtosize(const char *nptr, char **endptr, int base, size_t *result) { >> intmax_t s; >> uintmax_t u; >> >> errno = 0; >> s = strtoimax(nptr, endptr, base); >> >> if (errno == 0 && s >= 0 && s <= SIZE_MAX) { >> *result = s; >> return 1; >> } >> >> #if SIZE_MAX > INTMAX_MAX >> if (errno == ERANGE && s == INTMAX_MAX) { >> errno = 0; >> u = strtoumax(nptr, endptr, base); >> >> if (errno == 0 && u <= SIZE_MAX) { >> *result = u; >> return 1; >> } >> } >> #endif >> >> if (errno == 0) >> errno = ERANGE; >> >> return 0; >> } > > What is the point of trying strotoimax before using strotoumax? > Just call strtotumax and convert the result to size_t. > > The checks are probably unnecessary. As of the current C standard, > SIZE_MAX cannot be bigger than UINT_MAX. (C23 will allow for > the possibility that SIZE_MAX > UINT_MAX, but implementations are > unlikely to take advantage of that -- which means your checking > code will at best be difficult to test.) I think you mean UINTMAX_MAX rather than UINT_MAX.