How small could Int.bitWidth get on arbitrary platforms?

Is it safe to assume that Int.bitWidth will always be at least 32?

If not, then what about 16 or 8?

I’m writing some code that compares an Int against a constant, and I’m wondering how defensive I need to be about giving those constants explicit types.

I’d prefer to leave the constants as Int by default, but I worry that some hypothetical platform might have a smaller bit-width.

For example, given n: Int, is it reasonable to write if n < 1 << 30, or should I always make it if n < (1 as Int32) << 30 to ensure the shift doesn’t overflow on a small-width platform?

Do I need to be defensive all the way down to 128 in case an 8-bit platform might exist? Or even further?

Not to dodge the question, but is it worth worrying about being this defensive before you have a platform in front of you that might be less than 32 bits wide?

If time and money were infinite I would love to get Swift Embedded building on top of llvm-mos so I could target 6502/65816 hardware, and that C target has a 16-bit int IIRC.

The C standard requires that int be 16 bits or larger, so I don't think 8-bit is something you'd realistically need to worry about for Swift, either, so if you want to be defensive now, 16 is probably the lowest you'd need to go.

3 Likes

Two reasons:

First, I’m working on something that I’d like contribute to the standard library, so I’d rather do it right the first time.

Second, for bit shifts in particular, the failure mode if built for a platform of smaller bit-width is “silently does the wrong thing with no warning”. That is much worse than for integer literals (loudly fails to compile) or ordinary arithmetic (traps at runtime).

It looks like the compiler and standard library currently only support _16, _32, and _64 options for _pointerBitWidth, so if you replicate that, it should cover all the platforms Swift currently supports.

1 Like

In the stdlib, I’d spell it if Int.bitWidth < 32 || n < (1 << 30) (typed out freehand on the go: double check my logic) and let the compiler do its thing. It expresses your intent even if somehow Int is 2 bits wide.

(Or, to avoid any doubt as to untestable code paths, it would be fine at the top to have guard Int.bitWidth >= 32 else { fatalError("not implemented") }.)

6 Likes

Right. Stdlib code doesn’t need to handle every possible platform someone might want to support. It has to handle all supported platforms. It’s completely OK to have a check that will fail when someone tries to bring up a new platform that doesn’t meet expectations.

8 Likes

Thanks everybody!

2 Likes