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?
ppapunta a p, escribir a *ppescribe py leer de *pplecturas de p. Si pestá dentro del alcance, eso es, por supuesto, un poco tonto, ya que podría leer o escribir pdirectamente. Pero, ¿qué ppasa si no está dentro del alcance, o qué pasa si ppapunta a cualquiera p o q (según la lógica anterior), y le gustaría usar o actualizar el puntero al que ppapunta?
