Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Assignment from value to value not working for non-trivial types #115

Closed
dsiroky opened this issue Apr 11, 2024 · 4 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@dsiroky
Copy link

dsiroky commented Apr 11, 2024

Hi! This issues seems to appear only if the value is of a non-trivial type.

This code

    ankerl::unordered_dense::map<int, std::string> m{};
    m[1] = "abc";
    m[2] = m[1];
    std::cout << '"' << m[1] << "\"\n";
    std::cout << '"' << m[2] << "\"\n";

prints

"abc"
""

Expected output is

"abc"
"abc"

If I "pre-create" the value in the map then it works:

    ankerl::unordered_dense::map<int, std::string> m{};
    m[1] = "abc";
    m[2]; // pre-create
    m[2] = m[1];
    std::cout << '"' << m[1] << "\"\n";
    std::cout << '"' << m[2] << "\"\n";

System:

  • OS: Linux
  • Compiler: g++ 13.2, clang++ 16.0.6
  • unordered_dense git commit d911053
@dsiroky dsiroky added the bug Something isn't working label Apr 11, 2024
@martinus
Copy link
Owner

Hi @dsiroky, thanks for the bug report! This seems to work for the try_emplace methods, but not for operator[]. I'll have a look

@glebm
Copy link

glebm commented Aug 4, 2024

A repro test case for test/assignment_combinations.cpp:

TEST_CASE_MAP("assignment_combinations_11", int, std::string) {
    map_t m;
    m[1] = "abc";
    m[2] = m[1];
    REQUIRE(m[1] == "abc");
    REQUIRE(m[2] == "abc");
}

@glebm
Copy link

glebm commented Aug 4, 2024

Let me rewrite the failing example above to an equivalent order of operations:

std::string &a = m[1]; // evaluate right-hand side
std::string &b = m[2]; // evaluate left-hand side
b = a; // assign

The problem is that the reference to a is invalidated in when the left-hand side is evaluated (because the underlying storage is resized), so it is invalid at the time of the assignment.

I don't think this is actually a bug in unordered_dense.

@martinus
Copy link
Owner

martinus commented Oct 5, 2024

@glebm you are of course right, there's nothing I can do about this since the map doesn't guarantee reference stability.

@martinus martinus closed this as completed Oct 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants