Skip to content

Conversation

@lemire
Copy link
Member

@lemire lemire commented Jan 4, 2026

Add lifetimebound and noescape attribute macros

Although simdutf currently has no use cases for the lifetimebound attribute, define a cross-compiler macro for it to enable potential future usage. This follows the evolving C++ lifetime profile proposals and provides compatibility with MSVC and Clang attributes where available.

Additionally, introduce a macro for Clang's noescape attribute. This attribute indicates that a pointer parameter does not escape the function scope, allowing optimizers to make stronger assumptions. Include detailed explanatory comments describing its purpose, valid and invalid usage examples, current limitations (Clang-only support, declarative only with no static enforcement), and restriction to pointer parameters.

These macros fall back to empty definitions on unsupported compilers to ensure portability.

Add lifetimebound and noescape attribute macros

Although simdutf currently has no use cases for the lifetimebound attribute, define a cross-compiler macro for it to enable potential future usage. This follows the evolving C++ lifetime profile proposals and provides compatibility with MSVC and Clang attributes where available.

The lifetimebound attribute indicates that a pointer (or reference) parameter or return value does not outlive the object it refers to. It helps compilers detect potential lifetime issues, such as dangling pointers or references, by enforcing that the lifetime of the pointed-to object extends at least as long as the function's result or any derived pointers. For example, it could be applied to a function returning a pointer into an input buffer:

const char* find_char([[clang::lifetimebound]] const std::string& s, char c) {
  return std::find(s.begin(), s.end(), c);
}  // Valid if the returned pointer's lifetime is bound to s

An invalid use might return a pointer to a local variable, which the compiler could warn about if the attribute is present.

The noescape attribute signals that the function does not store the pointer (or anything derived from it) in a location accessible after the function returns, such as globals or heap allocations. This enables better optimizations, like assuming the pointer remains valid only within the call. A valid example is local access only:

char f(simdutf_noescape const char* p) {
  return p[0];  // Valid: pointer used transiently
}

An invalid example stores it globally:

const char* global_ptr;
void g(simdutf_noescape const char* p) {
  global_ptr = p;  // Invalid: pointer escapes via global
}

These macros fall back to empty definitions on unsupported compilers to ensure portability.

@pauldreik
Copy link
Collaborator

I think this might be useful but am hesitant to add this unless we actually use it. Or did you plan to annotate the coming c api?

@pauldreik
Copy link
Collaborator

also, in case swift would use the C++ api, would this be the right macros? looking at #893 (comment) it seems like they would need to do different things depending on compilation mode (switft/C++).

@lemire
Copy link
Member Author

lemire commented Jan 5, 2026

@pauldreik I don't know. I just wanted us to consider that we can add these things if we want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants