What you do is not supported by the c++ standard, reading from non active union member is undefined behaviour. So if you write in i then read from bf, it is UB. However some compilers may allow this via extensions. On top, compilers are free to pad the structs so unless you specifically tell the compiler not to pad, you can end up with a surprise.
What you can do is get rid of union and add helper methods to struct to initialise bitfields from different data