En Go's runtime/proc.go
, hay un código que se muestra a continuación:
// funcPC devuelve la PC de entrada de la función f.
// Se supone que f es un valor func. De lo contrario, el comportamiento es indefinido.
// CUIDADO: en programas con complementos, funcPC puede devolver diferentes valores
// para la misma función (porque en realidad hay múltiples copias de
// la misma función en el espacio de direcciones). Para estar seguro, no use los
// resultados de esta función en ninguna expresión ==. Solo es seguro
// usar el resultado como una dirección para comenzar a ejecutar el código.
//go:nosplit
func funcPC(f interface{}) uintptr {
return **(**uintptr)(add(unsafe.Pointer(&f), sys.PtrSize))
}
Lo que no entiendo es ¿por qué no usar * (* uintptr) en lugar de ** (** uintptr)?
Entonces escribo un programa de prueba a continuación para descubrir.
package main
import (
"fmt"
"unsafe"
)
func main(){
fmt.Println()
p := funcPC(test)
fmt.Println(p)
p1 := funcPC1(test)
fmt.Println(p1)
p2 := funcPC(test)
fmt.Println(p2)
}
func test(){
fmt.Println("hello")
}
func funcPC(f func()) uintptr {
return **(**uintptr)(unsafe.Pointer(&f))
}
func funcPC1(f func()) uintptr {
return *(*uintptr)(unsafe.Pointer(&f))
}
El resultado de que p no es igual a p1 me confunde. ¿Por qué el valor de p no es igual al valor de p1 mientras su tipo es el mismo?
funcPC(p)
sería el valor de . ¿Cuál es el punto de tener un puntero a un puntero de todos modos?
pp
apunta a p
, escribir a *pp
escribe p
y leer de *pp
lecturas de p
. Si p
está dentro del alcance, eso es, por supuesto, un poco tonto, ya que podría leer o escribir p
directamente. Pero, ¿qué p
pasa si no está dentro del alcance, o qué pasa si pp
apunta a cualquiera p
o q
(según la lógica anterior), y le gustaría usar o actualizar el puntero al que pp
apunta?