From: Guus Sliepen Date: Sun, 13 Sep 2009 12:08:59 +0000 (+0200) Subject: Apparently it's impolite to ask GCC to subtract two pointers. X-Git-Tag: release-1.0.10~32 X-Git-Url: https://git.tinc-vpn.org/git/browse?a=commitdiff_plain;h=75773efe2689d347a2f219c5f27e4a82eef1236b;p=tinc Apparently it's impolite to ask GCC to subtract two pointers. If two pointers do not belong to the same array, pointer subtraction gives nonsensical results, depending on the level of optimisation and the architecture one is compiling for. It is apparently not just subtracting the pointer values and dividing by the size of the object, but uses some kind of higher magic not intended for mere mortals. GCC will not warn about this at all. Casting to void * is also a no-no, because then GCC does warn that strict aliasing rules are being broken. The only safe way to query the ordering of two pointers is to use the (in)equality operators. The unsafe implementation of connection_compare() has probably caused the "old connection_t for ... still lingering" messages. Our implementation of AVL trees is augmented with a doubly linked list, which is normally what is traversed. Only when deleting an old connection the tree itself is traversed. --- diff --git a/src/connection.c b/src/connection.c index 66eb0596..283ebd71 100644 --- a/src/connection.c +++ b/src/connection.c @@ -37,7 +37,7 @@ connection_t *broadcast; static int connection_compare(const connection_t *a, const connection_t *b) { - return a - b; + return a < b ? -1 : a == b ? 0 : 1; } void init_connections(void)