What does "bits are not addressable" mean for dummies (like me and my students) ?
The smallest value/entity a computer can store/move/change is a byte = 8-bits. You cannot instruct it to read/write 3-bits, then 1-bit, then 11-bits, and tell the computer to memorize them as separate values. No, it only handles single bytes or byte packs/ranges.
Then the whatever application/process/hardware can play around with the bits inside a byte (or a native integer type, always a multiple of a byte).
Yet, once done playing, the stored values in memory/storage are still by "range" of bytes, which each single BYTE value - despite having their bits modified - gets directly updated with their new value at BYTE level.
That means, unless you build processors, you only actually deal with bytes, 0-255, period.
In records ? yes. Memory address ? yes. File data/stream ? yes. Network transfer ? YES GodDAMMIT !
As an example : lets say I'm on my LittleEndian computer having a 3 bytes (24-bits) record in memory in my application :
structure Test24 {
var16 : 0xC1D3, // 49619 = 1100 0001 1101 0011
var8 : 0xCA // 202 = 1100 1010
}
Record that I save raw in a file, which I pass on to a buddy, on his BigEndian machine. What he gets on his machine upon loading the record in the same application is :
structure Test24 {
var16 : 0xD3C1, // 54209 = 1101 0011 1100 0001 (bytes swapped)
var8 : 0xCA // 202 = 1100 1010 (same value)
}
The var16 is slightly different (corrupted), but that's because I didn't code my application to handle IO datas on a BigEndian architecture. He does not get the following record though where the bits gets entirely swapped :
structure Test24 {
var16 : 0xCB83, // 52099 = 1100 1011 1000 0011 (bits swapped)
var8 : 0x53 // 83 = 0101 0011 (different value)
}
^^ and that's because the file is read bytes-by-bytes, not bits-by-bits.
That's what "bits are not addressable" implies.
Student : But why are people being fancy about LSBit (LSB-0), MSBit, sometimes bit-endianness, like "it's very important knowledge" ?
Because that way of calling the bits actually gets the endianness concern out of the equation. Use the meaning of things in the right way, at least, use logic. The misunderstanding arises when we mix up talks about data, and talks about (processor) architecture. They-are-un-re-la-ted !
A data requires a context, like "this byte at this address contains the eight flags defining your access privileges on the system". That's NOT endianness concerns, that's what a bit at a given index is used for in the context of a defined data.
We, humans, are trained to read horizontally. But here is the problem :
What is byte 241 ? How we may represent what it contains ?
perhaps on little endian, LSB-0 on the left (?)
bit index : 0, 1, 2, 3, 4, 5, 6, 7 => 10001111b ?
or on big endian, LSB-0 on the right (?)
bit index : 7, 6, 5, 4, 3, 2, 1, 0 => looks more intuitive 11110001b
STOP SHOOTING YOURSELF IN THE FOOT ! Consider looking at it this way :
LSB 0 <- see : here it is, it doesn't matter where it is, it's just there
1
2
3
4
5
6
MSB 7 <- and here the other one, on the opposite side.
or this way :
MSB 7
6
5
4
3
2
1
0 LSBit
It doesn't matter where LSB-0 MSBit are as long as one is on the opposite side of the other. Get endianness out of the way ! Use the LSB-0 term to fix the start of your data encoding.
^^ now when you define "data flags order start at LSB-0", the flags being, "directory open, open pwd protected, directory copy, copy pwd protected, directory write, write pwd protected, directory delete, delete pwd protected", that means :
LSB 0 directory open
1 open pwd protected
2 directory copy
3 copy pwd protected
4 directory write subitem
5 write to pwd protected
6 delete subitem
MSB 7 delete pwd protected
So a byte value of 241 = LSB-0 : 1, 0, 0, 0, 1, 1, 1, MSB : 1
means
LSB 0 = 1 -> you can open directory
1 = 0 -> directory access is not password protected
2 = 0 -> you cannot copy directory
3 = 0 -> noop
4 = 1 -> you may create files or sub directories
5 = 1 -> but a password is required to create file or dir
6 = 1 -> you may delete the things in the directory
MSB 7 = 1 -> but a password is required to delete
There is no endianness involved at bit level when it comes to data, only bit position matters when you give a meaning to the value of a byte, and LSB-0 is always 0x01, no matter it's a big endian machine or a little endian one.
Byte values has nothing to do with how the machine treats a bit, most significant or not. So when you ask "could my data gets corrupted ?", noone should talk about MSBit or LSBit on the left or on the right. If you ask "what are the most volatile bits on this CPU ?", there you go, LSB/MSB positions is right in the middle of the talk (but are you into processor engineering ?)
- The actual SO question here is not how most architectures are assumed to behave (memory addressing), or can/cannot do, that, we should ask over Theorical Computer Science or Software Engineering.
- the real underlying question is when the data produced by my application, when it goes through network, IO, COM, hardware, whatever, gets its bits swapped, or gets corrupted when I failed to handle bit-order in my application.
Answer is : that doesn't happen, as long as you are not writing ROM data at hardware level, and you care about endianness at BYTE-level ONLY, when transferring data through different architectures/protocols. People are confused because of unnecessary endianness drama, and that endianness-thing is lurking where it should not.
At least, that's why I'm here, for students to start understanding what matters for a given challenge/concerns. They wouldn't be here if they already knew. Most people only have either little endian computer, or big endian, and don't have the privilege to cross check. They just don't know for sure, they get here via google and "bits are not addressable" errrmm... what ? what does that mean ? Should I swap my game data at byte or bit-level to be read correctly on all platforms or not ? I still don't know :/ That's the underlying reason why one would ask. Beyond the technical fact "bits are not addressable", there are that don't have the background to fully grasp the implications of such statement.
You only have to care about byte-endianness in the very rare case you actually encode your own made (or company specified) binary data through your application via your proprietary or borrowed stream read/write logic.
Don't want to handle endianness, use engines/frameworks with built-in read/write (like databases, clouds, etc.) or go plain text such as Json or XML.