Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the pointer of return value from function call?

Tags:

pointers

go

I just need a pointer to time.Time, so the code below seems invalid:

./c.go:5: cannot take the address of time.Now()

I just wonder why? Is there any way to do that except to do assignment to a variable first and take the pointer of the variable?

package main  import "time" func main() {     _ = &time.Now() } 
like image 546
Meng Avatar asked Jun 10 '15 00:06

Meng


People also ask

How do you return a value from a pointer in C++?

To get the value pointed to by a pointer, you need to use the dereferencing operator * (e.g., if pNumber is a int pointer, *pNumber returns the value pointed to by pNumber . It is called dereferencing or indirection).

Can we declare a function that can return a pointer to a function of the same type?

You cannot return a function in C - you return a pointer to a function. If you mean to define a function which returns a pointer to a function which again returns a pointer to a function and so on, then you can use typedef to implement it.


2 Answers

The probably unsatisfying answer is "you can't do it because the spec says so." The spec says that to use & on something it has to be addressable or a compound literal, and to be addressable it has to be "a variable, pointer indirection, or slice indexing operation; or a a field selector of an addressable struct operand; or an array indexing operation of an addressable array." Function calls and method calls are definitely not on the list.

Practically speaking, it's probably because the return value of a function may not have a usable address; it may be in a register (in which case it's definitely not addressable) or on the stack (in which case it has an address, but one that won't be valid if it's put in a pointer that escapes the current scope. To guarantee addressability, Go would have to do pretty much the exact equivalent of assigning it to a variable. But Go is the kind of language that figures that if it's going to allocate storage for a variable it's going to be because you said to, not because the compiler magically decided to. So it doesn't make the result of a function addressable.

Or I could be over-thinking it and they simply didn't want to have a special case for functions that return one value versus functions that return multiple :)

like image 75
hobbs Avatar answered Sep 27 '22 18:09

hobbs


You can't directly take the address of a function call (or more precisely the return value(s) of the function) as described by hobbs.

There is another way but it is ugly:

p := &[]time.Time{time.Now()}[0] fmt.Printf("%T %p\n%v", p, p, *p) 

Output (Go Playground):

*time.Time 0x10438180 2009-11-10 23:00:00 +0000 UTC 

What happens here is a struct is created with a literal, containing one element (the return value of time.Now()), the slice is indexed (0th element) and the address of the 0th element is taken.

So rather just use a local variable:

t := time.Now() p := &t 

Or a helper function:

func ptr(t time.Time) *time.Time {     return &t }  p := ptr(time.Now()) 

Which can also be a one-liner anonymous function:

p := func() *time.Time { t := time.Now(); return &t }() 

Or as an alternative:

p := func(t time.Time) *time.Time { return &t }(time.Now()) 

For even more alternatives, see:

How do I do a literal *int64 in Go?

Also see related question: How can I store reference to the result of an operation in Go?

like image 31
icza Avatar answered Sep 27 '22 20:09

icza