Re: turning g_assert* into warnings


Why not introduce a new check, some g_check_stuff() which would
do what you propose? And let g_assert() be what it is, a glib analog
of C assert(). When an assertion fails, you can't possibly expect the
code to function in any meaningful way, e.g.

int idx;
g_assert (idx >= 0);
array[idx] = 8;

you get segfault or worse here if g_assert() above fails to bring program
down, you simply can't change g_assert() now to behave in such a
different way.
Often you indeed can do sensible things after some important assumption
happened to be false, and in those situations a new check would be really cool
(where existing code does manual checks like
if (bad) {g_critical ("oops"); emergency_return_or_whatever();} ).
But it should be a programmer decision, and it's just not acceptable
to change behavior of existing code.

Best regards,

Tim Janik wrote:
hey All.

i'd like to propose to turn g_assert and friends like g_assert_not_reached
into warnings instead of errors. i'll give a bit of background before the
details though.

the main reasons we use g_return_if_fail massively throughout the glib and
gtk+ code base is that it catches API misuses verbosely and gives programmers
a chance to fix their code. this could be achieved with either a g_warning
(mourn on stderr) or a g_error (mourn and abort).

the reasons for the default behavior to use g_warning:
a) a warning usually fullfills its purpose, the programmer knows there's
    something to fix and can start to trace the root cause.
b) for easy tracing in gdb with backtraces, programmers can use
    --g-fatal-warnings to force abort behavior.
c) programs that aren't 100% bug free could possibly trigger these warnings
    during production. aborting would take all the end user data with it,
    created/modified images, text documents, etc.
    issuing just a warnig preserves the possibility to still save crucial
    data if the application logic state still permits (which is most often
    the case in practice).

in a recent discussion, i figured that (c) perfectly applies to g_assert
and g_assert_if_reached() also. but we're actually aborting here:
   g_assert_warning ([...])
     abort ();

i'd like to change that to:

   g_assert_warning ([...])
-   abort ();
+   if (--g-fatal-warninngs)
+     abort ();

for a few reasons:
1) allow users to save their data if still possible; i.e. (c) from above.
2) for glib/gtk+ unit tests (more on that later), failing but
    non-aborting tests are interesting for overall report generation; and the
    ability to force immediate aborts for debugging is preserved with
3) assertions can help to document programmer intentions and frequent (but
    regulated) use as we have it with g_return_if_fail can significantly
    reduce debugging time. i have so far been fairly strict about not adding
    assertions to the glib/gtk+ core though, because they also tend to make
    the code and end-user experiences more brittle, especially an
    occasional wrong assertions that'd have to be revoked upon closer
    conditionalizing the abort removes the brittleness and allows for
    adding more helpful assertion statements.

note that in practice, this shouldn't change anything for programmers
(except for the ability to write better code ;)
because of G_DISABLE_ASSERT, programmers can already not rely on
failing assertions to abort their programs (only g_error will reliably
do that).
it should however take down programs in end user scenarios less often,
and code review can be more lax about adding assertions.

as a side note, it'd probably make sense to present the end users with more
prominent warnings if one of his applications ran into a glib warning/
critical/assertion, and he should be notified about needing to save
his data and exit ASAP. but that's really another topic, probably
best tackled by gnome.

comments welcome and thanks for the interest.

gtk-devel-list mailing list
gtk-devel-list gnome org

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]