Open steffengy opened 6 years ago
Glad you're asking ;-)
The internal/crt
is a temporary one. I will get to its reason of existence below. It differs from cznic/crt
in that
sqlite2go
of cznic/crt
)The goal is of course to get back having only one CRT in cznic/crt
.
The new sqlite2go
produces code isolating the worlds of C and Go pointers from observing each other wherever possible. That was a main failure point of cznic/ccgo
. The outcome is that every C pointer becomes an uintptr
in Go, completely breaking compatibility with the current CRT API, where those things are declared as unsafe.Pointer
.
cznic/crt
cznic/sqlite
working on Windows. sqlite2go
has not been tested on WIndows yet and we don't know if it will just work, or if there is a lot of work yet to be done.internal/crt
to cznic/crt
. The former support only Linux, so also regenerate cznic/sqlite
for `linux_{amd64,386}.cznic/sqlite
continues to work for both Windows and Linux in the time the Windows port of sqlite2go and the new Windows crt is not yet existing and/or known to work.cznic/sqlite
, instead develop the Windows port in cznic/sqlite2go
and cznic/sqlite3shell
.cznic/sqlite
for all platforms and make a joint announcement for both platforms at once. Not really important, but better, I guess.It's up to you which way you prefer. There's no hurry. I am currently working on the libtcl
support to be able to run the original TCL tests via tclsqlite.c
. I think we should release cznic/sqlite
only after those tests work and pass. Either all of them, or the release can point out that some special cases are not yet, or never will be handled. Not that I know about such, but that may happen.
Thanks for joining the project!
The outcome is that every C pointer becomes an uintptr in Go, completely breaking compatibility with the current CRT API, where those things are declared as unsafe.Pointer.
How does that work with preventing use-after-frees?
Just because the memory is allocated as a []byte
before that outlives the running code?
I think since it should fairly trivial (a few hours) to port, approach B would work better.
To clarify:
cznic/sqlite2go
is independant of the platform, so in the best case modifying CRT is enough already.cznic/sqlite3shell
runs, replace cznic/crt
with sqlite3shell
's new CRT and the "port" is done.How does that work with preventing use-after-frees?
It does not work. sqlite2go should translate correct and working C programs to correct and working Go programs where possible. If the original C code uses a C pointer after free, the program may crash. However, note that [translated] C allocates outside of Go managed heap completely, so the result might be sometimes the same as in the original C code - it can silently "just" work, because no other malloc/free/realloc has yet reclaimed/overwritten the freed memory.
I think since it should fairly trivial (a few hours) to port, approach B would work better.
I think you've selected the better approach. Not sure about the "few hours" part though ;-)
AFAIK cznic/sqlite2go is independant of the platform, so in the best case modifying CRT is enough already.
Well, sqlite2go has never been tested on Windows. It depends on cznic/ccir/libc and cznic/cirtual (not exactly sure why in the later case) and things probably lagged for Windows, at least in the libc headers.
After cznic/sqlite3shell runs, replace cznic/crt with sqlite3shell's new CRT and the "port" is done.
Yes!
C allocates outside of Go managed heap completely.
That's the important point I didn't remeber anymore, thanks for refreshing my memory. (I was thinking about the previous VM I think, too much time ago)
I think you've selected the better approach. Not sure about the "few hours" part though ;-)
Yeah best case of course :)
Atleast sqlite2go already seems to builds on windows, so definitely not the worst case.
@cznic I seem to be having some trouble with c99 parsing of (omitted some spaces so it fits here)
#define isnan(x) __mingw_choose_expr ( __mingw_types_compatible_p ( __typeof__( x ) , double ) ,
__isnan ( x ) , __mingw_choose_expr ( __mingw_types_compatible_p ( __typeof__( x ) , float),
__isnanf (x) ,__mingw_choose_expr (__mingw_types_compatible_p (__typeof__( x ) , long double),
__isnanl ( x ) , __dfp_expansion(__isnan , ( __builtin_trap ( ) , x ) , x ) ) ) )
since c.expand
in cpp.go seems to inject some {}
within it with leads to:
sqlite-amalgamation-3210000\sqlite3.c:28223:8: unexpected '{', expected one of [!=, $end, %=, &&,
&=, '%', '&', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '[', ']',
'^', '|', '}', *=, ++, +=, --, -=, ->, /=, <<, <<=, <=, ==, >=, >>, >>=, ^=, |=, ||]
As a quick workaround, can you please try removing [conditionally only for Windows?] this define? If it helps, feel free to commit right to master.
FTR: I'm not aware of any inejctions of {}
being performed in c.expand
. It's just the notation used in https://www.spinellis.gr/blog/20060626/cpp.algo.pdf meaning 'empty list'.
As a quick workaround, can you please try removing [conditionally only for Windows?] this define? If it helps, feel free to commit right to master.
Yeah sure that would likely work, since it'd use sqlites isnan. but possibly other macros have the same issue.
FTR: I'm not aware of any inejctions of {} being performed in c.expand. It's just the notation used in https://www.spinellis.gr/blog/20060626/cpp.algo.pdf meaning 'empty list'.
Yeah I'm dumping toks
before and w.toks
after https://github.com/cznic/sqlite2go/blob/7f5b1202061163184d9f3320b5512be7ec96de1b/internal/c99/cpp.go#L578
and somehow multiple {}
are injected:
before:
[-: "\ue020" "__mingw_choose_expr" -: " " -: "(" -: " " -: "\ue020" "__mingw_types_compatible_p" -: " " -: "("
-: " " -: "\ue020" "__typeof__" -: " " -: "(" -: " " -: "\ue020" "x" -: " " -: ")" -: " " -: "," -: " " -: "\ue020" "float" -:
" " -: ")" -: " " -: "," -: " " -: "\ue020" "__isnanf" -: " " -: "(" -: " " -: "\ue020" "x" -: " " -: ")" -: " " -: "," -: " " -:
"\ue020" "__mingw_choose_expr" -: " " -: "(" -: " " -: "\ue020" "__mingw_types_compatible_p" -: " " -: "(" -:
" " -: "\ue020" "__typeof__" -: " " -: "(" -: " " -: "\ue020" "x" -: " " -: ")" -: " " -: "," -: " " -: "\ue020" "long" -: "
" -: "\ue020" "double" -: " " -: ")" -: " " -: "," -: " " -: "\ue020" "__isnanl" -: " " -: "(" -: " " -: "\ue020" "x" -: " "
-: ")" -: " " -: "," -: " " -: "\ue020" "__dfp_expansion" -: " " -: "(" -: " " -: "\ue020" "__isnan" -: " " -: "," -: " " -: "
(" -: " " -: "\ue020" "__builtin_trap" -: " " -: "(" -: " " -: ")" -: " " -: "," -: " " -: "\ue020" "x" -: " " -: ")" -: " " -: ","
-: " " -: "\ue020" "x" -: " " -: ")" -: " " -: ")" -: " " -: ")"]
after
[-: "\ue020" "__mingw_choose_expr" -: " " -: "(" -: " " -: "\ue020"
"__builtin_types_compatible__" -: "(" -: "(" -: "\ue020" "__typeof__" -: " " -: "(" -: " " -: "\ue020" "x" -: " " -: ")"
-: ")" -: "{" -: "}" -: "," -: " " -: "(" -: "\ue020" "float" -: ")" -: "{" -: "}" -: ")" -: " " -: "," -: " " -: "\ue020"
"__isnanf" -: " " -: "(" -: " " -: "\ue020" "x" -: " " -: ")" -: " " -: "," -: " " -: "\ue020" "__mingw_choose_expr" -: "
" -: "(" -: " " -: "\ue020" "__builtin_types_compatible__" -: "(" -: "(" -: "\ue020" "__typeof__" -: " " -: "(" -: " " -:
"\ue020" "x" -: " " -: ")" -: ")" -: "{" -: "}" -: "," -: " " -: "(" -: "\ue020" "long" -: " " -: "\ue020" "double" -: ")" -:
"{" -: "}" -: ")" -: " " -: "," -: " " -: "\ue020" "__isnanl" -: " " -: "(" -: " " -: "\ue020" "x" -: " " -: ")" -: " " -: "," -: " "
-: "(" -: " " -: "\ue020" "__builtin_trap" -: " " -: "(" -: " " -: ")" -: " " -: "," -: " " -: "\ue020" "x" -: " " -: ")" -: " " -:
")" -: " " -: ")"]
Hmm, don't know where the '{' and '}' come from. I suspect the culprit is possibly the expansion of some builtins (like __mingw_types_compatible_p
, provided it's a macro) or lack of expansion of some other builtins. For instance, I think __typeof__
, __mingw_types_compatible_p
, __isnanl
and similar are probably unrecognized/usupported. Some may come from the __mingw_choose_expr
perhaps. Where does this macro come from? I though that even before we supported the predefines and builtins from gcc, but now I see the Windows port in ccir/libc mentions mingw often.
Unfortunately, I know nothing about mingw. When dealing with GCC, I had to remove all gcc*
and gnu*
defines to make it not pulling gcc-specific things, like assembly implementations of things etc. Maybe you can try something similar to avoid mingw specifics?
Especially the various predicates (__foo_p
) make me nervous. They are usually implemented directly in the compiler and often it's not possible to actually implement them as a macro. Meaning, we cannot have them slip into the compilation or we have to emulate them completely. I would prefer to avoid the later, if possible.
Hmm #2. I see the "old" cznic/cc supported at least `builtin_types_compatible' and maybe more such stuff.
So, if really necessary, I'll port those very speical "macros" to cznic/sqlite2go/internal/c99.
@cznic It's defined in the same header file:
#define __mingw_choose_expr __builtin_choose_expr
#define __mingw_types_compatible_p(type1, type2) __builtin_types_compatible_p ( type1 , type2 )
__isnanXX are extern functions that are defined in that header aswell.
So __builtin_types_compatible_p
isn't supported?
So __builtin_types_compatible_p isn't supported?
Not yet. Will try to port the __builtin_types_compatible_p
implementation from 'cc'.
@steffengy Please try https://github.com/cznic/sqlite2go/commit/eda9f5474f89d464bbf5973f185686d24115ab89, it does not yet support __builtin_types_compatible_p
completely, but there's a chance it will handle just what's needed.
Edit: typo
Still the same output after c.expand
as far as I can see:
[-: "\ue020" "__mingw_choose_expr" -: " " -: "(" -: " " -: "\ue020" "__builtin_types_compatible__" -: "(" -: "("
-: "\ue020" "__typeof__" -: " " -: "(" -: " " -: "\ue020" "x" -: " " -: ")" -: ")" -: "{" -: "}" -: "," -: " " -: "(" -:
"\ue020" "float" -: ")" -: "{" -: "}" -: ")" -: " " -: "," -: " " -: "\ue020" "__isnanf" -: " " -: "(" -: " " -: "\ue020" "x" -:
" " -: ")" -: " " -: "," -: " " -: "\ue020" "__mingw_choose_expr" -: " " -: "(" -: " " -: "\ue020"
"__builtin_types_compatible__" -: "(" -: "(" -: "\ue020" "__typeof__" -: " " -: "(" -: " " -: "\ue020" "x" -: " " -: ")"
-: ")" -: "{" -: "}" -: "," -: " " -: "(" -: "\ue020" "long" -: " " -: "\ue020" "double" -: ")" -: "{" -: "}" -: ")" -: " " -: ","
-: " " -: "\ue020" "__isnanl" -: " " -: "(" -: " " -: "\ue020" "x" -: " " -: ")" -: " " -: "," -: " " -: "(" -: " " -: "\ue020"
"__builtin_trap" -: " " -: "(" -: " " -: ")" -: " " -: "," -: " " -: "\ue020" "x" -: " " -: ")" -: " " -: ")" -: " " -: ")"]
Analogically for other __magic__
keywords if encountered.
Won't that just lead to typeof being replaced with ""?
Github formatting sucks, I wanted to say
#define __typeof__ typeof
Edit: grammar
Yeah that works, I'll try to get the next error resolved.
libc\__ctype_b_loc_tab.c:132:2: undefined: _IScntrl
Now I'm getting a:
sqlite2go: PANIC: D:\projects\Go\gopath\src\github.com\cznic\sqlite2go\_sqlite\sqlite-amalgamation-3210000\sqlite3.c:28223:8: undefined: __mingw_choose_expr
github.com/cznic/sqlite2go/internal/c99.(*Expr).eval(0xc046770ff0, 0xc04224c000, 0xc046776501, 0xc046769110, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
I guess this is because __builtin_choose_expr
is not defines aswell
and then not expanded here?
Can you port that aswell?
~/src/github.com/cznic/ccir/libc> grep -nr '#define __mingw_choose_expr'
math_windows_386.h:411:#define __mingw_choose_expr __builtin_choose_expr
math_windows_amd64.h:329:#define __mingw_choose_expr __builtin_choose_expr
~/src/github.com/cznic/ccir/libc> grep -nr '#define __builtin_choose_expr'
builtin.h:15:#define __builtin_choose_expr(a, b, c) (a) ? (b) : (c)
~/src/github.com/cznic/ccir/libc>
Seems defined to me, should expand to a conditional expression (the C ternary operator). Can you see why it does not happen? So far I don't.
Is builtin.h still included automatically?
Not sure if that's the problem, but that error should be impossible since it should be expanded during expansion (to __builtin_choose_expr atleast) So there's definitely something going wrong.
Not sure if that's the problem, but that error should be impossible since it should be expanded during expansion (to __builtin_choose_expr atleast) So there's definitely something going wrong.
That observation seems correct. However, there are lot of non intuitive cases in the C preprocessor when the expansion is forbidden, like protection against endless recursive expansion. It thus may be also a bug in (*cpp).expand itself.
Edit: grammar
I've added an attempt to reproduce the error in https://github.com/cznic/sqlite2go/commit/4d9ae6c171f27b8e301ab8e672291c8781691e75.
Seems to work here:
~/src/github.com/cznic/sqlite2go/internal/ccgo> go test -v -run Other -cc -ccgo -build -re 10.c |& tee log2
=== RUN TestOther
--- PASS: TestOther (0.19s)
all_test.go:375: cc 1 ccgo 1 build 1 run 1 ok 1
PASS
ok github.com/cznic/sqlite2go/internal/ccgo 0.197s
~/src/github.com/cznic/sqlite2go/internal/ccgo>
I guess it fails during expansion because of the '{}' bug?
mingw_choose_expr ( __builtin_types_compatible__ ( ( typeof ( x ) ) { } , ( float ) { } ) , __isnanf ( x ) , __mingw_choose_expr ( __builtin_types_compatible__ ( ( typeof ( x ) ) { } , ( long double ) { } ) , __isnanl ( x ) , ( __builtin_trap ( ) , x ) ) )
Can you test:
extern int __isnan(double);
extern int __isnanf(float);
extern int __isnanl(long double);
#define __typeof__ typeof
#define __dfp_expansion(__call, __fin, x) __fin
#define __mingw_choose_expr __builtin_choose_expr
#define __mingw_types_compatible_p(type1, type2) __builtin_types_compatible_p ( type1 , type2 )
#define isnan(x) __mingw_choose_expr ( __mingw_types_compatible_p ( __typeof__ ( x ) , double ) , __isnan ( x ) , __mingw_choose_expr ( __mingw_types_compatible_p ( __typeof__ ( x ) , float ) , __isnanf ( x ) , __mingw_choose_expr ( __mingw_types_compatible_p ( __typeof__ ( x ) , long double ) , __isnanl ( x ) , __dfp_expansion ( __isnan , ( __builtin_trap ( ) , x ) , x ) ) ) )
?
Ofcourse with calling `isnan´.
That was very helpful, using https://github.com/cznic/sqlite2go/commit/072d9cad093a93e4fd41dcf6f7bef640af4f76f2 I can now get an error:
~/src/github.com/cznic/sqlite2go/internal/ccgo> go test -v -run Other -cc -ccgo -build -re 11.c -to |& tee log2
=== RUN TestOther
--- FAIL: TestOther (0.01s)
all_test.go:349: ../c99/testdata/bug/11.c: PANIC:
/home/jnml/src/github.com/cznic/sqlite2go/internal/ccgo/expr.go:398: TODO
../c99/testdata/bug/11.c:15:2: <nil> "__mingw_choose_expr"
github.com/cznic/sqlite2go/internal/ccgo.todo(0x70321f, 0x9, 0xc42031ee90, 0x3, 0x3)
/home/jnml/src/github.com/cznic/sqlite2go/internal/ccgo/etc.go:134 +0x3ec
github.com/cznic/sqlite2go/internal/ccgo.(*gen).value(0xc4203da000, 0xc4203bc5a0, 0x0)
/home/jnml/src/github.com/cznic/sqlite2go/internal/ccgo/expr.go:398 +0xa2c
github.com/cznic/sqlite2go/internal/ccgo.(*gen).void(0xc4203da000, 0xc4203bc5a0)
/home/jnml/src/github.com/cznic/sqlite2go/internal/ccgo/expr.go:77 +0x1994
github.com/cznic/sqlite2go/internal/ccgo.(*gen).void(0xc4203da000, 0xc4203bc690)
/home/jnml/src/github.com/cznic/sqlite2go/internal/ccgo/expr.go:192 +0x123
github.com/cznic/sqlite2go/internal/ccgo.(*gen).void(0xc4203da000, 0xc4203bc780)
/home/jnml/src/github.com/cznic/sqlite2go/internal/ccgo/expr.go:220 +0x245a
github.com/cznic/sqlite2go/internal/ccgo.(*gen).exprList(0xc4203da000, 0xc4203a9340, 0x1)
/home/jnml/src/github.com/cznic/sqlite2go/internal/ccgo/expr.go:29 +0x8a
all_test.go:375: cc 1 ccgo 0 build 0 run 0 ok 0
FAIL
exit status 1
FAIL github.com/cznic/sqlite2go/internal/ccgo 0.008s
~/src/github.com/cznic/sqlite2go/internal/ccgo>
Thanks, investigating the cause.
I think https://github.com/cznic/ccir/commit/56b415702bc97e73d7315cae6e3da9fd4c482cda fixes the problem. Please apply also https://github.com/cznic/sqlite2go/commit/6c3bf81ddaa3ac1b6345799fb33bbf830a34551d and test, thanks.
Edit: link
Even though it may work now, I'm not sure the fix is correct. I think (*cpp).expand is maybe wrong in this case. Have to consult the standard first.
Yeah it works. Now the fun begins with anonymous unions in structs, I hoped I wouldn't have to workaround that a second time :D
Regarding cpp:
~/tmp> cat main.c
#define a(b) b
#define c a
int main() {
__builtin_printf("%i\n", c(42));
}
~/tmp> cpp -std=c99 --pedantic main.c
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"
int main() {
__builtin_printf("%i\n", 42);
}
~/tmp>
It seems that function-like macro name should be replaced when used in non-call-like context. The standard seems to agree, https://www.spinellis.gr/blog/20060626/cpp.algo.pdf not so much, but that's what I based the implementation on.
Fix coming hopefully tomorrow.
Now the fun begins with anonymous unions in structs, I hoped I wouldn't have to workaround that a second time :D
Sorry to hear that. I suppose you're talking about generator.go
in 'ccir/libc', right?
Edit: grammar
Sorry to hear that. I suppose you're talking about generator.go in 'ccir/libc', right?
No nothing related to GO. The workaround introduced here: https://github.com/cznic/cc/commit/c6e08ea15fe7ab053b862aa36169efa2f3c3ecc4
for stuff like (couldn't find our discussion regarding that else I'd just link the same example I probably used back then):
typedef struct _OVERLAPPED {
ULONG_PTR Internal;
ULONG_PTR InternalHigh;
union {
struct {
DWORD Offset;
DWORD OffsetHigh;
};
PVOID Pointer;
};
HANDLE hEvent;
} OVERLAPPED;
...
OVERLAPPED test;
test.Offset = 42;
Ah, now I understand and even recall you've solved that. Good news are the C type system in sqlite2go/internal/c99 is now slightly better, I believe, compared to cznic/cc.
@steffengy Expansion of the mingw isnan
macro now seems to be working as intended.
Any pointers on how to best get the anonymous nested union stuff working?
The relevant places are: https://github.com/cznic/sqlite2go/blob/master/internal/c99/ast2.go#L637 https://github.com/cznic/sqlite2go/blob/master/internal/c99/ast2.go#L977
But I'm somehow confused by it going through scope to resolve fields insteadof iterating over the fields directly. Also I'm not quite sure if I'd need to adjust BitOffset or Offset in those cases, in CC I just used Offset and added to it recursively for every nested level of anonymous members, but Offset isn't even used for Select-Exprs (L637).
Already away from the computer today, I will take a look in the morning.
I think we don't need to calculate the offsets in C99 ast2.go. There we need only to check the field name exists. Offsets are calculated later in Model.Layout. (model.go).
Closed by mistake, I hate mobile UIs...
I was wrong, all is and must be computed in ast.go. I'll give it a try and report back in few hours regardless of the outcome.
@steffengy Please try https://github.com/cznic/sqlite2go/commit/6f364c284b320320564d686887eec89740cb1bd4 and let me know about any failing cases you will run into, thanks.
@cznic That panics with a null-deref on Declarator for
&{Bitoff:0 Bits:0 Declarator: Offset:0 PackedType:<nil> Padding:0 Size:8 Type:union{dwOemId DWORD;
struct{wProcessorArchitecture WORD; wReserved WORD}}}
Should that just use .Type
in general?
IDK, please post the failing C declaration source code for me to reproduce, thank you.
@cznic Yeah sure, sometimes forgetting you're no wizard either :)
#include <assert.h>
typedef struct _SYSTEM_INFO {
union {
int dwOemId;
struct {
int wProcessorArchitecture;
int wReserved;
};
};
int dwPageSize;
int lpMinimumApplicationAddress;
int lpMaximumApplicationAddress;
int dwActiveProcessorMask;
int dwNumberOfProcessors;
int dwProcessorType;
int dwAllocationGranularity;
int wProcessorLevel;
int wProcessorRevision;
} SYSTEM_INFO;
int main() {
SYSTEM_INFO sysinfo;
sysinfo.dwPageSize = 1;
}
@steffengy ;-)
Please try https://github.com/cznic/sqlite2go/commit/b23ed97182b8d6d152476acbd111ec14994a8f5c, thanks.
@cznic Seems to work, thanks!
Next very obscure error:
sqlite2go: *c99.cpp: PANIC: github.com\cznic\ccir\libc\errno.h:6:2: "( * _errno ( ) ).h" ["@" "gopath\\src\\github.com\\cznic\\ccir\\libc"]
github.com/cznic/sqlite2go/internal/c99.(*cpp).include(0xc04cbf3170, 0x6eae20, 0xc04d06ea50, 0xc04d043b00, 0x12, 0xc04cbe9a20, 0x2, 0x2, 0x6eab80, 0xc04cbbb1c0)
D:/projects/Go/gopath/src/github.com/cznic/sqlite2go/internal/c99/cpp.go:1068 +0x75d
github.com/cznic/sqlite2go/internal/c99.(*cpp).directive(0xc04cbf3170, 0x6ec420, 0xc04635ca20, 0x6eab80, 0xc04cbbb1c0, 0xc04d06e610, 0x2, 0x2, 0xc04d06e610, 0x2, ...)
D:/projects/Go/gopath/src/github.com/cznic/sqlite2go/internal/c99/cpp.go:1068
The panic line does not seems to be possible in commit https://github.com/cznic/sqlite2go/commit/b23ed97182b8d6d152476acbd111ec14994a8f5c.
Anyway it seems that instead of including eg. errno_windows_amd64.h
the program attempts to include some nonsense. Probably caused by another bug in cpp.go - invalid expansion of the __include
macro.
I think I had a similar problem on linux, see here. Can you please try the same hack with quoting the argument when _CCGO is defined? (in errno.h
)
FTR: The linux case was a valid expansion, but stat
was defined by some header file as a macro, like
#define stat stat64
causing
__include(sys/stat)
to expand to
#include "sys/stat64_linux_amd64"
// instead of the correct
#include "sys/stat_linux_amd64"
Making it conditional for _CCGO defined only is needed as old cznic/cc cannot handle the quoted string case.
@cznic I seem to be having an ordering issue with the preprocessor (possibly?):
typedef long long off64_t ;
_off64_t lseek64 (int fd ,_off64_t offset ,int whence );
long lseek (int _FileHandle ,long _Offset ,int _Origin );
#define lseek lseek64
might be enough to trigger it:
github.com/cznic/sqlite2go/internal/c99.(*Declarator).check(0xc04aef2dd0, 0xc04328c120, 0xc04fabe780, 0x6ee040, 0x6e7058, 0x561101, 0x0, 0x0, 0x0, 0x0, ...)
D:/projects/Go/gopath/src/github.com/cznic/sqlite2go/internal/c99/ast2.go:2176 +0xff5
github.com/cznic/sqlite2go/internal/c99.(*InitDeclarator).check(0xc04aef0b70, 0xc04328c120, 0xc04fabe780, 0x0, 0x0, 0x0, 0x0)
(type does not match declaration)
Just a few questions so I get this running on win: