Hi Bruno,
When writing a Coreutils patch that used mbfile [1], these lines seemed
like they could be potentially problematic:
- line_out[offset_out++] = '\n';
- fwrite (line_out, sizeof (char), offset_out, stdout);
+ mb_setascii (&line_out[offset_out], '\n');
+ offset_out++;
Since mb_setascii is a macro, if one wrote the following as I would have
liked to:
mb_setascii (&line_out[offset_out++], '\n');
Their program would compile, but work incorrectly. This is because the
first argument would evaluate multiple times.
Any objections to the attatched patch? It makes mb_setascii an extern
inline function. I can see someone writing a bug like this in the future
because they don't realize mb_setascii is a macro.
Collin
[1] https://lists.gnu.org/archive/html/coreutils/2025-08/msg00031.html
>From 219757c03ffa1a21d4705363c42911cbf22d222b Mon Sep 17 00:00:00 2001
Message-ID: <219757c03ffa1a21d4705363c42911cbf22d222b.1755820206.git.collin.fu...@gmail.com>
From: Collin Funk <[email protected]>
Date: Thu, 21 Aug 2025 16:48:58 -0700
Subject: [PATCH] mbfile: Make mb_setascii an inline function.
* lib/mbchar.h (mb_setascii): Define as an extern inline function
instead of a macro.
---
ChangeLog | 6 ++++++
lib/mbchar.h | 11 ++++++++---
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 62a792c994..0943803f6f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2025-08-21 Collin Funk <[email protected]>
+
+ mbfile: Make mb_setascii an inline function.
+ * lib/mbchar.h (mb_setascii): Define as an extern inline function
+ instead of a macro.
+
2024-08-19 Bruno Haible <[email protected]>
doc: Update for glibc 2.42.
diff --git a/lib/mbchar.h b/lib/mbchar.h
index d77168e717..85422cd527 100644
--- a/lib/mbchar.h
+++ b/lib/mbchar.h
@@ -262,9 +262,14 @@ mb_width_aux (char32_t wc)
#if defined GNULIB_MBFILE
/* Assignment. */
-# define mb_setascii(mbc, sc) \
- ((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \
- (mbc)->wc = (mbc)->buf[0] = (sc))
+MBCHAR_INLINE void
+mb_setascii (mbchar_t *mbc, char sc)
+{
+ mbc->ptr = mbc->buf;
+ mbc->bytes = 1;
+ mbc->wc_valid = true;
+ mbc->wc = mbc->buf[0] = sc;
+}
#endif
/* Copying a character. */
--
2.50.1