Jump to content
  • Advertisement
Sign in to follow this  
DevFred

putting pointers to objects in a set

This topic is 3344 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can some C++ guru confirm I'm invoking undefined behavior?
#include <set>

class Player
{
    // exact contents irrelevant
};

int main()
{
    Player* a = new Player();
    Player* b = new Player();
    std::set<Player*> players;

    players.insert(a);
    players.insert(b);

    players.clear();
    delete b;
    delete a;
}
I don't want to spoil the fun, but it's obviously got to do with pointers ;)

Share this post


Link to post
Share on other sites
Advertisement
Quote:

5.9 Relational operators

If two pointers point to elements of the same array or one beyond the end of the array, the pointer to the object with the higher subscript compares higher. [...] Other pointer comparisons are unspecified.

Yup, there you have it. But what exactly does "unspecified" mean in this context? Is that less strong than "undefined"?

As I understand it, putting pointers to objects in an unordered_set should be ok, right?
Quote:

5.10 Equality operators

Pointers to objects or functions of the same type (after pointer conversions) can be compared for equality. Two pointers of the same type compare equal if and only if they are both null, both point to the same function, or both represent the same address.

Share this post


Link to post
Share on other sites
Quote:
Original post by DevFred
Quote:

5.9 Relational operators

If two pointers point to elements of the same array or one beyond the end of the array, the pointer to the object with the higher subscript compares higher. [...] Other pointer comparisons are unspecified.
Yup, there you have it. But what exactly does "unspecified" mean in this context? Is that less strong than "undefined"?
Much less strong than 'undefined':

Unspecified behavior also means that the code is also completely legal C++, but compilers may interpret it differently. The difference between implementation-defined behavior and unspecified behavior is that the compiler vendor is not required to describe what their particular compiler does. For example, when you cast an integer to an enum , the resulting enum value may in some cases be unspecified. (source)

However, an interesting side effect of that definition of 'unspecified', is that your original code is indeed legal C++. Or, in other words, C++ doesn't guarantee the order of elements in your set-of-pointers, but it does guarantee that an ordering will exist (and may differ between implementations).

Share this post


Link to post
Share on other sites
Hm, but as I understand it, "unspecified" could also mean that p < q always returns false if p and q do not point to elements of the same array, because the implementation can do whatever it wants...

Share this post


Link to post
Share on other sites
Or, worse, it could always return true, making it not define a partial order at all.

Share this post


Link to post
Share on other sites
Why is C++ not properly defined / specified? Makes it so much more complex, with the only result that compiler builders can do what they want?

Share this post


Link to post
Share on other sites
Because defining and specifying the behavior of a lot of that behavior would have performance impacts. Ex: indexing out array bounds with a pointer is undefined behavior. In order to define that behavior, you would then need to track the array bounds and the pointer aliases and do comparisons against those bounds.

Share this post


Link to post
Share on other sites
Quote:
Original post by DevFred
Can some C++ guru confirm I'm invoking undefined behavior?

*** Source Snippet Removed ***

I don't want to spoil the fun, but it's obviously got to do with pointers ;)


Yup. Failing to return a specific value from a function of type int is bad, and in the case of main() it should be explicitly return EXIT_SUCCESS; *nod nod nod*.

Yes, ok, the hidden < operator is wrong in this context. But memory has been flat since Windows 3.1 died, anywhere I've even been, so ordering by address is something I no longer worry about. It's all a big array now really.

On the other hand, there is rarely reason to order things by address. You just wouldn't use set for that, you're paying for useless ordering. Which in itself bugs me; I don't know why a set, which is not a term that implies ordering to me, has to be ordered in the first place. They should have been called set and ordered_set. Yeah. Someone fix the standard.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!