Path: csiph.com!news.mixmin.net!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: string to size_t Date: Mon, 19 Dec 2022 09:59:54 -0800 Organization: None to speak of Lines: 55 Message-ID: <87r0wvs291.fsf@nosuchdomain.example.com> References: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: reader01.eternal-september.org; posting-host="8e7fdbea1bc660c36eba0e0212d247ec"; logging-data="437877"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+Mu8rfIk3uilsWn/GZomnn" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) Cancel-Lock: sha1:CpcJrTEhxbtWL066lFIYi7bLO1U= sha1:UoUUHK+S+jp3hX5uEKoW7G9lsGQ= Xref: csiph.com comp.lang.c:168593 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.) -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for XCOM Labs void Void(void) { Void(); } /* The recursive call of the void */