Path: csiph.com!weretis.net!feeder8.news.weretis.net!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: How to add ssize_t a by size_t b? Date: Fri, 01 Oct 2021 14:13:46 -0700 Organization: None to speak of Lines: 44 Message-ID: <87y27ch2id.fsf@nosuchdomain.example.com> References: Mime-Version: 1.0 Content-Type: text/plain Injection-Info: reader02.eternal-september.org; posting-host="13acd1fe4bff95bcb7ffb2395063c869"; logging-data="20569"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/dhVN7+lbTsrveUM8TuRXk" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) Cancel-Lock: sha1:e6++PLgEDgNsURcCxEXXLK4V7B0= sha1:kzzuRW4RneywgcxUeKI4hb5tvf0= Xref: csiph.com comp.lang.c:162919 wij writes: > To simply the question of "a+b": > > ssize_t add(ssize_t a, size_t b) { > if(a+b would overflow) { set errno=ERANGE; } > a+=b; // ? > return a; > } > > Another example: > ssize_t a=SSIZE_T_MIN; > size_t b=SIZE_T_MAX; > a+=b; // Is this OK? Or, How the addition is done correctly? In standard C, you don't, because ssize_t doesn't exist (unless you define it yourself). However, POSIX does define a type ssize_t, which is a signed integer type that can represent values up to SSIZE_MAX. The rules are given in N1570 6.3.1.8, "Usual arithmetic conversions". It's likely, but not guaranteed, that size_t and ssize_t have the same rank. If so, then the ssize_t value is converted to size_t, and assuming SSIZE_MAX <= SIZE_MAX the conversion does not change the value. The addition is then done with two size_t (unsigned) operands, with the usual wraparound semantics if the result exceeds SIZE_MAX. It's very likely that ssize_t is the signed type that corresponds to the unsigned type size_t; for example, if size_t is unsigned long, then ssize_t is probably long. But I don't think POSIX actually guarantees that. (Which means, for example, that a "%zd" format specifier isn't guaranteed to be correct for value of type ssize_t.) This assumes that size_t and ssize_t have a rank greater than or equal to that of int, which is not guaranteed but is almost certain. If not then both operands are promoted via the "integer promotions" before the "usual arithmetic conversions" are applied. (This is relevant if, for example, you want to add operands of types short and unsigned short.) -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips void Void(void) { Void(); } /* The recursive call of the void */