Why are some primitive types defined in Julia, and others in the C code?


I noticed that the Base Julia code defines some primitive types, but not others, and I’m curious if somebody could explain this. Specifically it seems that Bool, UInt8, Int32, UInt32, Int64, and UInt64 are defined in the C code, while the other primitive types are defined in the Julia code.

I guess that Int32 and Int64 being defined in the C code has something to do with the fact that either one or the other is aliased to Int depending on architecture, but I’ve got no clue on the others.

It’s especially puzzling how Int8 is defined in Julia, but UInt8 and Bool are defined in C, seeing as they’re all “just bytes”.

Note that I almost surely won’t be reading the C code, so I’m hoping for some simple explanation, if possible :grinning:

This is the relevant Julia file, BTW: julia/boot.jl at master · JuliaLang/julia · GitHub


The ones that are defined in C are the ones are used from the C code for Julia’s runtime. Since one needs to have a reference to these types from both C and Julia, there are two ways you can go about it:

  1. Define in Julia then make C bindings;
  2. Define in C then make Julia bindings.

For a while we did the former to try to make more things defined in Julia code, but it’s a bit awkward. You need to predeclare all these types in C without definitions, then get enough of the Julia runtime working to evaluate enough Julia code to define those types (without using any of them). Then you need to finish setting up the C runtime by grabbing references to the types you’ve created in Julia and initializing C references to them. Then you can go back to evaluating Julia code to bootstrap Base.

The second order is less annoying: you setup the C runtime including all the Julia types it needs in one go; then you make Julia references to those types and you’re ready for pure Julia bootstrapping. In particular, this avoids needing a phase where you can evaluate Julia code without being able to use any Julia types from the C runtime code.

Taking this one as an example: the Julia runtime uses the UInt8 type but doesn’t use Int8 anywhere, so Int8 can simply be defined in Julia code and no C reference to it needs to exist.