c-for-go
c-for-go copied to clipboard
Arch-specific options for integer type mapping
Firstly, thanks for creating and maintaining such a useful utility.
I found commit https://github.com/xlab/c-for-go/commit/ddcfe2673053652b6566fa8fabe6d0966a6b4ed9 changes the default type mapping for long and int type. Indeed, unless the size is explicitly specified (e.g. uint64_t), the sizes of types int / unsigned int / long / unsigned long are arch-specific and implementation-specific. The change in commit https://github.com/xlab/c-for-go/commit/ddcfe2673053652b6566fa8fabe6d0966a6b4ed9 seems to be correct.
However, such changes will break the signature of existing Go bindings between versions (https://github.com/NVIDIA/go-nvml/issues/31#issuecomment-981449209). If the user wants to generate bindings for a specific platform (e.g. x86_64_linux), type unsigned long should be translated to uint or uint64 type.
Should we make this mapping to be arch-specific (wiki/Parser-config-section#arch)?
https://github.com/xlab/c-for-go/blob/291d167cff5752d6cc5b4c369c326cd5ac61367a/parser/predefined.go#L81-L104
Or is there a way to add some option in the configuration to customize it?
Related issue NVIDIA/go-nvml#31.
C snippet:
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
// User defined function in C
void printf_ulong(unsigned long *x)
{
*x = (unsigned long)UINT32_MAX + 1;
printf("Value in function: %lu\n", *x);
}
// Binding in Golang
void go_binding()
{
uint64_t value64 = 0;
printf("Value before function: %lu\n", value64);
printf_ulong((unsigned long *)&value64);
printf("Value after function: %lu\n", value64);
}
int main()
{
go_binding();
return 0;
}
On x86_64 Linux machine (Ubuntu 20.04 LTS), compile and run with g++ 9.3.0:
$ uname -io
x86_64 GNU/Linux
$ gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc -std=c99 "test.c" -o "test" && { ./"test"; rm "test" }
Value before function: 0
Value in function: 4294967296
Value after function: 4294967296
C snippet (change types to uint32_t but keep the function input type as unsigned long):
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
// User defined function in C
void printf_ulong(unsigned long *x)
{
*x = (unsigned long)UINT32_MAX + 1;
printf("Value in function: %lu\n", *x);
}
// Binding in Golang
void go_binding()
{
uint32_t value32 = 0;
printf("Value before function: %u\n", value32);
printf_ulong((unsigned long *)&value32);
printf("Value after function: %u\n", value32);
}
int main()
{
go_binding();
return 0;
}
Got errors:
$ gcc -std=c99 "test.c" -o "test" && { ./"test"; rm "test" }
Value before function: 0
Value in function: 4294967296
Value after function: 0
*** stack smashing detected ***: terminated