Search code examples
gogtkgtk3init

Why are goGTK widgets not initialized in the init() function?


I am using Go 1.21.4 on a Windows 11 Pro machine and GTK 3 binding for Go.

Simple sample code:

package GTKView

import (

    "github.com/gotk3/gotk3/gtk"
)

var mToolbar *gtk.Toolbar

func initGtkWidgets() {

    mToolbar, _ = gtk.ToolbarNew()

}

func InitGUI(Win *gtk.Window, fp func(*gtk.TextBuffer)) {

    initGtkWidgets()
    mToolbar.SetHAlign(gtk.ALIGN_START)

}

This code works: InitGUI() is called from main() to initialize the GTK GUI. mToolbar is initialized with the call to initGtkWidgets() , and mToolbar.SetHAlign executes properly.

However, the following code, relying on init() to initialize mToolbar, compiles, but fails at runtime with a string of errors and memory addresses, apparently because mToolbar was not initialized by init() when InitGUI() was called from main() .

package GTKView

import (

    "github.com/gotk3/gotk3/gtk"
)

var mToolbar *gtk.Toolbar

func init() {

    mToolbar, _ = gtk.ToolbarNew()

}

func InitGUI(Win *gtk.Window, fp func(*gtk.TextBuffer)) {

    mToolbar.SetHAlign(gtk.ALIGN_START)
 
}

I come from a C++ and Object Pascal background. 
My understanding is that Go's `init()` 
is similar to the `initialization` section of an Object Pascal unit: 
Runs once, automatically, before code in the unit itself is called, 
and it's possible to initialize exposed variables in the `initialization` section.

Why aren't widgets initialized properly in Go, using `init()`?

  [1]: https://en.wikipedia.org/wiki/Windows_11
  [2]: https://en.wikipedia.org/wiki/Embarcadero_Delphi
  [3]: https://en.wikipedia.org/wiki/Object_Pascal



Solution

  • Thanks to Cerise Limón for pointing me in the right direction:

    Package initialization

    More precisely, a package-level variable is considered ready for initialization if it is not yet initialized and either has no initialization expression or its initialization expression has no dependencies on uninitialized variables.

    The GTK widgets are written in C, and in their constructors the widgets are initialized using pointers with the new operator. Although the documentation refers to initialization expressions outside of init(), it appears that the GTK widgets. although they are included in init(), are also not ready for initialization because of dependencies on uninitialized variables, and were not initialized in the call to InitGUI() when relying on init().