Seems that I really know not much about Nim strings...
var FirmwareTableProviderSignature: uint32
var a, b, c, d: uint32
FirmwareTableProviderSignature = cast[uint32]("ACPI".cstring)
echo 'A'.ord shl 0 + 'C'.ord shl 8 + 'P'.ord shl 16 + 'I'.ord shl 24
a = cast[uint32]("ACPI")
b = cast[uint32]("ACPI".cstring)
c = cast[uint32]("ACPI"[0])
d = cast[uint32]("ACPI"[0 .. 3])
echo a
echo b
echo c
echo d
$ ./t 1229996865 4323872 4323921 65 1255772240
The last value is arbitrary. Will think or read about it tomorrow -- indeed I was going to try castuint32 which does not compile.
echo 'A'.ord shl 0 + 'C'.ord shl 8 + 'P'.ord shl 16 + 'I'.ord shl 24
var a,b,c,d: uint32
let x = "ACPI"
a = cast[ptr uint32](x[0].unsafeAddr)[]
b = cast[ptr uint32](x.cstring)[]
c = cast[ptr uint32]("ACPI".cstring)[]
d = cast[ptr uint32](cast[int]("ACPI".cstring))[]
echo a
echo b
echo c # 65 ???
echo d
"A" is represented by the unsigned integer 65 in utf-8. On that particular line you are covering a string to a cstring, converting that into a pointer to a unsigned integer, then dereferencing the pointer. Since a cstring is a pointer to a character array, dereferencing the pointer will give you the first character.
There is a possible bug this program reveals though - the type of c looks to be a uint8, when it should be something else. This is because the value printed should be a amalgamation of the first four character's integer form (8-bit characters times four equals 32).
@variount yes that possible bug is why I wrote "65 ???" ... imho it should be the same result as in d.
Something similar happens with:
var a = cast[ptr uint32](cast[int](['A','C','P','I']))[]
echo a
Which crashes without the intermediate cast to int.
Note that casting the intermediate state to "pointer" or any "ptr type" does not work either.
The cast to ptr uint32 of the c string generates.
x = *"ACPI"
While the other version casts the cstring pointer to an int and this than to the uint32 pointer.
x = *((NU32*) ((NI) ("ACPI")));
It seems like the Nim compiler is missing that the cstring is actually a pointer to a char array and as such needs a cast to the uint32 type to work correctly. I don't know if it is supposed to know that "cstring" is a "ptr char array" in the context of casts.