Re: [go-nuts] the defer list

2016-10-20 Thread andrew . smith
Yeah, thanks for that Konstantin. I have done something fairly similar, 
although all my objects support a Destroyable interface with one method 
Destroy(). However, I think your idea to closely mimic the defer list and 
simply push functions is much cleaner. The basic concept seems to work 
quite well so far and makes the wrapped functions pretty tidy at the 
expense of some efficiency I imagine. Ive also added a finalizer to the 
Stack so that in the (hopefully rare) case where the defer might be 
accidentally omitted, there is potentially a second chance to clean up.

On Thursday, October 20, 2016 at 3:46:00 PM UTC+1, Konstantin Khomoutov 
wrote:
>
> On Wed, 19 Oct 2016 15:35:40 -0700 (PDT) 
> andrew...@miracl.com  wrote: 
>
> [...] 
> > Im considering a scheme where I push every CString onto an 
> > implementation of a stack, and then call defer once. Im sure some 
> > people might think it overkill... Kinda like this : 
> > 
> > func Outer(arg1 string, arg2 string, arg3 string, arg4 string) Return 
> > { stack := NewStack() 
> > defer stack.Destroy() 
> > return wrapReturn( 
> > C.inner( 
> > NewStackCString(arg1, stack).p, 
> > NewStackCString(arg2, stack).p, 
> > NewStackCString(arg3, stack).p, 
> > NewStackCString(arg4, stack).p)) 
> > } 
> [...] 
>
> I think something like this should work in Go almost unmodified -- 
> just you won't have a system-provided "defer list", will have a single 
> deferred execution of stack.Destroy() and have your own implementation 
> of that stack type. 
>
> Something like this: 
>
> 8< 
> package main 
> 
> import "fmt" 
> 
> type dtor func() 
> 
> type cleanup struct { 
> dts []dtor 
> } 
> 
> func (c *cleanup) Add(d dtor) { 
> c.dts = append(c.dts, d) 
> } 
> 
> func (c *cleanup) Cleanup() { 
> for _, f := range c.dts { 
> f() 
> } 
> } 
> 
> type Foo struct{} 
> 
> func (f Foo) Close() { 
> fmt.Println("Foo.Close()") 
> } 
> 
> type Bar struct{} 
> 
> func (b Bar) CFree() { 
> fmt.Println("Bar.CFree()") 
> } 
> 
> func foo() { 
> var dts cleanup 
> defer dts.Cleanup() 
> 
> foo := Foo{} 
> dts.Add(foo.Close) 
> 
> bar := Bar{} 
> dts.Add(bar.CFree) 
> } 
> 
> func main() { 
> foo() 
> } 
> 8< 
>
> (Playground link: https://play.golang.org/p/TqCfBfZb_X). 
>
>
> BTW I found myself doing something much like this in some of my C# 
> projects to avoid nesting hell of 
>
>   using (...acquire resource...) { 
> using (...acquire resource...) { 
>   ...etc ad nauseum 
>   } 
>
> whereas you have a stack-like data type which implements IDisposable, 
> and you just have a single using() { ... } block for it inside which 
> you add particular resources to be destroyed to that instance, and at 
> the end of the block it's told to destroy itself and then it destroys 
> whatever resources have been added to it. 
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-20 Thread Konstantin Khomoutov
On Wed, 19 Oct 2016 15:35:40 -0700 (PDT)
andrew.sm...@miracl.com wrote:

[...]
> Im considering a scheme where I push every CString onto an
> implementation of a stack, and then call defer once. Im sure some
> people might think it overkill... Kinda like this :
> 
> func Outer(arg1 string, arg2 string, arg3 string, arg4 string) Return
> { stack := NewStack()
> defer stack.Destroy()
> return wrapReturn(
> C.inner(
> NewStackCString(arg1, stack).p,
> NewStackCString(arg2, stack).p,
> NewStackCString(arg3, stack).p,
> NewStackCString(arg4, stack).p))
> }
[...]

I think something like this should work in Go almost unmodified --
just you won't have a system-provided "defer list", will have a single
deferred execution of stack.Destroy() and have your own implementation
of that stack type.

Something like this:

8<
package main

import "fmt"

type dtor func()

type cleanup struct {
dts []dtor
}

func (c *cleanup) Add(d dtor) {
c.dts = append(c.dts, d)
}

func (c *cleanup) Cleanup() {
for _, f := range c.dts {
f()
}
}

type Foo struct{}

func (f Foo) Close() {
fmt.Println("Foo.Close()")
}

type Bar struct{}

func (b Bar) CFree() {
fmt.Println("Bar.CFree()")
}

func foo() {
var dts cleanup
defer dts.Cleanup()

foo := Foo{}
dts.Add(foo.Close)

bar := Bar{}
dts.Add(bar.CFree)
}

func main() {
foo()
}
8<

(Playground link: https://play.golang.org/p/TqCfBfZb_X).


BTW I found myself doing something much like this in some of my C#
projects to avoid nesting hell of

  using (...acquire resource...) {
using (...acquire resource...) {
  ...etc ad nauseum
  }

whereas you have a stack-like data type which implements IDisposable,
and you just have a single using() { ... } block for it inside which
you add particular resources to be destroyed to that instance, and at
the end of the block it's told to destroy itself and then it destroys
whatever resources have been added to it.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-19 Thread andrew . smith
Thanks for the advice. Im fairly new to golang, but Im used to the 
guarantees of C++ destructors. I think defer is a great thing and similar 
to the scope guard idiom. I dont think Im trying to fight the language, 
just trying to see if there is a way to protect myself from stupid mistakes 
that are very hard to detect in unit tests as well as in a production 
environment.

Im considering a scheme where I push every CString onto an implementation 
of a stack, and then call defer once. Im sure some people might think it 
overkill... Kinda like this :

func Outer(arg1 string, arg2 string, arg3 string, arg4 string) Return {
stack := NewStack()
defer stack.Destroy()
return wrapReturn(
C.inner(
NewStackCString(arg1, stack).p,
NewStackCString(arg2, stack).p,
NewStackCString(arg3, stack).p,
NewStackCString(arg4, stack).p))
}

Thanks again for the input,

Andy

On Wednesday, October 19, 2016 at 9:47:09 PM UTC+1, Pietro Gagliardi 
(andlabs) wrote:
>
> Manual memory management is a part of life in the C world. defer is the 
> solution that Go comes up with to situations where explicit cleanup is 
> necessary, and it's a powerful tool that I'm pretty sure *is* an innovation 
> Go did first. If you just follow the idiom
>
> cstr := C.CString(str)
> defer C.free(unsafe.Pointer(cstr))
>
> with nothing in between those two lines, then you won't have to worry 
> about whether something gets cleaned up every time, because the answer is 
> yes, it *will* get cleaned up every time! It's not like C anymore where you 
> have to worry about making sure every code path frees only what is 
> allocated on that code path, which means either juggling gotos or 
> infinitely nesting ifs and possibly NULL checks everywhere.
>
> Stop trying to fight the language; start using it.
>
> If you are really prone to forgetting to free something somewhere, write a 
> program using the go/... packages to do static analysis and evaluate the 
> lifetime of C objects for yourself.
>
> On Oct 19, 2016, at 4:22 PM, andrew...@miracl.com  wrote:
>
> I thought someone might ask! Im writing many wrapper functions to C 
> functions that take multiple C.char* arguments. All of these require a call 
> to C.free() before the wrapper function terminates. I can do this with 
> defer but Im absolutely sure Im going to miss one or more of these out. So 
> I was wondering, if I could get hold of the defer list, then I could 
> encapsulate the construction together with the defer in a function.
>
> e.g. roughly :
>
> func NewCString(s string, deferList List) *C.char {
>cs := C.CString(s)
>deferList.PushBack(func() { C.free(cs) }
>return cs
> }
>
> Then in an *imagined world* I could write my wrapper simply as :
>
> func wrapper(s1 string, s2 string, s3 string) {
>   deferList := runtime.DeferList()
>   return C.inner(NewCString(s1,deferList), NewCString(s2,deferList), 
> NewCString(s2,deferList))
> }
>
> Basically, I cant seem to find a clean solution to ensure all these 
> C.char* are 100% freed... swig allows me to wrap the C.char* with string, 
> but swig is pretty awkward to use especially when wrapping the libraries I 
> have. Im currently preferring cgo which seems much simpler and cleaner, but 
> I dont have the equivalent of swigs typemaps to ensure all allocs are 
> correctly freed... :o(
>
>
>
> On Wednesday, October 19, 2016 at 8:41:25 PM UTC+1, Pietro Gagliardi 
> (andlabs) wrote:
>>
>> What do you want to do with it?
>>
>> On Oct 19, 2016, at 3:31 PM, andrew...@miracl.com wrote:
>>
>> Hi,
>>
>> This is probably a long shot, but is it possible to get a reference to 
>> the list of functions that the 'defer' statement populates? Is it exposed 
>> and/or is it specific?
>>
>> Andy
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts...@googlegroups.com .
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-19 Thread 'Thomas Bushnell, BSG' via golang-nuts
Ah, yes, that's true indeed.

On Wed, Oct 19, 2016 at 2:33 PM adonovan via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> On Wednesday, 19 October 2016 16:50:55 UTC-4, Thomas Bushnell, BSG wrote:
>
> On Wed, Oct 19, 2016 at 1:47 PM Pietro Gagliardi 
> wrote:
>
> Manual memory management is a part of life in the C world. defer is the
> solution that Go comes up with to situations where explicit cleanup is
> necessary, and it's a powerful tool that I'm pretty sure *is* an innovation
> Go did first.
>
>
> Oh my, no. It's a wonderful thing, but it's essentially equivalent to
> Lisp's UNWIND-PROTECT or (in the outward case) Scheme's dynamic-wind.
>
>
> Unwind-protect and the better known but equivalent try/finally both
> operate at the level of balanced lexical blocks: expressions in Lisp,
> statement blocks in Java or C++.  In contrast, defer operates at the
> function level and requires a dynamic stack, and in that sense it is novel,
> but I can't think of a single time I've actually wanted to defer an action
> beyond the point when try/finally would have executed it.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-19 Thread adonovan via golang-nuts
On Wednesday, 19 October 2016 16:50:55 UTC-4, Thomas Bushnell, BSG wrote:
>
> On Wed, Oct 19, 2016 at 1:47 PM Pietro Gagliardi  > wrote:
>
>> Manual memory management is a part of life in the C world. defer is the 
>> solution that Go comes up with to situations where explicit cleanup is 
>> necessary, and it's a powerful tool that I'm pretty sure *is* an innovation 
>> Go did first.
>>
>
> Oh my, no. It's a wonderful thing, but it's essentially equivalent to 
> Lisp's UNWIND-PROTECT or (in the outward case) Scheme's dynamic-wind.
>

Unwind-protect and the better known but equivalent try/finally both operate 
at the level of balanced lexical blocks: expressions in Lisp, statement 
blocks in Java or C++.  In contrast, defer operates at the function level 
and requires a dynamic stack, and in that sense it is novel, but I can't 
think of a single time I've actually wanted to defer an action beyond the 
point when try/finally would have executed it.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-19 Thread 'Thomas Bushnell, BSG' via golang-nuts
On Wed, Oct 19, 2016 at 1:47 PM Pietro Gagliardi 
wrote:

> Manual memory management is a part of life in the C world. defer is the
> solution that Go comes up with to situations where explicit cleanup is
> necessary, and it's a powerful tool that I'm pretty sure *is* an innovation
> Go did first.
>

Oh my, no. It's a wonderful thing, but it's essentially equivalent to
Lisp's UNWIND-PROTECT or (in the outward case) Scheme's dynamic-wind.

Thomas




> If you just follow the idiom
>
> cstr := C.CString(str)
> defer C.free(unsafe.Pointer(cstr))
>
> with nothing in between those two lines, then you won't have to worry
> about whether something gets cleaned up every time, because the answer is
> yes, it *will* get cleaned up every time! It's not like C anymore where you
> have to worry about making sure every code path frees only what is
> allocated on that code path, which means either juggling gotos or
> infinitely nesting ifs and possibly NULL checks everywhere.
>
> Stop trying to fight the language; start using it.
>
> If you are really prone to forgetting to free something somewhere, write a
> program using the go/... packages to do static analysis and evaluate the
> lifetime of C objects for yourself.
>
> On Oct 19, 2016, at 4:22 PM, andrew.sm...@miracl.com wrote:
>
> I thought someone might ask! Im writing many wrapper functions to C
> functions that take multiple C.char* arguments. All of these require a call
> to C.free() before the wrapper function terminates. I can do this with
> defer but Im absolutely sure Im going to miss one or more of these out. So
> I was wondering, if I could get hold of the defer list, then I could
> encapsulate the construction together with the defer in a function.
>
> e.g. roughly :
>
> func NewCString(s string, deferList List) *C.char {
>cs := C.CString(s)
>deferList.PushBack(func() { C.free(cs) }
>return cs
> }
>
> Then in an *imagined world* I could write my wrapper simply as :
>
> func wrapper(s1 string, s2 string, s3 string) {
>   deferList := runtime.DeferList()
>   return C.inner(NewCString(s1,deferList), NewCString(s2,deferList),
> NewCString(s2,deferList))
> }
>
> Basically, I cant seem to find a clean solution to ensure all these
> C.char* are 100% freed... swig allows me to wrap the C.char* with string,
> but swig is pretty awkward to use especially when wrapping the libraries I
> have. Im currently preferring cgo which seems much simpler and cleaner, but
> I dont have the equivalent of swigs typemaps to ensure all allocs are
> correctly freed... :o(
>
>
>
> On Wednesday, October 19, 2016 at 8:41:25 PM UTC+1, Pietro Gagliardi
> (andlabs) wrote:
>
> What do you want to do with it?
>
> On Oct 19, 2016, at 3:31 PM, andrew...@miracl.com wrote:
>
> Hi,
>
> This is probably a long shot, but is it possible to get a reference to the
> list of functions that the 'defer' statement populates? Is it exposed
> and/or is it specific?
>
> Andy
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-19 Thread Pietro Gagliardi
All right then. Good to know, thanks.
> On Oct 19, 2016, at 4:50 PM, Thomas Bushnell, BSG  
> wrote:
> 
> On Wed, Oct 19, 2016 at 1:47 PM Pietro Gagliardi  > wrote:
> Manual memory management is a part of life in the C world. defer is the 
> solution that Go comes up with to situations where explicit cleanup is 
> necessary, and it's a powerful tool that I'm pretty sure *is* an innovation 
> Go did first.
> 
> Oh my, no. It's a wonderful thing, but it's essentially equivalent to Lisp's 
> UNWIND-PROTECT or (in the outward case) Scheme's dynamic-wind.
> 
> Thomas
> 
> 
>  
> If you just follow the idiom
> 
>   cstr := C.CString(str)
>   defer C.free(unsafe.Pointer(cstr))
> 
> with nothing in between those two lines, then you won't have to worry about 
> whether something gets cleaned up every time, because the answer is yes, it 
> *will* get cleaned up every time! It's not like C anymore where you have to 
> worry about making sure every code path frees only what is allocated on that 
> code path, which means either juggling gotos or infinitely nesting ifs and 
> possibly NULL checks everywhere.
> 
> Stop trying to fight the language; start using it.
> 
> If you are really prone to forgetting to free something somewhere, write a 
> program using the go/... packages to do static analysis and evaluate the 
> lifetime of C objects for yourself.
> 
>> On Oct 19, 2016, at 4:22 PM, andrew.sm...@miracl.com 
>>  wrote:
>> 
>> I thought someone might ask! Im writing many wrapper functions to C 
>> functions that take multiple C.char* arguments. All of these require a call 
>> to C.free() before the wrapper function terminates. I can do this with defer 
>> but Im absolutely sure Im going to miss one or more of these out. So I was 
>> wondering, if I could get hold of the defer list, then I could encapsulate 
>> the construction together with the defer in a function.
>> 
>> e.g. roughly :
>> 
>> func NewCString(s string, deferList List) *C.char {
>>cs := C.CString(s)
>>deferList.PushBack(func() { C.free(cs) }
>>return cs
>> }
>> 
>> Then in an *imagined world* I could write my wrapper simply as :
>> 
>> func wrapper(s1 string, s2 string, s3 string) {
>>   deferList := runtime.DeferList()
>>   return C.inner(NewCString(s1,deferList), NewCString(s2,deferList), 
>> NewCString(s2,deferList))
>> }
>> 
>> Basically, I cant seem to find a clean solution to ensure all these C.char* 
>> are 100% freed... swig allows me to wrap the C.char* with string, but swig 
>> is pretty awkward to use especially when wrapping the libraries I have. Im 
>> currently preferring cgo which seems much simpler and cleaner, but I dont 
>> have the equivalent of swigs typemaps to ensure all allocs are correctly 
>> freed... :o(
>> 
>> 
>> 
>> On Wednesday, October 19, 2016 at 8:41:25 PM UTC+1, Pietro Gagliardi 
>> (andlabs) wrote:
>> What do you want to do with it?
>> 
>>> On Oct 19, 2016, at 3:31 PM, andrew...@miracl.com <> wrote:
>>> 
>>> Hi,
>>> 
>>> This is probably a long shot, but is it possible to get a reference to the 
>>> list of functions that the 'defer' statement populates? Is it exposed 
>>> and/or is it specific?
>>> 
>>> Andy
>>> 
>>> -- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>> email to golang-nuts...@googlegroups.com <>.
>>> For more options, visit https://groups.google.com/d/optout 
>>> .
>> 
>> 
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts+unsubscr...@googlegroups.com 
>> .
>> For more options, visit https://groups.google.com/d/optout 
>> .
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com 
> .
> For more options, visit https://groups.google.com/d/optout 
> .

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-19 Thread Pietro Gagliardi
Manual memory management is a part of life in the C world. defer is the 
solution that Go comes up with to situations where explicit cleanup is 
necessary, and it's a powerful tool that I'm pretty sure *is* an innovation Go 
did first. If you just follow the idiom

cstr := C.CString(str)
defer C.free(unsafe.Pointer(cstr))

with nothing in between those two lines, then you won't have to worry about 
whether something gets cleaned up every time, because the answer is yes, it 
*will* get cleaned up every time! It's not like C anymore where you have to 
worry about making sure every code path frees only what is allocated on that 
code path, which means either juggling gotos or infinitely nesting ifs and 
possibly NULL checks everywhere.

Stop trying to fight the language; start using it.

If you are really prone to forgetting to free something somewhere, write a 
program using the go/... packages to do static analysis and evaluate the 
lifetime of C objects for yourself.

> On Oct 19, 2016, at 4:22 PM, andrew.sm...@miracl.com wrote:
> 
> I thought someone might ask! Im writing many wrapper functions to C functions 
> that take multiple C.char* arguments. All of these require a call to C.free() 
> before the wrapper function terminates. I can do this with defer but Im 
> absolutely sure Im going to miss one or more of these out. So I was 
> wondering, if I could get hold of the defer list, then I could encapsulate 
> the construction together with the defer in a function.
> 
> e.g. roughly :
> 
> func NewCString(s string, deferList List) *C.char {
>cs := C.CString(s)
>deferList.PushBack(func() { C.free(cs) }
>return cs
> }
> 
> Then in an *imagined world* I could write my wrapper simply as :
> 
> func wrapper(s1 string, s2 string, s3 string) {
>   deferList := runtime.DeferList()
>   return C.inner(NewCString(s1,deferList), NewCString(s2,deferList), 
> NewCString(s2,deferList))
> }
> 
> Basically, I cant seem to find a clean solution to ensure all these C.char* 
> are 100% freed... swig allows me to wrap the C.char* with string, but swig is 
> pretty awkward to use especially when wrapping the libraries I have. Im 
> currently preferring cgo which seems much simpler and cleaner, but I dont 
> have the equivalent of swigs typemaps to ensure all allocs are correctly 
> freed... :o(
> 
> 
> 
> On Wednesday, October 19, 2016 at 8:41:25 PM UTC+1, Pietro Gagliardi 
> (andlabs) wrote:
> What do you want to do with it?
> 
>> On Oct 19, 2016, at 3:31 PM, andrew...@miracl.com  wrote:
>> 
>> Hi,
>> 
>> This is probably a long shot, but is it possible to get a reference to the 
>> list of functions that the 'defer' statement populates? Is it exposed and/or 
>> is it specific?
>> 
>> Andy
>> 
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout 
>> .
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com 
> .
> For more options, visit https://groups.google.com/d/optout 
> .

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-19 Thread andrew . smith
I thought someone might ask! Im writing many wrapper functions to C 
functions that take multiple C.char* arguments. All of these require a call 
to C.free() before the wrapper function terminates. I can do this with 
defer but Im absolutely sure Im going to miss one or more of these out. So 
I was wondering, if I could get hold of the defer list, then I could 
encapsulate the construction together with the defer in a function.

e.g. roughly :

func NewCString(s string, deferList List) *C.char {
   cs := C.CString(s)
   deferList.PushBack(func() { C.free(cs) }
   return cs
}

Then in an *imagined world* I could write my wrapper simply as :

func wrapper(s1 string, s2 string, s3 string) {
  deferList := runtime.DeferList()
  return C.inner(NewCString(s1,deferList), NewCString(s2,deferList), 
NewCString(s2,deferList))
}

Basically, I cant seem to find a clean solution to ensure all these C.char* 
are 100% freed... swig allows me to wrap the C.char* with string, but swig 
is pretty awkward to use especially when wrapping the libraries I have. Im 
currently preferring cgo which seems much simpler and cleaner, but I dont 
have the equivalent of swigs typemaps to ensure all allocs are correctly 
freed... :o(



On Wednesday, October 19, 2016 at 8:41:25 PM UTC+1, Pietro Gagliardi 
(andlabs) wrote:
>
> What do you want to do with it?
>
> On Oct 19, 2016, at 3:31 PM, andrew...@miracl.com  wrote:
>
> Hi,
>
> This is probably a long shot, but is it possible to get a reference to the 
> list of functions that the 'defer' statement populates? Is it exposed 
> and/or is it specific?
>
> Andy
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts...@googlegroups.com .
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-19 Thread andrew . smith
I thought you might Im writing many wrapper functions to C functions that 
take multiple C.char*. All of these require a defer statement to free the C 
string when the wrapper function terminates. Im absolutely sure Im going to 
miss one or more of these out, so I was wondering if I could get hold of 
the defer list, then I could encapsulate the construction with the defer in 
a function.

e.g. roughly :

func NewCString(s string, deferList List) *C.char {
   cs := C.CString(s)
   deferList.PushBack(func() { C.free(cs) }
   return cs
}

Then in an *imagined world* I could write my wrapper simply as :

func wrapper(s1 string, s2 string, s3 string) {
  deferList := runtime.DeferList()
  return C.inner(NewCString(s1,deferList), NewCString(s2,deferList), 
NewCString(s2,deferList))
}

Basically, I cant seem to find a clean solution to ensure all these C.char* 
are 100% freed... swig allows me to wrap the C.char* with string, but swig 
is pretty awkward to use especially when wrapping the libraries I have. Im 
currently preferring cgo which seems much simpler and cleaner, but I dont 
have the equivalent of swigs typemaps to ensure all allocs are correctly 
freed... :o(





On Wednesday, October 19, 2016 at 8:41:25 PM UTC+1, Pietro Gagliardi 
(andlabs) wrote:
>
> What do you want to do with it?
>
> On Oct 19, 2016, at 3:31 PM, andrew...@miracl.com  wrote:
>
> Hi,
>
> This is probably a long shot, but is it possible to get a reference to the 
> list of functions that the 'defer' statement populates? Is it exposed 
> and/or is it specific?
>
> Andy
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts...@googlegroups.com .
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-19 Thread andrew . smith
I thought you might Im writing many wrapper functions to C functions that 
take multiple C.char*. All of these require a defer statement to free the C 
string when the wrapper function terminates. Im absolutely sure Im going to 
miss one or more of these out, so I was wondering if I could get hold of 
the defer list, then I could encapsulate the construction with the defer in 
a function.

e.g. roughly :

func NewCString(s string, deferList List) *C.char {
   cs := C.CString(s)
   deferList.PushBack(func() { C.free(cs) }
return cs
}

Then in an imagined world I could write my wrapper as :

func wrapper(s1 string, s2 string, s3 string) {
  deferList := runtime.DeferList()
  return C.inner(NewCString(s1,deferList)
}


On Wednesday, October 19, 2016 at 8:41:25 PM UTC+1, Pietro Gagliardi 
(andlabs) wrote:
>
> What do you want to do with it?
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-19 Thread Ian Lance Taylor
On Wed, Oct 19, 2016 at 12:31 PM,   wrote:
>
> This is probably a long shot, but is it possible to get a reference to the
> list of functions that the 'defer' statement populates? Is it exposed and/or
> is it specific?

The list is not available.

Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] the defer list

2016-10-19 Thread Pietro Gagliardi
What do you want to do with it?

> On Oct 19, 2016, at 3:31 PM, andrew.sm...@miracl.com wrote:
> 
> Hi,
> 
> This is probably a long shot, but is it possible to get a reference to the 
> list of functions that the 'defer' statement populates? Is it exposed and/or 
> is it specific?
> 
> Andy
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com 
> .
> For more options, visit https://groups.google.com/d/optout 
> .

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] the defer list

2016-10-19 Thread andrew . smith
Hi,

This is probably a long shot, but is it possible to get a reference to the 
list of functions that the 'defer' statement populates? Is it exposed 
and/or is it specific?

Andy

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.