Maison  >  Article  >  développement back-end  >  Pourquoi le mélange de « println » et « fmt.Println » a-t-il un impact sur la croissance de la pile dans Go ?

Pourquoi le mélange de « println » et « fmt.Println » a-t-il un impact sur la croissance de la pile dans Go ?

DDD
DDDoriginal
2024-11-17 13:58:01392parcourir

Why Does Mixing `println` and `fmt.Println` Impact Stack Growth in Go?

Mélanger Println et Fmt.Println : Comprendre la croissance de la pile

Dans Go, la pile se développe dynamiquement pour s'adapter au stockage des variables et des arguments de fonction . Cependant, ce comportement peut être affecté lors de l'utilisation de différentes fonctions d'impression.

Considérons l'exemple suivant :

package main

import "fmt"

const size = 1024

func main() {
    fmt.Println("Start")
    s := "HELLO"
    stackCopy(&s, 0, [size]int{})
}

func stackCopy(s *string, c int, a [size]int) {
    println("println: ", s, *s)
    //fmt.Println("fmt:     ", s, *s)
    c++
    if c == 10 {
        return
    }
    stackCopy(s, c, a)
}

Lorsque seul println est utilisé, l'adresse de la chaîne s change à mesure que la pile grandit. :

Start
println:  0xc000107f58 HELLO
println:  0xc000117f58 HELLO
println:  0xc000117f58 HELLO

Cependant, lorsque fmt.Println est mélangé avec println, ou utilisé exclusivement, l'adresse de s reste la même :

Start
println:  0xc00010a040 HELLO
fmt:      0xc00010a040 HELLO
println:  0xc00010a040 HELLO
fmt:      0xc00010a040 HELLO

Comprendre la différence

La différence vient de la façon dont println et fmt.Println gèrent leurs arguments.

println est une fonction intégrée qui ne conserve aucun argument qui lui est transmis. En conséquence, les arguments ne s'échappent pas vers le tas et sont alloués sur la pile.

fmt.Println, en revanche, provient de la bibliothèque standard et est traitée comme une fonction personnalisée. Le compilateur ne suppose pas que fmt.Println ne conserve pas ses arguments, ils peuvent donc s'échapper vers le tas. Par conséquent, les arguments de fmt.Println sont alloués sur le tas au lieu de la pile.

Étant donné que la fonction stackCopy prend un argument volumineux ([size]int), la pile initiale peut devenir insuffisante et une plus grande sera attribué. Si les variables allouées sur la pile sont transmises comme arguments aux fonctions où elles peuvent s'échapper vers le tas, elles seront déplacées vers le tas à mesure que la pile grandit. C'est pourquoi nous observons le changement d'adresse des s lorsque seul println est utilisé.

Conclusion

Mélanger println et fmt.Println peut influencer la croissance de la pile en raison de la différence dans la façon dont ils gèrent leurs arguments. println conserve les arguments sur la pile, tandis que fmt.Println peut les allouer au tas, ce qui peut entraîner des modifications dans la disposition de la pile et les adresses des variables.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn