cancel
Showing results for 
Search instead for 
Did you mean: 

Shifting left – a general C question

EThom.3
Senior

Hi,

I have a piece of CRC calculating code that I nicked from somewhere a couple of decades ago. I've been wondering about a few lines:

  *CRCVal ^= (*CRCVal << 8) << 4;
  *CRCVal ^= ((*CRCVal & 0xFF) << 4) << 1;

(CRCVal is a pointer to a uint16_t variable.)

What I'm curious about is the slightly weird left-shifting notation. Shouldn't it give exactly the same result if it was written like this?

  *CRCVal ^= (*CRCVal << 12);
  *CRCVal ^= (*CRCVal & 0xFF) << 5;

Does anyone have a hunch why the shifts are split up like this? Could it be something related to a specific compiler or device that handles half-byte shifts in a certain way?

By the way, it would be great if this forum had a "General programming" board. I prefer to ask questions here, as I think that the community has a nice vibe.

16 REPLIES 16

@EThom.3 wrote:

Or perhaps an 8051, if that even had a C compiler 20-30 years ago. .


Keil C51 was well-established 20-30 years ago.

Keil was established as an 8051 tools company long before ARM bought them.

https://en.wikipedia.org/wiki/Keil_(company)

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Interesting. Thanks.

Thus, my best guess is that the piece of code was originally made for either a PIC or an 8051.

Maybe by someone trying to write assembler in C: they didn't realise that the compiler can work out how to do a 12-bit shift - they didn't have to manually decompose it themselves?

Used to see a lot of that.

Also people thinking that cramming as much as possible into a single source line would produce less object code!

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
EThom.3
Senior

I just thought of something.

If this – quite old – code was indeed written for a PIC, it might have been written in an ancient MPLAB C compiler environment. Around the turn of the century, the MPLAB C17 compiler was not ANSI C compliant, had insane limitations, and was riddled with errors. If the CRC code was used in that environment, the doubled shifting operations might have been a work-around to get the code to compile correctly.


@Andrew Neil wrote:

Also people thinking that cramming as much as possible into a single source line would produce less object code!


I have seen one guy removing whitespaces and empty lines, to make the program smaller. Or go faster – I'm not sure.

> I have seen one guy removing whitespaces and empty lines, to make the program smaller. Or go faster – I'm not sure.

Compressing whitespace in C does not affect program output.

If you feel a post has answered your question, please click "Accept as Solution".

Of course it doesn't. That's what made the guy's attempts mildly amusing.