Dear ICU Team & Users,
I would like to propose the following API for: ICU 79
Please provide feedback by: next Wednesday, 2026-01-21
Designated API reviewer: Markus
Ticket: ICU-23310
(The "ICU 79 API proposal status" document is still marked as TODO, so
instead I just added this proposal to the old "ICU 78 API proposal
status" from where it later can be easily cut'n'pasted.)
There's a pretty new C++ feature called lifetimebound, currently
supported by newer versions of the Clang and MSVC compilers (and
possibly others):
https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
https://learn.microsoft.com/en-us/cpp/code-quality/c26816?view=msvc-170
While it doesn't turn C++ into Rust quite yet, it makes it possible
for the compiler to emit warnings or errors for a bunch of easily made
memory bugs that are otherwise hard to detect.
I therefore propose adding a new ICU4C macro for the feature:
#ifndef __cplusplus
// Not for C.
#elif defined(U_LIFETIME_BOUND)
// Use the predefined value.
#elif UPRV_HAS_CPP_ATTRIBUTE(clang::lifetimebound)
# define U_LIFETIME_BOUND [[clang::lifetimebound]]
#elif UPRV_HAS_CPP_ATTRIBUTE(msvc::lifetimebound)
# define U_LIFETIME_BOUND [[msvc::lifetimebound]]
#elif UPRV_HAS_ATTRIBUTE(lifetimebound)
# define U_LIFETIME_BOUND __attribute__((lifetimebound))
#endif
With that in place, I'd then proceed to annotate ICU4C functions like this:
U_COMMON_API const char* getName() const U_LIFETIME_BOUND;
static const Locale& getLocale(
const Locale& valid U_LIFETIME_BOUND,
const Locale& actual U_LIFETIME_BOUND,
ULocDataLocaleType type, UErrorCode& status);
That will make it possible for the compiler to detect the memory bugs
in code like this:
const char* p = Locale("hi").getName();
const Locale& l = LocaleBased::getLocale(Locale("aa"), Locale("zu"),
ULOC_VALID_LOCALE, status);
Such code would then result in compiler errors like these:
error: temporary whose address is used as value of local variable 'p'
will be destroyed at the end of the full-expression
[-Werror,-Wdangling]
const char* p = Locale("hi").getName();
^~~~~~~~~~~~
error: temporary bound to local reference 'l' will be destroyed at the
end of the full-expression [-Werror,-Wdangling]
const Locale& l = LocaleBased::getLocale(Locale("aa"), Locale("zu"),
^~~~~~~~~~~~
error: temporary bound to local reference 'l' will be destroyed at the
end of the full-expression [-Werror,-Wdangling]
const Locale& l = LocaleBased::getLocale(Locale("aa"), Locale("zu"),
^~~~~~~~~~~~
So when all the above is in place, I furthermore propose adding
-Wdangling to the default compiler options.
--
Fredrik Roubert
rou...@google.com