-
Notifications
You must be signed in to change notification settings - Fork 159
Frequently Asked Questions (FAQ)
Generated Code
- Why are C strings (
const char*
) treated as[]byte
, instead of using Go'sstring
type? - Why are all pointers converted into slices?
There are a few reasons:
- Strings in Go are immutable. In C, strings can (and often are) manipulated directly. This would cause huge issues with the garbage collector as every change would have to create a new string.
- Since C strings are pointers they are always passed by reference, allowing functions to manipulate them. This would require all strings to be passed by reference and make the output very un-Go-like and error prone.
- You may also notice that all strings have a NULL byte appended to them. This is to make compatibility of low-level functions more consistent with how they work in C. C strings do not have a defined length and so they have a virtual end at the first NULL character which may or may not be the last character in the dynamically or statically allocated memory block. Unlike Go strings which have a defined length, despite including NULL characters.
In C, a pointer refers to the start of a memory block. That memory block may one contain one element, or it may be the start of a statically or dynamically allocated block. The same pointer can refer to several of these during its lifetime with no way or knowing at compile time or runtime. In Go, pointers only refer to a reference of a single entity and pointer arithmetic does not really exist (at least not in the same way as it can be done in C).
On top of that we want the type system from C to Go to be simple and predictable. At any point during the transpilation we should always be able to derive the same Go type from a C type without needing to know any other information.
Making all pointers into slices is able to cover all of these scenarios with a little trickery. When using pointers as arrays it translates nicely into Go slices. The trickiness is when we want to use a pointer to take the reference of something else, for example:
int a;
int *b = &a;
In this case we create a slice for b
(the same as all pointers) but we manipulate the internal pointer of the slice data to point to the location of a
. When b
is dereferenced (*b
or b[0]
) the value will refer to the value of a
. This is also true when changing the value of a
or the dereferenced b
as they point to the same memory location.