C++ is bad: structs aren't the same as structs

Aug 20, 2009 20:38

Here's a fun little problem. Suppose you've got a system that makes use of the following struct:

struct User {
unsigned int user_id;
unsigned short access_level;
float account_balance; // stored as US dollars
}Your system is ridiculously well-tested, all the tests pass, everything works totally fine. I'll be so bold as to say it's (kinda) ( Read more... )

software engineering, software, cpp, cpp is bad

Leave a comment

Comments 8

mikasaur2000 August 21 2009, 06:16:28 UTC
An interesting quirk of C++... Vewwy interwesting.

A question, though. You obviously know I'm new to C++, so this might be really basic, but what does the line:

new_user.access_level = Privileges::ROOT;

mean? Specifically the Priviliges::ROOT part. I've seen the :: when you're defining a member function of a class outside of its declaration (I think that made sense) but I'm not quite sure what's going on here.

As for the account_balance thing, I've no idea. It can't be a precision or size thing. Does it have to do with the way you might withdraw or deposit money and things getting out of sync? Yeah, I don't know...

Reply

big_bad_al August 21 2009, 06:27:20 UTC
It's referring to the ROOT object/data in the Privileges class/namespace. By convention, things in UPPERCASE are constants, and we already know it's an unsigned short. I didn't bother showing you the Privileges class, but I had intended the constants in it to be bit fields.

Reply


macdaddyfrosh August 21 2009, 15:01:14 UTC
The :: notation is for getting at static (not-bound-to-an-instance) class data. If you've seen Java's Math.Pi, this is the same thing, just a different syntax.

First basic rule of C++: ninety percent of "good coding practice" is to keep you from shooting yourself in the foot.

Reply


Heh ISO floating point... anonymous October 15 2009, 06:34:35 UTC
As someone who has had this drilled into his head at Mudd, I'm not sure if I count as allowed to comment, but hey, I haven't seen any other responses so far.

It almost gives it away, but the reason you should never, ever store data that requires precision - like financial info - is because, well, ISO floating-point (i.e. the float or double types in C, C++, Java, Python, or pretty much any language) is imprecise by design. It's not possible to have arbitrary-precision numbers in POD like floats or doubles, because to have arbitrary precision you need an arbitrary number of bytes. Floating-point fudges this by storing a floating-point number encoded in fractional powers of two, which means that only numbers that are sums of integer powers of two (and fit within a certain range) are stored precisely, and such numbers are still limited by the number of available bytes. This also means that addition and multiplication aren't commutative, for obvious reasons.

Hence you could have an Office Space type problem, where adding $1 to someone's ( ... )

Reply

Re: Heh ISO floating point... big_bad_al October 15 2009, 08:14:19 UTC
Precisely! Using floating point numbers for money can land you in federal pound-me-in-the-ass prison. Addition and subtraction are noncommutative, which can lead to catastrophic cancellation (add a million dollars, add one cent, then subtract a million dollars, and you're left with nothing) and round-off errors when calculating exchange rates can cause similar woes (convert from dollars to euros to dollars again, and the balance is different). On top of that, doubles take up 64 bits in RAM but 80 bits in the FPU (see "extended precision"), which means that floating point comparison can be nondeterministic (depending on what else needs the FPU and what optimizations the compiler is trying, there isn't a good way to know how many bits of precision a given double will have ( ... )

Reply

Re: Heh ISO floating point... big_bad_al October 21 2009, 00:05:00 UTC
Wait, I think floating point operations are still commutative. However, they're not associative, which is what leads to the problems.

Reply

Re: Heh ISO floating point... anonymous October 23 2009, 12:19:25 UTC
You may be right about that. I believe ISO actually specifies commutativity for floating point ops, though associativity is definitely out.

Reply


Leave a comment

Up