Subject: Re: How to get 3dvector largest coordinate index?
Date: Saturday 7th March 2009 05:28:16 UTC (over 8 years ago)
It's sad to see that so many people have no knowledge of the C++ language, or even worse, disdain for that knowledge and taking the attitude that it doesn't matter. Yes, the standard is pretty nasty, long and full of language that takes way too long to interpret. But it's *the* only source of authoritative answers to many of the questions we can encounter while coding. It's like a workman who doesn't like or want to understand his tools. Oh, wait -- it's exactly like that. Now don't get me wrong, I've by no means an expert at the language, but I've tried to preach 3.10.15 over the years (I saw that Charles beat me to it posting it). The very first reaction to the paragraph should be to read it again. Here it is: 3.10.15: If a program attempts to access the stored value of an object through an lvalue of other than one of the following types the behavior is undefined: — the dynamic type of the object, — a cv-qualified version of the dynamic type of the object, — a type that is the signed or unsigned type corresponding to the dynamic type of the object, — a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object, — an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), — a type that is a (possibly cv-qualified) base class type of the dynamic type of the object, — a char or unsigned char type. Note the wording of the first sentence (read it again, how many of you guys did read it the time Charles posted it? :). *Any other* access than the ones listed are invalid (actually undefined behavior, which in standard speak is run away and hide). Actually, Philip Taylor wrote an earlier email explaining most of this in plain talk, read his post again :) People try to get around this and read the following very liberally, but it turns out that no, the way you can access memory is very limited. The above can be summarize in short as: "Only one type can ever live at one memory address at the same time" Now, as many noted, char* are intentionally left there as a loophole. You can always access things through a char* and it will be fine. But you need to treat it as char, and not go around doing things like: float f; int* bad = (int*)(char*)(float*)&f; // this is bad. If you want an integer representing your IEEE 754 number, you need to do (assuming a long is 32 bits of course and endianess): float f; unsigned char* p = (unsigned char*)&f; long i = p << 24 | p << 16 | p << 8 | p; The union trick does not work. No really, it doesn't. It's undefined behavior meaning that the compiler is free to do whatever it likes. Even erase your hard drive or start tetris. It so happens that the gcc guys usually doesn't want people to hunt them down and strangle them so in this case they are trying to do the right thing, through turning off most of the optimizations. Another point to make is that the bit_cast that Pal mentioned (I think it has been mentioned before as union_cast) has one terrible flaw apart from the obvious that it's undefined since it uses the union trick: it works by copying r-values. It can thus be abused like this: int* i = union_cast