Implications and Motives for Supporting Various Architectures.

I am writing a simple C program with SDL2 which utilizes some techniques from Handmade Hero. I wish for it to support gnu/linux, windows, macos, iphoneos and android OS's. As I understand it, the common cpu architectures one may encounter on these OS's are x86_64, i386, arm and arm64. I have some questions regarding these different architectures:
1. For an x86_64 cpu, is there any benefit to compiling for i386? i.e. compile 32 bit application to be run on 64bit OS. If not, are there really that many 32bit OS's that people still use to play games to make it worth supporting?
2. Across these architectures, will Handmade Hero's
1
typedef float real32; typedef double real64;
still be accurate? i.e. does a float on 64bit take 32bits but on other architectures does it take a different amount?

3. I like the idea of using fixed sized data types where possible, i.e. u32 over int. However, across these architectures, is there a particular size I should favor?
4. Are there any other notable things to be thinking about when supporting these various architectures when programming? (I know intrinsics are one thing)

Sorry if these are basic questions, I'm just having trouble distinguishing between the differences in these architectures and how that affects the C code you are writing.
Thanks.

EDIT:
As I know the compiler used influences these things, for gnu/linux, windows and macos I am using llvm clang. For iphoneos xcode and android android studio.

Edited by Ryan on Reason: Include compilers used
1.

i386 is pretty much dead. Unless you really want to support almost 15 year old hardware. There are tiny amount of new PC's released that support only 32-bit. It is not common anymore. As for OS - Ubuntu and ArchLinux dropped 32-bit support last year, macOS current version is last one that supports 32-bit binaries (although you cannot buy 32-bit macOS hardware anymore for a very long time). Windows will probably follow soon. Most big major software is released only as 64-bit binaries. For example Unity Editor dropped 32-bit support 3 years ago.

As for ARM - 32-bit arm is still out there. But it will be soon decreasing. All new phone hardware is armv8. If you want to write code for future products, it makes sense to evaluate if you really want to support 32-bit arm when your product will be released.

So you are really left with two major architectures x86_64 and armv8.

2.

yes, float always takes 4 bytes and double always takes 8 bytes. This is irrelevant of architecture - intel or arm, 32-bit or 64-bit or even 16-bit x86. float/double comes from IEEE 754 standard that many architectures implement.

3.

depends on use case. Sometimes 32-bit type is better even on 64-bit because it takes less memory so more values fit in cache. Sometimes 64-bit is better on 64-bit because some operations are not available on 32-bit types (like pointer + offset addressing), so compiler needs to insert extra instructions to extend it to 64-bit or similar.

4.

Extensions to instruction set would be one thing. SSE3/4, AVX1/2/512, FMA. Same one arm - arm6, arm7, arm7 & neon, other arm7 extensions. On amrv8 its a bit easier as neon is mandatory, only very few rare operations is an extension (like AES crypto)


Edited by Mārtiņš Možeiko on
Thank you so much Martins! I have a much better understanding now.