c++cairogladegtkmm3

gtkmm signal function must return "int"?


I'm in the process of writing a program that is supposed to display the Sierpinski triangle. To this end, I first created a demonstration for cairo, since I've never worked with cairo before; it just creates one line:

#include <glibmm.h>
#include <gtkmm.h>

Gtk::Window* W_Main;
Gtk::DrawingArea* D_Triangle;
Gtk::Button* B_Draw;
Gtk::Adjustment* A_Depth;

int on_D_Triangle_draw(const Cairo::RefPtr<Cairo::Context> cr) {
    cr->set_source_rgb(0.0, 0.0, 0.0);
    cr->set_line_width(4.0);
    cr->move_to(0, 0);
    cr->line_to(30, 30);
    cr->stroke();
    return 0;
}

int main(int argc, char** argv) {
    auto app = Gtk::Application::create(argc, argv, "org.CENSORED.sierpinski");
    
    auto builder = Gtk::Builder::create_from_file("sierpinski.glade");
    
    builder->get_widget("W_Main", W_Main);
    builder->get_widget("D_Triangle", D_Triangle);
    builder->get_widget("B_Draw", B_Draw);
    builder->get_widget("A_Depth", A_Depth);
    
    D_Triangle->signal_draw().connect(sigc::ptr_fun(on_D_Triangle_draw));
    
    app->run(*W_Main);
}

Now here's the odd thing: Apparently, the "on_D_Triangle_draw" function HAS TO return an integer! I first tried to make it a void function, but then the compiler returned a totally incomprehensible error message.

Can someone explain to me what is going on here? Further, is 0 the right value to return (in the sense of "best practice")?

EDIT: Here is the (very verbose) error message, as requested:

In file included from /usr/include/sigc++-2.0/sigc++/signal_base.h:27,
                 from /usr/include/sigc++-2.0/sigc++/signal.h:8,
                 from /usr/include/sigc++-2.0/sigc++/sigc++.h:123,
                 from /usr/include/glibmm-2.4/glibmm/thread.h:50,
                 from /usr/include/glibmm-2.4/glibmm.h:103,
                 from sierpinski.cpp:1:
/usr/include/sigc++-2.0/sigc++/functors/slot.h: In instantiation of ‘static T_return sigc::internal::slot_call1<T_functor, T_return, T_arg1>::call_it(sigc::internal::slot_rep*, sigc::type_trait_take_t<T_arg3>) [with T_functor = sigc::pointer_functor1<Cairo::RefPtr<Cairo::Context>, void>; T_return = bool; T_arg1 = const Cairo::RefPtr<Cairo::Context>&; sigc::type_trait_take_t<T_arg3> = const Cairo::RefPtr<Cairo::Context>&]’:
/usr/include/sigc++-2.0/sigc++/functors/slot.h:177:56:   required from ‘static void* (* sigc::internal::slot_call1<T_functor, T_return, T_arg1>::address())(void*) [with T_functor = sigc::pointer_functor1<Cairo::RefPtr<Cairo::Context>, void>; T_return = bool; T_arg1 = const Cairo::RefPtr<Cairo::Context>&; sigc::internal::hook = void* (*)(void*)]’
/usr/include/sigc++-2.0/sigc++/functors/slot.h:679:90:   required from ‘sigc::slot1<T_return, T_arg1>::slot1(const T_functor&) [with T_functor = sigc::pointer_functor1<Cairo::RefPtr<Cairo::Context>, void>; T_return = bool; T_arg1 = const Cairo::RefPtr<Cairo::Context>&]’
/usr/include/sigc++-2.0/sigc++/functors/slot.h:1843:26:   required from ‘sigc::slot<T_return, T_arg1, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil>::slot(const T_functor&) [with T_functor = sigc::pointer_functor1<Cairo::RefPtr<Cairo::Context>, void>; T_return = bool; T_arg1 = const Cairo::RefPtr<Cairo::Context>&]’
sierpinski.cpp:40:38:   required from here
/usr/include/sigc++-2.0/sigc++/functors/slot.h:170:16: error: void value not ignored as it ought to be
  169 |       return (typed_rep->functor_).SIGC_WORKAROUND_OPERATOR_PARENTHESES<type_trait_take_t<T_arg1>>
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  170 |                (a_1);
      |                ^~~~~

Solution

  • From the gtkm-3 documentation:

    Slot Prototype:
    bool on_my_draw(const ::Cairo::RefPtr< ::Cairo::Context>& cr)

    This signal is expected to return a value, either a bool or something convertible to bool. Returning int is acceptable, but void is not.

    Returns
    true to stop other handlers from being invoked for the event. false to propagate the event further.

    If you return zero (false), other handlers may be invoked. If you return non-zero (true), then no other handlers will be invoked. You can read the return value as "job done".