简体   繁体   中英

Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type

I have the following code that is giving an error of V629 from PVS Studio:

V629 Consider inspecting the 'length << 32' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. circular_buffer.cc 84

bool CircularBuffer::AcquireCached(uint32_t key, size_t length,
                               Allocation* out_allocation) {
uint64_t full_key = key | (length << 32);

On a machine where size_t is 32 bit (so virtually on any modern 32 bit platform) wide this code doesn't do what you would think it does.

length is 32 bit wide, and there's no integral promotion, so the left shift by 32 bit invokes undefined behavior (it's UB to shift more than the type size). Even if it was well defined, it would shift all the bits out of the 32 bit value, so again, not what the author expected.

To make it work as intended, you have to cast to uint64_t before shifting, so that the shift is done with a 64-bit wide type and the bits can actually go somewhere useful.

uint64_t full_key = key | (uint64_t(length) << 32);

Notice that this happens to work fine on 64 bit platforms (where size_t is already 64 bit wide, so that shift is fine), so I imagine that's probably why this wasn't spotted earlier.

The right answer was given earlier. This warning will be issued in case where the type size_t is 32-bit. If size_t is 64-bit, there won't be a mistake and the analyzer won't complain.

I would like to add couple of things. Firstly, I'd like to give a link to the docs: V629 . Secondly, I ask to use tag pvs-studio on the issues relating to PVS-Studio analyzer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM