TL;DR: I believe we should rename Fl_Terminal::putchar() to
something that doesn't conflict with the global function name
putchar() which *may* be defined as a macro.
I'm asking for your comments, see rationale below:
As GitHub issue #944 "Support for NetBSD" [1] shows, putchar() *can*
be defined as a macro and Michael Bäuerle showed that this *is*
the case for some NetBSD versions (maybe not all?).
Although you can use fully qualified Fl_Terminal::putchar(...) to
distinguish Fl_Terminal's method from the global putchar() function
this does not work if putchar is defined as a macro.
More info:
- According to the POSIX man page [2] for putchar(int c) "The
function call putchar(c) shall be equivalent to putc(c,stdout)."
- According to the POSIX man page [3] for putc(int c, FILE *stream)
"The putc() function shall be equivalent to fputc(),
except that if it is
implemented as a macro ..."
Honestly, I don't read this as "putchar() can be implemented as a
macro" (emphasis on "The function call putchar(c)
..." in the docs) but as it stands, on the tested system putchar *is*
defined as a macro.
Although Michael provides a patch for Fl_Terminal.cxx (short: #undef
putchar) this is IMHO not a working solution because user code that
calls Fl_Terminal::putchar() would also be affected even if
fully qualified !
As a proof of concept I added one line to test/handle_keys.cxx:
win->tty->printf("Please press any key ...\n");
win->tty->Fl_Terminal::putchar('a', 0, 2); // this line added (line 337)
... which works as expected (note: fully qualified putchar call)
... until I also add the following macro after all #include's:
#defineputchar(c) putc(c, stdout)
... as "suggested" by the POSIX docs cited above.
Error message in the user's program would be something like:
/git/fltk/master/test/handle_keys.cxx:337:43: error: macro "putchar" passed 3 arguments, but takes just 1
337 | win->tty->Fl_Terminal::putchar('a', 0, 2);
| ^
/path/to/fltk/test/handle_keys.cxx:29: note: macro "putchar" defined here
29 | #define putchar(c) putc(c, stdout)
|
/path/to/fltk/test/handle_keys.cxx: In function ‘int main(int, char**)’:
/path/to/fltk/test/handle_keys.cxx:337:26: error: statement cannot resolve address of overloaded function
337 | win->tty->Fl_Terminal::putchar('a', 0, 2);
| ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
ninja: build stopped: subcommand failed.
Conclusion:
Since we can't prevent that a system defines putchar as a macro we
should IMHO rename the function rather than trying to work around it
by patching the FLTK source file. And of course we can't '#undef putchar' anywhere in a public
header file. Telling users that run into this issue to '#undef putchar' wouldn't be a good
suggestion as well.
Another point is, BTW, that Fl_Terminal::putchar() has two
overloaded methods, where one uses a 'char' but the other one uses a
string ('char *') which might be confusing. Another name might
clarify this.
My suggestion: Fl_Terminal::put_text()
for both overloads. This avoids name clashes and 'text' is neutral
and can take a 'char' or a 'char *'.
Fortunately it's still time to do this before we release 1.4.0 !
Comments are owned by the poster. All other content is copyright 1998-2025 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.