Skip to content

Conversation

@timadye
Copy link
Contributor

@timadye timadye commented Jan 21, 2026

A possible simpler alternative to #4968.

I think this is equivalent, in that both use a unique static variable in a member function templated on the contained type. This PR just replaces the hashed type name with a pointer to Handler. In fact this test is already used to check for the same type in operator=.

--- END COMMIT MESSAGE ---
This is draft, because I haven't yet tested it, except for some simple examples with different compilation units. What do you think?

@paulgessinger

@github-actions github-actions bot added the Component - Core Affects the Core module label Jan 21, 2026
@github-actions github-actions bot added this to the next milestone Jan 21, 2026
@timadye timadye changed the title simpler type check in Acts::Any refactor: simpler type check in Acts::Any Jan 21, 2026
@github-actions
Copy link
Contributor

📊: Physics performance monitoring for bb35650

Full contents

physmon summary

@sonarqubecloud
Copy link

@paulgessinger
Copy link
Member

paulgessinger commented Jan 21, 2026

Thanks @timadye.

I think this is exactly what we're had in Acts::Any before my change to the type hash in #4828.

This exactly exhibits the problem: the pointers will point at different addresses in different shared libraries and the check then returns false, identifying them as separate types.

The pointer comparison in the assignment operator is likely a bug I think.

@timadye
Copy link
Contributor Author

timadye commented Jan 21, 2026

Sorry, I didn't see that you'd tried this before.

I think I see how yours might work. The pattern is the same. In each case you are relying on a static variable inside a template <typename T> static function only being initialised once. That seems to work across compilation units, but not across shared libraries.

In that case, you rely on typeid(T).name() being the same between different shared libraries. This clearly won't work with the original method (and my repeat of it here), where we compare addresses.

However, according to cppreference, the only things guaranteed to match are comparing std::typeinfo objects (returned by typeid(T)), their ti.hash_code()s, and std::type_index(ti).

libstdc++'s std::any compares typeid(T)s. Actually it compares addresses first, so will not throw if either

  1. the address of a static function inside a template <typename T> static struct {} matches, or
  2. typeid(T) matches, with the typeinfo of the contained type being returned by function templated on that type.

I think it does both for speed, and so it mostly works even if RTTI isn't available.

I think we could do something similar by caching a pointer to the std::typeinfo and dereferencing before comparing. Or cache the hash_code or std::type_index.

I can try that...

@paulgessinger
Copy link
Member

We just need to make sure that this then actually works, also in @wdconinc's case. I fear that all of the guarantees around typeid, type_index or .hash_code() don't actually work in practice in the cases we need them to.

dynamic_cast is also guaranteed to work across libraries, I believe, but in our experience, it often doesn't work.

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

Labels

Component - Core Affects the Core module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants