Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: A final word on casting. Date: Mon, 24 Dec 2018 14:52:31 -0800 Organization: None to speak of Lines: 84 Message-ID: References: <41c52811-03f6-4546-a2d4-fe85d9d27411@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader01.eternal-september.org; posting-host="c5d6bb295247060aff140a96636e3e46"; logging-data="326"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19ZDodW9fdWhjFMWcfuehjQ" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:tytNX57py6F/aLt/u9ad/Qwz7FE= sha1:j1Y6o+8TxQEpw3jzWA+R67QF0ns= Xref: csiph.com comp.lang.c:139035 chanrasjid@gmail.com writes: > I think I have got the final word on casting: > "It is the set of rules to convert from one data type to another." > I think it is what Ben and others have said. It is as simple as that - > hope I am right this time. No, that's not what "casting" means. The term "cast" is often *incorrectly* used to refer to type conversion in general. "Conversion" means taking a value of some type and obtaining from it a value of a (probably different) type. A conversion can be an implicit conversion (for example, in a simple assignment) or an explicit conversion. An explicit conversion is specified by a *cast*, an expression consisting of a type name in parentheses followed by an expression. (The parenthesized type name is a cast operator). The word "cast" refers *only* to that particular kind of expression. A cast specifies exactly the same operation that would have been performed if the same conversion had been done implicitly (*if* it's a conversion that can be done implicitly; most pointer conversions require casts). (Strictly speaking, a unary-expression with no cast operator is also a cast-expression, but that's only for syntactic convenience, consistent with the way other kinds of expressions are defined in the grammar.) > Just to satisfy myself, I google for "C casting" and read what some > articles teach about C casting. Basically, it is what I seem to > already know. I suspect a lot of those articles repeat the same misconception, that an implicit conversion is a "cast". It isn't. > The only thing that troubled me in the past was the casting of signed > int to unsigned : > while (number < 0) { > number += MAX_UNSIGNED_INT + 1 > } That's a conversion, not a cast (and the macro is UINT_MAX). > It was explained that the cast here does not change the bit patterns; > both values have the same bits, but values will be different as they > depend on interpretation of the bits. I was thinking along why would > anyone entertain having one of its computed -ve value assigned to an > unsigned int. No one starts off with : unsigned int x = -123, y = > -23,... rarely. So what is the purpose of casting. A conversion from a signed integer type to an unsigned integer type of the same size *typically* doesn't change the bit pattern, but that's not how it's defined (though the way it's defined is certainly motivated by that). On a system that uses ones'-complement or sign-and-magnitude, rather than the vastly more common two's-complement, the conversion of a negative integer to an unsigned type does change the bit pattern. > As C allows for assignment of one type to a variable of a different > type, a set of casting rules is needed. > So this is C type casting. No, this is C conversion. Converting any integer to an unsigned type is well defined -- mostly because the result can be specified in a way that's easy to implement. The standard's description of "repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type" is not how it's actually implemented; it's a way of expression, while referring only to *values*, something that's actuallly done by simple a manipulation of the *representation*. The bits of the source value are simply copied, or the high-order bits are discarded, or zero bits are added at the top, depending on the relative sizes (*if* the system uses two's-complement). Converting any integer to a signed type is defined more loosely. If the converted value is outside the range of the target type, the result is implementation-defined. -- Keith Thompson (The_Other_Keith) kst@mib.org Will write code for food. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"