Why are programming languages strictly reliant on primitive types, and is assembly more flexible? [closed]

StackOverflow https://stackoverflow.com/questions/15715787

Question

Why don't we have data types that are 4 bits in size? Why can't we make them if we are so inclined? I have seen bit-fields, but I have heard they are not portable, and perhaps not used as well? I think this is a result of how the machine interprets the place-value of the bit's location. (big-endian, little-endian)

typedef struct
{
   int b1  : 1;
   int b2  : 1;
   ..
   ..
   ..
   int b32 : 1;
} bitfield32;

We also cannot make a bit-field like this which is bigger than any primitive type. So why the restrictions? Can it be done in assembly?

Was it helpful?

Solution

Why don't we have data types that are 4 bits in size?

Who said that? The Intel 4004 CPU had 4-bit registers and 4-bit memory operands. 4-bit data types are natural for this CPU since they're supported directly.

The Intel 8051 CPU can manipulate single bits of memory directly and so you can have 1-bit variables on it.

These are just two examples of CPUs where data types can be very small, smaller than now ubiquitous 8-bit bytes.

Why can't we make them if we are so inclined?

We can. You can either make a CPU with direct support for 4-bit data types or you can simulate 4-bit variables as parts of larger variables.

You could pack 2 4-bit variables into an 8-bit byte. The problem with this approach is that you need to use more instructions to extract 4 bits from 8-bit registers or memory locations (you need a shift and a mask (AND) instruction for this) and similarly you need more instructions to properly save 4-bit values into the halves of an 8-bit byte (load 8 bits, clear the old value in the 4-bit half (with mask/AND), shift the new value, combine it with the rest and save back). Obviously, this would negatively affect the code size of your program and its speed. Besides, 4-bit variables aren't very useful since they can hold so little information. For these reasons simulation of smaller types isn't very popular.

I have seen bit-fields, but I have heard they are not portable, and perhaps not used as well?

They are used. They exist precisely because in some (but not all) applications they are very useful. If you have many short variables, it may be advantageous to pack several of them into a byte or a machine word and thus reduce memory waste.

They aren't entirely unportable. They have limited portability in C and C++ because the language standards do not define precisely the location and layout of bitfields in the larger data types. That's done intentionally to allow compiler writers to utilize CPU features most effectively when working with bit-fields.

6.7.2.1 Structure and union specifiers clause 10 of the C standard from 1999 says this:

An implementation may allocate any addressable storage unit large enough to hold a bitfield. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.

 

I think this is a result of how the machine interprets the place-value of the bit's location. (big-endian, little-endian)

Yes, that's part of the reason. But that's in no way specific to bit-fields exclusively. Regular, non-bit-field types have this problem as well.

We also cannot make a bit-field like this which is bigger than any primitive type. So why the restrictions? Can it be done in assembly?

If your C (or C++) compiler (or interpreter) can simulate types bigger than those supported by the CPU directly, you can have even 256-bit bit-fields.

But again, if the CPU's largest type supported directly is 32-bit, it will mean that the use of larger types (whether bit-fields or not) like 128-bit ones is going to incur more code and certain performance penalties since a single CPU instruction (or just a couple of them) won't be able to manipulate with such big data values. You'll need more instructions and more time to execute those extra instructions.

Yes, this can be done in assembly. Anything can be done in assembly so long as you're willing to write the code and make it work. :)

OTHER TIPS

Why don't we have data types that are 4 bits in size?

Because the smallest numbers that modern processors like x86 can work on is 8 bits.

Why can't we make them if we are so inclined?

You can, but they would be much slower because you'd have to do more work than normal, since the processors don't support it.

Can it be done in assembly?

Assembly is just a bunch of instructions for you processor, so you could only do it efficiently if your processor supports it.

A lot of this will make sense if you actually study digital design; until then, you'll have to just take these restrictions as granted.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top