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
Thanks to Cerise Limón for pointing me in the right direction:
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()
.