Skip to content

Orphan StringName when using static LazyLock<StringName> and useless p_is_static=true #1306

@beicause

Description

@beicause

If I use:

static STATIC_STRING_NAME: LazyLock<StringName> =
    LazyLock::new(|| StringName::from(c"static_string_name")); // Or from("str");

Then the static StringName will be orphan (static count 1, refcount 2) because inc_ref increments refcount and it is never freed.

fn from(c_str: &'static std::ffi::CStr) -> Self {
// SAFETY: c_str is nul-terminated and remains valid for entire program duration.
let result = unsafe {
Self::new_with_string_uninit(|ptr| {
sys::interface_fn!(string_name_new_with_latin1_chars)(
ptr,
c_str.as_ptr(),
sys::conv::SYS_TRUE, // p_is_static
)
})
};

In my opinion, creating a p_is_static=true StringName from CStr without assigning it to a static variable makes no sense, since otherwise you're still constructing and destroying the StringName. I did a quick benchmark that shows no performance advantage comparing with p_is_static=false. I believe it's better to make From<&CStr> non-static because we do not have static cache.

Not sure if we can add a method like Godot's SNAME to create a static StringName, or use a global HashMap cache
(Actually in C#, global HashMap cache can significantly improve performance, but in C++ or rust it may be not worth).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions