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.