Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!gatech!ncar!ames!pacbell!att!chinet!kdb From: kdb@chinet.chi.il.us (Karl Botts) Newsgroups: comp.std.c Subject: casting structs Message-ID: <9184@chinet.chi.il.us> Date: 6 Aug 89 08:32:18 GMT Reply-To: kdb@chinet.chi.il.us (Karl Botts) Distribution: usa Organization: Chinet - Public Access Unix Lines: 60 Why is it utterly illegal to cast a struct (or a union) to anything? Obviously, this would be a capability susceptible to abuse; nevertheless, it is not in the "spirit of C" do ban something for that reason only. In fact there are cases -- particularly involving bit structs, but it is possible to hypothesize case for other structs as well -- when casting a struct seems perfectly reasoable. For instance: typedef struct X_T { unsigned a : 1; unsigned b : 2; unsigned c : 3; } x_t; x_t x = { 1, 2, 5}; int i = (int)x; seems quite sensible to me. Of course, you can acheive the desired effect here by replacing the last line of the above with: int i = *(int *)&x; but this strikes me as unnecessary obfuscation (but no additional overhead, at least on the compilers I have traced through the output of similar code for -- they can figure out that no real pointer operations are required here.) What would be really nice would be a way to initialize an int, say, by using a struct. It is perfectly legal to initialize a value by casting another type of value into the type desired, as in: long l = (long)&foo; where foo can be any lvalue. So why isn't it legal for a non-scalar type? The only reason I can come up with is that it won't fit into the syntax -- at least I can't come up with anything that seems sensibel and would work. How would you wirte what I _really_ want to do in the first example? int i = (int)x_t x = {1, 2, 5}; Whoops, that's no good (even if the compiler would accept it) -- it defines a data object "x", just like the first example. So lets leave x out: int i = (int)x_t = {1, 2, 5}; Hey, wait a minute, maybe that _does_ work. Suppose we stipulated that initializing a type name, as opposed to an object of that type, produces an rvalue of the specified type and value, rather than an lvalue. This wouldn't break any code, because initializeing a type name is simply illegal now. Hmmm.. The next question is, is the above an LALR parse? I can't see any reason why not, off the top of my head. If the type name was compound, you might have to put perens around it as in: int i = (int)(struct X_T) = {1, 2, 5}; I must think about this...