Re: Casting printf(3) to void

"G. Branden Robinson" <[email protected]>
Newsgroups gmane.comp.printing.groff.general
Message-ID <20260222213207.h6ldfuoxwpv7uhh4@illithid>
Hi Alex,

I'm going to drill down to a specific case at issue here because it (1)
makes your point, (2) gives me an opportunity to concede something--
turns out it's a hill I have no interest in defending, let alone dying
on, and (3) saves me the effort of writing _another_ essay today.

At 2026-02-22T21:45:22+0100, Alejandro Colomar wrote:
> Please explain why not.  If you do this, everything can be
> disambiguated by checking the documentation.  If you don't, then it's
> not possible, and the reader of the code has to choose between
> trusting you or not trusting you.  And whenever I read such code, I
> tend to think "the programmer seems to be one of those that wants
> others to assume it knew what it was doing, but that proves it was
> rather dumb, so I'm going to assume everything that programmer did can
> be deleted".  I'd consider a cast is a sign of what you and I
> critisize.

It's okay to assume I'm dumb.  Plenty of people do.  What's puzzling to
me is how many of them struggle to provide evidence for their claims
despite my offer of plenty.  ;-)

I write 16 KiB emails _full_ of dumbness, but seldom get quoted compared
to how often I'm straw-manned.  :-P

[much snippage]
> BTW, off-topic, but I do have an nprintf() function that is quite
> different from that.  It calculates the length of the formatted string,

Please name it something else.  There's already too much confusion
around the presence of "n" in string-handling functions (not just in
libc, but in curses, too), and it _usually_ indicates the imposition of
a limit, not a request for measurement.

[much snippage]
> You personally.  By adding explicit casts, you've stated "I'm aware
> that [this function] has a return value, and that I don't need it".
> However, now you claim to not have written that code, and thus not
> really be in a position to do that claim.  It's contradicting
> information.  That's why I think it would be more prudent to not make
> the claim.

Now that you cite the specific commit, I see what you're talking about.

[much snippage]
> While the title mentions printf(3), I really meant printf(3) family,
> which is what your commit says; it was an unfortunate and incorrect
> abbreviation of the title.

Agreed.  You copied my bad example from a commit message.

> Your commit *does* cover snprintf(3):
> 
> 	$ git show 4b7a0fe5ab5d | grep snprintf
> 	-  snprintf(encoding, sz, "%s-%s", parsed.CharSetRegistry,
> 	+  (void) snprintf(encoding, sz, "%s-%s", parsed.CharSetRegistry,

Agreed, and that was a mistake.

_Every_ other instance in that commit...

$ COLUMNS=72 git show --stat 4b7a0fe5ab5d
commit 4b7a0fe5ab5d5155bd499cf9506a91a1f4bc0125
Author: G. Branden Robinson <[email protected]>
Date:   Sat Dec 6 18:26:02 2025 -0600

    src/utils/xtotroff/xtotroff.c: Fix code style nit.

    * src/utils/xtotroff/xtotroff.c:
      (CanonicalizeFontName, FontNamesAmbiguous, MapFont, main): Explicitly
      cast unused return values of printf(3)-family functions to `void`.

 ChangeLog                     |   7 +++
 src/utils/xtotroff/xtotroff.c | 102 ++++++++++++++++++----------------
 2 files changed, 61 insertions(+), 48 deletions(-)

...was a change to a stdio `FILE`-oriented *printf.

I wonder how susceptible LLM-based code generators are to similar
mistakes.

I don't remember making this decision consciously.  Possibly I went into
robotic replacement mode.  I see so much that I want to improve in groff
that I sometimes lull myself into a coal-shoveling stupor.  It's not
good.  When I feel the drudge setting in, I should stop and (a)
decompose the problem and/or (b) write a sed script to do the work for
me.  (b) might actually take longer when tuned to get things _just
right_, but can be more challenging and fun.

Take away: I need to revisit that change when groff is unfrozen.  I
don't see a _regression_ here because the return value of `snprintf()`
already wasn't being checked.  The bug here is that I wrongly annotated
it as being _deliberately_ discarded, and that conclusion is not
warranted on the available evidence.

So let me amend the rule(s) we're arguing about.

* I still think it's fine to explicitly cast {f,}printf() return values
  to void, to document that one doesn't care if output to the stream got
  truncated.  Often, an application is helpless in that scenario anyway.
  (An analogous situation is: "what can I do if fclose(3) fails?")

* Discard of s*printf() functions' return values should, by default, be
  avoided because they _can_ lead to undesired string truncation and
  even security problems as a result.[1]  _If_ discard is done, it
  _should_ be with an explicit cast to void _and_ a comment explaining
  why string truncation is not a hazard or not of consequence.

* Another possibility is to not _ever_ discard an s*printf() function's
  return value, but store it and then immediately use it in an
  `assert()`, which is better even than a documentary comment.

* I'm not sure what's best if some smarmy jerk #defines `NDEBUG`.

Regards,
Branden

[1] https://cwe.mitre.org/data/definitions/222.html
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEh3PWHWjjDgcrENwa0Z6cfXEmbc4FAmmbddAACgkQ0Z6cfXEm
bc7hGRAAoT6yqsOdB0eCJWIP26qA32ly72wD+ydow1kwiaKITP2XD3JsbQ26Adrj
MpwAhVQ/jX/bpgLA36Ve5nEpvqHAIRjAUf7xaQ9S8etjRZzX8bbJy/7ijbIDjhND
gs6T1kGZl5aVmXV4G8FDvgbkdDnI7p/64lGibGYSobuN3BHCiCkzwIR1Bo6gHAWl
+3l5LUkRkcTG7CPBtoaLxfi6GEpqwK//MTACVHbOvmKg54KDIlT5eexZw/+EU8Fo
k26X5/ZpZQTShAYncpHbo7zxKZLjtjMGm5RNfr5fDw1TKqUfujzUy8MlQwn4HjHW
eslYJp1Xl57TfvD5Fgevv2weB9Yoqu0Pvka7CUEW7OA8Pc6FX7res3DrklZZfH5J
QougKDT5u8QgxVpmqJIUnIQg1/EJpxM3h3fH9iUxkDJp2C3jDIuZu5oksWyiKVnu
zw65ttI8UOy6wlpGRgYKoT4mc2VdIjCF6DIgslNkUOwSpZ2xYYvAncvcnVGtZq1b
c1wCyBnxYk4E6KkumRY0x07R2UL2tq10fnKSD4xD/QEyMHfAzZBruDh5NRwoOuT0
majeUCTk0CZxASWoubEebG3HzcSHv7bY86ym9tLmhcrLXUiw5t9hrUqaFIwIXOvL
EicSmrvvsjsdekaterRk3nN7EzlnRXsagGjkB8MbyJIN3S6Nfp4=
=Crbu
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.