8

The question came up in a discussion at StackOverflow.

Is there a clean distinction between the two concepts cast and convert (concerning the type of an object), or are these two words describing exactly the same? How about languages other than C++, Python and Java? EDIT: What if the types in question are primitive types, like int to float?

krlmlr
  • 783
  • 5
  • 13

3 Answers3

5

Theoretically speaking, the two concepts are vastly different:

Type Casting refers to exchanging one type (roughly speaking, an object structure) for another while Type Conversion refers to translating of values (roughly speaking, contents of the object), so that they may be interpreted as belonging to a new type. Theoretically, they never mix.

That said, practically speaking, while you can have one without another, it's, almost always, a bad idea. It rarely makes sense to change your perception of an objects' structure, without also altering its contents. Practically, they're almost always the same

blueberryfields
  • 13,200
  • 8
  • 51
  • 87
  • 3
    This gets even more fun with a weakly typed language, like C, you can simply refer to a section of memory as a different type! – Sheldon Warkentin Feb 02 '12 at 23:18
  • That's not how the terms "cast" and "conversion" are used in C. See my answer. – Keith Thompson Feb 03 '12 at 00:31
  • I have edited the question. Do you have any thoughts about that? Thanks! – krlmlr Feb 03 '12 at 23:25
  • The answer doesn't change for primitives. – blueberryfields Feb 04 '12 at 16:24
  • "It rarely makes sense to change your perception of an objects' structure, without also altering its contents." isn't this the whole point of subtyping and polymorphism? holding a reference to an `AbstractSprite` while having no idea at all that it's actually a `BigGreenTreeSprite`? – sara Jun 12 '16 at 20:25
  • @kai apples != oranges. subtyping and polymorphism are useful but roughly tangential concepts to type casting and type conversion - not exceptions to the (almost) invariant. you're comparing tools for managing abstraction levels, with data/transformation operations. yes, it's convenient, desirable and practical to have higher and lower abstraction levels and tools to support them; no, it's not advisable in almost all cases to perform the two data transformation operations separately. – blueberryfields Jun 13 '16 at 23:49
3

Different languages define the words "cast" and "convert" differently; I don't think the question is meaningful other than in reference to a particular language.

In C, for example, the term "cast" properly refers only to an explicit cast operator, consisting of a type name in parentheses preceding the expression to be converted. A "conversion" converts a value of one type to a value of another type; some conversions are implemented by re-interpreting the bits that make up the representation, but it's defined as a value-to-value conversion. (Yes, that's true even for pointer conversions; it's possible for different pointer types to have different representations.)

Note that there is no such thing as an "implicit cast" in C.

Some conversions are explicit, specified by a cast operator. Others are implicit, and are applied in certain cases when an expression of one type is used in a context that needs an expression of a different type. The conversion performed is exactly the same in either case.

For example:

double x = 1.23;
int y = (int)x;  /* A cast, or explicit conversion, setting y to 1 */
int z = x;       /* An implicit conversion, setting z to 1. */

C++ is similar; it has the same casts and conversions as C, and it adds a functional notation equivalent to a C-style cast expression, plus 4 more specific keywords: const_cast, dynamic_cast, reinterpret_cast, and static_cast.

Keith Thompson
  • 6,402
  • 2
  • 29
  • 35
  • Am I the only person who dislikes casting as a means of converting floating-point numbers to integer types, or larger integer types to smaller ones? To my mind, casting should be appropriate for situations where a language designer could only choose one plausible behavior, and other means of conversion should be used when different behaviors would make sense in different contexts. For example, one could argue that a language should make `(int)1.5-2*(int)(-1.5)` yield 3, 4, 5, or 6, but if `(int)` had been replaced with `truncInt`, `roundPeriodicInt`, `floorInt`, or `roundEvenInt`,... – supercat Jan 28 '14 at 16:48
  • ...there would be no ambiguity. Likewise, when casting a longer integer type to a shorter one, there are cases where numbers that don't fit the smaller type are expected and should wrap, and there are cases where such numbers are unexpected and should trigger an exception. Different languages have different behaviors with such casts, so it's hardly self-evidence which behavior a cast should have. Unless a language has both wrapping and non-wrapping integer types (a good design concept, IMHO, though I don't know any that do), specifying whether wrapping is expected would seem helpful. – supercat Jan 28 '14 at 17:05
  • @supercat: At least in C, a cast always specifies the same kind of conversion that would be performed implicitly by an assignment to an object of the same type -- *if* it's one of the conversions (mostly ones between arithmetic types) that can be done implicitly. Other kinds of conversions, e.g., specifying the kind of rounding/truncation for floating-point, can be done via function calls. – Keith Thompson Jan 28 '14 at 19:41
  • Certainly functions can be used; my point is that I think functions or members *should* be regarded as *the* proper means of performing conversions whose results might not represent the original values. I know C allows implicit float-to-integer conversions, and compatibility dictates it will probably always have to do so, but that doesn't mean it should. Pascal requires a call to `Round` or `Trunc`--IMHO a much cleaner design. – supercat Jan 28 '14 at 20:46
1

While casting, you read the instance of one class as if it is the instance of another class. It could be appliccable for this pair of classes or not. No runtime work except checking. Often the possible incompatibility could be caught on compiling stage.

While converting, you recombine or recount fields of an instance of one class into an instance of another class. If there is a function for it, it could be applicable or not for this very instance. All the work is done during runtime. No error could be checked while compiling.

Gangnus
  • 2,805
  • 4
  • 21
  • 31