Search code examples
c++pointersdereference

Recomended formating for temporarily inverting data at pointer and then passing pointer to temporarily inverted data


Long story short, I have a pointer to a value that is stored inverted, so when we are calculating a hash to verify data integrety, we need to invert the data that is used in the hash. The hash function, however, takes a pointer as input. So what we need to do is take our pointer, dereference it to get to the data, temporarily invert the data, and the pass a reference to the inverted data.

I've written up some pseudocode for how I had originally done it.

uint32_t hash = 0;
MemoryBlock pMemoryBlock = pAllocator->GetFirstMemoryBlock();
while(nullptr != pMemoryBlock)
{
    uint32_t size = pMemoryBlock->getWordsUsed();
    const uint32_t* pStartAddress = pMemoryBlock->GetStartAddress();
    for (uint32_t i = 0; i < size; i++)
    {
        if (isDiagnostics)
        {
            uint32_t inverted_data = ~(pStartAddress[i]);
            hash = Algorithim::Calculate(&inverted_data, hash);
        }
        else
        {
            hash = Algorithim::Calculate(&pStartAddress[i], hash);
        }
    }
    pMemoryBlock->GetNextMemoryBlock();
}
return hash;

But a colleague on my code review wants me to avoid the temp variable and change it to.

uint32_t hash = 0;
MemoryBlock pMemoryBlock = pAllocator->GetFirstMemoryBlock();
while(nullptr != pMemoryBlock)
{
    uint32_t size = pMemoryBlock->getWordsUsed();
    const uint32_t* pStartAddress = pMemoryBlock->GetStartAddress();
    for (uint32_t i = 0; i < size; i++)
    {
        if (isDiagnostics)
        {
            hash = Algorithim::Calculate(&~pStartAddress[i], hash);
        }
        else
        {
            hash = Algorithim::Calculate(&pStartAddress[i], hash);
        }
    }
    pMemoryBlock->GetNextMemoryBlock();
}
return hash;

I was wondering if there was any real reason to avoid using the temp variable. If it even works to dereference a pointer, do an operator on the data, and then pass a reference to it without assigning the value to anything (cause i'm fairly certain it doesn't). And if there are any better ways to do this than the first example.


Solution

  • You need the temp variable. This expression:

    hash = Algorithim::Calculate(&~pStartAddress[i], hash);
    

    Is invalid because the result of the ~ operator is not an lvalue, and the & operator requires an lvalue.

    On a side note, you can reduce repetition in your code by using the temp value in both cases:

        uint32_t data = isDiagnostics ? ~pStartAddress[i] : pStartAddress[i];
        hash = Algorithim::Calculate(&data, hash);