This documentation is very unclear for me when it tries to say what is ${type}Var.
...for Kotlin enums it is named
${type}Var
wat?! What is Kotlin enums? Regular Kotlin enums?
enum class MyEnum {
FIRST, SECOND
}
I don't think it implied.
Okay, Let's look at the examples in this documentation:
struct S*is mapped toCPointer<S>,int8_t*is mapped toCPointer<int_8tVar>
Okay, it's clear
char**is mapped toCPointer<CPointerVar<ByteVar>>
Why is char** mapped to CPointer<CPointerVar<ByteVar>> but not to CPointer<CPointer<Byte>>?
So finally the question is: what is IntVar, LongVar, CPointerVar<T> and other things like ${type}Var?
You should read the whole paragraph again carefully.
All the supported C types have corresponding representations in Kotlin:
- Enums can be mapped to Kotlin enum
Also in C there are lvalues and rvalues (In C++ the equivivalent is Type & for lvalues and Type for rvalues). The main distinguish is that lvalues can be set to some value, while rvalues can't be changed after the initialization. So for each type in C you need it's own Kotlin type for lvalue and for rvalue.
In the topic
All the supported C types have corresponding representations in Kotlin:
only rvalues are considered.
But for lvalues the only thing you need to add is Var to end of type. The only exception is
For structs (and typedefs to structs) this representation is the main one and has the same name as the struct itself
Now let's return to enums. The regular Kotlin enums are mapped to the regular C enums. So actually FIRST and SECOND have type MyEnum in both languages. But what if you want to create a variable containing MyEnum for example:
// This is C Code
MyEnum a = FIRST;
a has type MyEnum in C, but it's lvalue (in C++ that's MyEnum &), so in Kotlin a will have type MyEnumVar because that's exactly what is said in documentation: ${type}Var, where ${type} = MyEnum.
To the next questions:
The type argument T of CPointer must be one of the "lvalue" types
So for struct S* it should be CPointer<SVar>, but remember that structs are exceptions and we shouldn't add Var, so that's just CPointer<S>.
int8_t* is CPointer<int_8tVar> - no exception here.char* is CPointer<ByteVar> - again no exception (only lvalue types, except for structs).char** is CPointer<CPointerVar<ByteVar>> as we need lvalue for CPointer<ByteVar> and that's exactly CPointerVar<ByteVar>.Finally:
IntVar, LongVar, CPointerVar<T> and other things are lvalues of types int, long, CPointer. That may be needed if you want to change the object in the function. Something like Ref<${type}> in Java.
what is
IntVar,LongVar,CPointerVar<T>and other things like${type}Var?
That's in the beginning of the sentence the end of which you quoted:
the Kotlin type representing the lvalue of this type, i.e., the value located in memory rather than a simple immutable self-contained value
"located in memory" means that you can take their address (using & operator in C, or .ptr in Kotlin).
wat?! What is Kotlin enums? Regular Kotlin enums?
Yes, so when Kotlin/Native sees MyEnum, it also generates MyEnumVar.
Why is
char**mapped toCPointer<CPointerVar<ByteVar>>but not toCPointer<CPointer<Byte>>?
CPointer<CPointer<Byte>> is illegal: CPointer's type parameter must extend CPointed, and Byte and CPointer<T> don't. And the reason they need to extend CPointed is because dereferencing a pointer gives an lvalue: something that has an address!
See https://docs.microsoft.com/en-us/cpp/c-language/l-value-and-r-value-expressions or https://eli.thegreenplace.net/2011/12/15/understanding-lvalues-and-rvalues-in-c-and-c/ for more about lvalues in C (and C++).