Took me 30 min to track down the bug in this code

102 points neandrake

For a hobby project I'm building a clean-room implementation of a library for reading/writing a binary format. I just spent the last 30 minutes to track down the bug in this code:

let length: u16 = size_of::<u16> as u16 // sop_class_uid_length
            + sop_class_uid.len() as u16
            + size_of::<u16>() as u16 // service_class_uid_length
            + service_class_uid.len() as u16
            + size_of::<u16>() as u16 // rel_gen_sop_classes_length
            + rel_gen_sop_classes_length;

Where sop_class_uid and service_class_uid (both &[u8]) are "1.2.3.4".into() and "2.3.4.5.6".into() respectively, and rel_gen_sop_classes_length is itself quite small.

I was getting a value of 10520 for length instead of 42 (coincidence\~).

I was originally going to post asking for help but I did end up figuring out the issue and what was happening:

! On the first line the size_of::<u16> as u16 is missing the function call parens, and should be size_of::<u16>() as u16. Without the parens this would normally result in an error but due to the cast it treats size_of as a function pointer as a numeric value. Oof. Playground link. !<