Closed im-kulikov closed 5 years ago
Yes, you are right. Main probrem - pointers. Now, general approach C pointers and C array transpile to Go slice with unsafe. So, it is not easy to use simplification like in your code. For that example , we can simplify and avoid package noarch. Feel free for PR. Result Go code is must build, must work but now look in Go way.
Now, general approach C pointers and C array transpile to Go slice with unsafe
Can you provide example?
If you don't mind, I propose to don’t close the issue to continue the discussion and organize PR
You have a good question. I don't remember, you can research this, but please remember about 2 operations(see next examples) and that operations will have unsafe
always:
Just for example, please run:
go test -v -tags=integration -run=TestIntegrationScripts/tests/array.c
and look in files:
~/go/src/github.com/Konstantin8105/c4go/tests/array.c
~/go/src/github.com/Konstantin8105/c4go/testdata/tests/array/main.go
Example of pointer arithmetic C:
float* next_pointer(float* v)
{
long l = 1;
long p = 2;
(void)(l);
(void)(p);
return p - p + v + l;
}
Go:
// next_pointer - transpiled function from C4GO/tests/array.c:178
func next_pointer(v []float32) []float32 {
var l int32 = 1
var p int32 = 2
_ = (l)
_ = (p)
return (*(*[1000000000]float32)(unsafe.Pointer(uintptr(unsafe.Pointer(&(*(*[1000000000]float32)(unsafe.Pointer(uintptr(unsafe.Pointer(&v[0])) + (uintptr)(p-p)*unsafe.Sizeof(v[0]))))[:][0])) + (uintptr)(l)*unsafe.Sizeof((*(*[1000000000]float32)(unsafe.Pointer(uintptr(unsafe.Pointer(&v[0])) + (uintptr)(p-p)*unsafe.Sizeof(v[0]))))[:][0]))))[:]
}
or
absolute syntatic test - it is ok by C, but I don't finish for Go:
#include <stdio.h>
int global;
int * pd()
{
global = 45;
return &global;
}
int main() {
int *i = pd();
char *c = i;
double *d = c;
int *i2 = d;
printf("%d\n", *i2);
return 0;
}
Go:
package main
import "github.com/Konstantin8105/c4go/noarch"
import "unsafe"
var global int
// pd - transpiled function from $GOPATH/src/templorary/wer/main.c:5
func pd() []int {
global = 45
return (*[100000000]int)(unsafe.Pointer(&global))[:]
}
// main - transpiled function from $GOPATH/src/templorary/wer/main.c:11
func main() {
var i []int = pd()
var c []byte = i
var d []float64 = c
var i2 []int = d
noarch.Printf([]byte("%d\n\x00"), i2[0])
return
}
Also, you can use project https://github.com/elliotchance/c2go/ with another approach C array, C pointer -> Go unsafe.Pointer
. Choose tool in according to your task.
My point of view:
Oh.. thanks a lot! I’ll try to make research
This is a good example for your question:
#include <stdio.h>
void a(int *v1)
{
printf("a: %d\n",*v1);
}
void b(int v1[], int size)
{
for (int i = 0;i < size; i++) {
printf("b: %d %d\n", i, v1[i]);
}
}
int main() {
int i1 = 42;
a(&i1);
b(&i1, 1);
int i2[] = {11,22};
a(i2);
b(i2,2);
return 0;
}
Go
package main
import "unsafe"
import "github.com/Konstantin8105/c4go/noarch"
// a - transpiled function from $GOPATH/src/templorary/wer/main2.c:3
func a(v1 []int) {
noarch.Printf([]byte("a: %d\n\x00"), v1[0])
}
// b - transpiled function from $GOPATH/src/templorary/wer/main2.c:8
func b(v1 []int, size int) {
{
var i int
for ; i < size; i++ {
noarch.Printf([]byte("b: %d %d\n\x00"), i, v1[i])
}
}
}
// main - transpiled function from $GOPATH/src/templorary/wer/main2.c:15
func main() {
var i1 int = 42
a((*[100000000]int)(unsafe.Pointer(&i1))[:])
b((*[100000000]int)(unsafe.Pointer(&i1))[:], 1)
var i2 []int = []int{11, 22}
a(i2)
b(i2, 2)
return
}
C language is too flexibility.
Wow! Thank you immensely!
May be I will add that example in README.md
for showing the main approach of this project.
Have fun.
Close, because discussion is not progress.
In README we can see example:
that can be simplified to
I do not quite understand the meaning of using
unsafe
andnoarch
packages in this case, when you can translate this code much easier.@Konstantin8105, What you think?