jonspaceharper
jonspaceharper

Reputation: 4367

Casting unsigned char to signed char for a red-black tree

Overview

I'm working on wrapping Windows Shell functionality with Qt. The issue I've run into regards ABSOLUTE_IDLISTs and storing the data. For reference, a Windows id list looks like this in memory:

//Note that there may be an arbitrary number of cb/abId pairs.
=================================================================
=           =   (cb bytes)  =           =  (cb bytes)   =       =
= USHORT cb =  UCHAR []abID = USHORT cb =  UCHAR []abId = '\0'  =
=================================================================

I'm using the absolute ID as a unique identifier for each node for quick retrieval. The value type is ShellNodePointer, a shared pointer to ShellNode, which caches data. I originally approached this using QHash (basically std::unordored_map), but that requires hashing the bits for every retrieval (although I stored the hash key in the ShellNode).

//unsigned int is the hash result, ShellNodePointer is a QSharedPointer to a ShellNode
QHash<unsigned int, ShellNodePointer>

Instead, I'm considering a red-black tree approach using QMap. My issue is this: the fastest way to compare two keys would be storing them as QByteArrays, which would allow quick less than comparisons and simple passing of the id list as raw data to the QByteArray constructor.

ITEMIDLIST_ABSOLUTE *someIdListPointer = ...;
QByteArray ba(someIdListPointer);

The Problem

Unfortunately, QByteArray takes a null-terminated const char *, without specificying signed or unsigned. Since I'm on Windows, this defaults to signed char.

The Question

Can I cast to [signed] char * and disregard the overflow issues, since every negative value key will overflow in the same way? Specifically, will the red-black tree still work as normal, since the resulting data is guaranteed to be uniform in two separate calls with the same key?

Note: I am aware the the USHORT cb will be included in the key. This is acceptable, as it's just extra data that will be matched with two identical keys.

Edit: clarified that abId is actually an array without a null-terminator.

Upvotes: 2

Views: 102

Answers (1)

Max Langhof
Max Langhof

Reputation: 23701

Can I cast to [signed] char * and disregard the overflow issues, since every negative value key will overflow in the same way? Specifically, will the red-black tree still work as normal, since the resulting data is guaranteed to be uniform in two separate calls with the same key?

Yes, casting like this simply interprets the bytes in memory in a different way and will be consistent for identical machine + executable/compiler. The byte representation of signed integers is not mandated by the standard, so the "meaning" (i.e. represented number) may not be what you expect, but that should not matter for a RB tree that just requires a total ordering.

Upvotes: 2

Related Questions