C API, switch to `bool`?

It all smells a bit messy :frowning: After all, we are not talking about a lot of functions if we consider the groups with consistent naming ā€œdoneā€, no? WUNUSED also gives a clue, though I see quite a few more functions should have it. That could be fixed.

Iā€™m not against, but I start getting the impression this is getting ugly and of limited value :frowning:

Not sure. Janus is surely a lot more powerful and also faster, but pyswip can be used withour compiling anything, so it can be easier to install for Python users (depending on platform, etc.)

The PL_is_*() functions are consistent (and obvious); but the rest arenā€™t (e.g., some PL_put_*() canā€™t return an error and some can).

Hereā€™s the breakdown (according to the mark-up I did in SWI-cpp2-plx.h, which could be slightly wrong):

  • 142 ā€œas-isā€ (of which 52 are for bool)
  • 62 - false is an error
  • 62 - false is failure or an error
  • 29 - no return code

(I havenā€™t updated SWI-cpp2-plx.h with the latest changes from int to bool, so I canā€™t give a breakdown of error for bool and not-bool)

In addition, there some difficult to describe situation, such as that PL_new_term_ref() and PL_new_term_refs() can be called up to 10 times without checking the return code.If PL_new_term_ref() is marked WUNUSED, then the compiler can be quietened by (void)PL_new_term_ref(...)

Any PL_put_*() that can return an error is annotated with WUNUSED. At least, that is the theory.

Only in particular scenarios. For C++ Iā€™d just check. That is mainly there for simplifying hand written code.

As PL_new_term_ref() returns a value you need, leaving it unused is rather unlikely. I guess we can safely mark it using WUNUSED, but I see little added value. What us critical is that it has a special return value (0) to indicate the error value. That is the case with many other functions, typically returning NULL for pointers in case of error and some negative value for functions returning int. Would adding something as ONERROR(Value) help?

I wasnā€™t thinking straight when I wrote that. (But ā€“ as a general rule ā€“ (void) cast can be used to turn off a WUNUSED warning)

I remember seeing some code that called PL_new_term_ref() and didnā€™t check that the result was non-zero ā€“ this was because it was guaranteed that at least 10 new terms could be allocated. And it allows more compact code (and eliminates a test), although it could be written

term_t t1, t2;
if ((t1=PL_new_term_ref()) && (t2=PL_new_term_ref()))

For C++, it can be written

PlTerm_var t1, t2;

and thereā€™s always a check, which can throw a C++ exception if it fails.

Nope. Try this:

#include <SWI-Prolog.h>

void
t(term_t t)
{ (void)PL_put_float(t, 3.14);
}

Now

gcc -O -Wall -I ~/src/swipl-devel/src -c t.c
t.c: In function ā€˜tā€™:
t.c:5:9: warning: ignoring return value of ā€˜PL_put_floatā€™ declared with attribute ā€˜warn_unused_resultā€™ [-Wunused-result]
    5 | { (void)PL_put_float(t, 3.14);

Cast-to-void used to work in the days of lint. Nowadays, something more verbose is needed:

#include <SWI-Prolog.h>

void t(term_t t) {
  [[maybe_unused]] auto unused = PL_put_float(t, 3.14);
}