Lesson 11. Pattern 3. Shift operations
It is easy to make a mistake in code that works with separate bits. The pattern of 64-bit errors under
consideration relates to shift operations. Here is an example of code:

ptrdiff_t SetBitN(ptrdiff_t value, unsigned bitNum) {

    ptrdiff_t mask = 1 << bitNum;

    return value | mask;

}

This code works well on a 32-bit architecture and allows you to set a bit with numbers from 0 to 31 into
one. After porting the program to a 64-bit platform you need to set bits from 0 to 63. But this code will
never set the bits with the numbers 32-63. Note that the numerical literal "1" has int type and causes an
overflow when a shift in 32 positions occurs as shown in Figure 1. As a result, we will get 0 (Figure 1-B)
or 1 (Figure 1-C) depending on the compiler implementation.




 Figure 1 - a) Correct setting of the 31-st bit in a 32-bit code; b,c) - Incorrect setting of the 32-nd bit on a
                                   64-bit system (two variants of behavior)

To correct the code we must make the type of the constant "1" the same as that of mask variable:

ptrdiff_t mask = ptrdiff_t(1) << bitNum;
Note also that the non-corrected code will lead to one more interesting error. When setting the 31-st bit
on a 64-bit system, the function's result will be the value 0xffffffff80000000 (see Figure 2). The result of
the expression 1 << 31 is the negative number -2147483648. This number is presented in a 64-bit
integer variable as 0xffffffff80000000.




                      Figure 2 - The error of setting the 31-st bit on a 64-bit system.

You should remember and take into consideration the effects of shifting values of different types. To
better understand all said above, consider some interesting expressions with shifts in a 64-bit system
shown in Table 1.




 Table 1 - Expressions with shifts and their results in a 64-bit system (we used Visual C++ 2005 compiler)

The type of errors we have described is considered dangerous not only from the viewpoint of program
operation correctness but from the viewpoint of security as well. Potentially, by manipulating with the
input data of such incorrect functions one can get inadmissible rights when, for example, dealing with
processing of access permissions' masks defined by separate bits. Questions related to exploiting errors
in 64-bit code for application cracking and compromise are described in the article "Safety of 64-bit
code".

Now a subtler example:

struct BitFieldStruct {

   unsigned short a:15;

   unsigned short b:13;

};

BitFieldStruct obj;

obj.a = 0x4000;

size_t addr = obj.a << 17; //Sign Extension
printf("addr 0x%Ixn", addr);

//Output on 32-bit system: 0x80000000

//Output on 64-bit system: 0xffffffff80000000

In the 32-bit environment, the order of calculating the expression will be as shown in Figure 3.




                            Figure 3 - Calculation of expression in 32-bit code

Note that a sign extension of "unsigned short" type to "signed int" takes place when calculating "obj.a
<< 17". To make it clear, consider the following code:

#include <stdio.h>

template <typename T> void PrintType(T)

{

    printf("type is %s %d-bitn",

               (T)-1 < 0 ? "signed" : "unsigned", sizeof(T)*8);

}

struct BitFieldStruct {

    unsigned short a:15;

    unsigned short b:13;

};

int main(void)
{

    BitFieldStruct bf;

    PrintType( bf.a );

    PrintType( bf.a << 2);

    return 0;

}

Result:

type is unsigned 16-bit

type is signed 32-bit

Now let us see the consequence of the sign extension in a 64-bit code. The sequence of calculating the
expression is shown in Figure 4.




                             Figure 4 - Calculation of expression in 64-bit code

The member of "obj.a" structure is converted from the bit field of "unsigned short" type to "int". "obj.a
<< 17" expression has "int" type but it is converted to ptrdiff_t and then to size_t before it is assigned to
addr variable. As a result, we will get the value 0xffffffff80000000 instead of 0x0000000080000000
expected.
Be careful when working with bit fields. To avoid the situation described in our example we need only to
explicitly convert "obj.a" to size_t type.

...

size_t addr = size_t(obj.a) << 17;

printf("addr 0x%Ixn", addr);

//Output on 32-bit system: 0x80000000

//Output on 64-bit system: 0x80000000


Diagnosis
Potentially unsafe shifts are detected by PVS-Studio static analyzer when it detects an implicit extension
of a 32-bit type to memsize type. The analyzer will warn you about the unsafe construct with the
diagnostic warning V101. The shift operation is not suspicious by itself. But the analyzer detects an
implicit extension of int type to memsize type when it is assigned to a variable, and informs the
programmer about it to check the code fragment that may contain an error. Correspondingly, when
there is no extension, the analyzer considers the code safe. For example: "int mask = 1 << bitNum;".

The course authors: Andrey Karpov (karpov@viva64.com), Evgeniy Ryzhkov (evg@viva64.com).

The rightholder of the course "Lessons on development of 64-bit C/C++ applications" is OOO "Program
Verification Systems". The company develops software in the sphere of source program code analysis.
The company's site: http://www.viva64.com.

Contacts: e-mail: support@viva64.com, Tula, 300027, PO box 1800

More Related Content

PPTX
Bit manipulation
PPT
Bit manipulation
PDF
Lesson 13. Pattern 5. Address arithmetic
PPTX
Computer arithmetic
PDF
Development of a static code analyzer for detecting errors of porting program...
PDF
Undefined behavior is closer than you think
PDF
C++11 and 64-bit Issues
DOCX
Check the following function headers and locate as many errors you ca
Bit manipulation
Bit manipulation
Lesson 13. Pattern 5. Address arithmetic
Computer arithmetic
Development of a static code analyzer for detecting errors of porting program...
Undefined behavior is closer than you think
C++11 and 64-bit Issues
Check the following function headers and locate as many errors you ca

What's hot (20)

PPT
1 arithmetic
DOC
C bitwise operators
PPTX
PDF
15 bitwise operators
DOCX
Calculating the hamming code
PDF
Module 00 Bitwise Operators in C
DOCX
Manoch1raw 160512091436
PDF
Assignment
PDF
Matlab numbers
PPT
Bitwise operators
PPT
Error detection and correction codes
PPT
PDF
FPGA Based Decimal Matrix Code for Passive RFID Tag
PDF
Comparison of analyzers' diagnostic possibilities at checking 64-bit code
DOCX
vhdl exp-5
PPTX
Floating Point Representation premium.pptx
PPT
digital logic circuits, digital component floting and fixed point
PPTX
Hamming code system
PPTX
Lecture 1: basic syntax
PPT
6 operators-in-c
1 arithmetic
C bitwise operators
15 bitwise operators
Calculating the hamming code
Module 00 Bitwise Operators in C
Manoch1raw 160512091436
Assignment
Matlab numbers
Bitwise operators
Error detection and correction codes
FPGA Based Decimal Matrix Code for Passive RFID Tag
Comparison of analyzers' diagnostic possibilities at checking 64-bit code
vhdl exp-5
Floating Point Representation premium.pptx
digital logic circuits, digital component floting and fixed point
Hamming code system
Lecture 1: basic syntax
6 operators-in-c
Ad

Viewers also liked (7)

PDF
Designing Teams for Emerging Challenges
PDF
UX, ethnography and possibilities: for Libraries, Museums and Archives
PDF
Study: The Future of VR, AR and Self-Driving Cars
PDF
Visual Design with Data
PDF
Hype vs. Reality: The AI Explainer
PDF
3 Things Every Sales Team Needs to Be Thinking About in 2017
PDF
How to Become a Thought Leader in Your Niche
Designing Teams for Emerging Challenges
UX, ethnography and possibilities: for Libraries, Museums and Archives
Study: The Future of VR, AR and Self-Driving Cars
Visual Design with Data
Hype vs. Reality: The AI Explainer
3 Things Every Sales Team Needs to Be Thinking About in 2017
How to Become a Thought Leader in Your Niche
Ad

Similar to Lesson 11. Pattern 3. Shift operations (20)

PDF
20 issues of porting C++ code on the 64-bit platform
PDF
20 issues of porting C++ code on the 64-bit platform
PDF
Program errors occurring while porting C++ code from 32-bit platforms on 64-b...
PDF
Safety of 64-bit code
PDF
Lesson 9. Pattern 1. Magic numbers
PDF
A collection of examples of 64 bit errors in real programs
PDF
A Collection of Examples of 64-bit Errors in Real Programs
PDF
A Collection of Examples of 64-bit Errors in Real Programs
PDF
Monitoring a program that monitors computer networks
PDF
Lesson 6. Errors in 64-bit code
PDF
Static code analysis for verification of the 64-bit applications
PDF
Lesson 22. Pattern 14. Overloaded functions
PDF
About size_t and ptrdiff_t
PDF
Monitoring a program that monitors computer networks
PDF
The forgotten problems of 64-bit programs development
PDF
Lesson 19. Pattern 11. Serialization and data interchange
PDF
Wade not in unknown waters. Part three.
PDF
Lesson 24. Phantom errors
PDF
The article is a report about testing of portability of Loki library with 64-...
PDF
A 64-bit horse that can count
20 issues of porting C++ code on the 64-bit platform
20 issues of porting C++ code on the 64-bit platform
Program errors occurring while porting C++ code from 32-bit platforms on 64-b...
Safety of 64-bit code
Lesson 9. Pattern 1. Magic numbers
A collection of examples of 64 bit errors in real programs
A Collection of Examples of 64-bit Errors in Real Programs
A Collection of Examples of 64-bit Errors in Real Programs
Monitoring a program that monitors computer networks
Lesson 6. Errors in 64-bit code
Static code analysis for verification of the 64-bit applications
Lesson 22. Pattern 14. Overloaded functions
About size_t and ptrdiff_t
Monitoring a program that monitors computer networks
The forgotten problems of 64-bit programs development
Lesson 19. Pattern 11. Serialization and data interchange
Wade not in unknown waters. Part three.
Lesson 24. Phantom errors
The article is a report about testing of portability of Loki library with 64-...
A 64-bit horse that can count

Recently uploaded (20)

PDF
EIS-Webinar-Regulated-Industries-2025-08.pdf
PPTX
AQUEEL MUSHTAQUE FAKIH COMPUTER CENTER .
PDF
NewMind AI Journal Monthly Chronicles - August 2025
PDF
Human Computer Interaction Miterm Lesson
PDF
A symptom-driven medical diagnosis support model based on machine learning te...
PDF
5-Ways-AI-is-Revolutionizing-Telecom-Quality-Engineering.pdf
PDF
CCUS-as-the-Missing-Link-to-Net-Zero_AksCurious.pdf
PDF
Streamline Vulnerability Management From Minimal Images to SBOMs
PDF
Data Virtualization in Action: Scaling APIs and Apps with FME
PDF
Transform-Your-Supply-Chain-with-AI-Driven-Quality-Engineering.pdf
PDF
Early detection and classification of bone marrow changes in lumbar vertebrae...
PDF
Altius execution marketplace concept.pdf
PPTX
Report in SIP_Distance_Learning_Technology_Impact.pptx
PDF
A hybrid framework for wild animal classification using fine-tuned DenseNet12...
PDF
substrate PowerPoint Presentation basic one
PDF
zbrain.ai-Scope Key Metrics Configuration and Best Practices.pdf
PDF
giants, standing on the shoulders of - by Daniel Stenberg
PDF
Examining Bias in AI Generated News Content.pdf
PPTX
AI-driven Assurance Across Your End-to-end Network With ThousandEyes
PDF
NewMind AI Weekly Chronicles – August ’25 Week IV
EIS-Webinar-Regulated-Industries-2025-08.pdf
AQUEEL MUSHTAQUE FAKIH COMPUTER CENTER .
NewMind AI Journal Monthly Chronicles - August 2025
Human Computer Interaction Miterm Lesson
A symptom-driven medical diagnosis support model based on machine learning te...
5-Ways-AI-is-Revolutionizing-Telecom-Quality-Engineering.pdf
CCUS-as-the-Missing-Link-to-Net-Zero_AksCurious.pdf
Streamline Vulnerability Management From Minimal Images to SBOMs
Data Virtualization in Action: Scaling APIs and Apps with FME
Transform-Your-Supply-Chain-with-AI-Driven-Quality-Engineering.pdf
Early detection and classification of bone marrow changes in lumbar vertebrae...
Altius execution marketplace concept.pdf
Report in SIP_Distance_Learning_Technology_Impact.pptx
A hybrid framework for wild animal classification using fine-tuned DenseNet12...
substrate PowerPoint Presentation basic one
zbrain.ai-Scope Key Metrics Configuration and Best Practices.pdf
giants, standing on the shoulders of - by Daniel Stenberg
Examining Bias in AI Generated News Content.pdf
AI-driven Assurance Across Your End-to-end Network With ThousandEyes
NewMind AI Weekly Chronicles – August ’25 Week IV

Lesson 11. Pattern 3. Shift operations

  • 1. Lesson 11. Pattern 3. Shift operations It is easy to make a mistake in code that works with separate bits. The pattern of 64-bit errors under consideration relates to shift operations. Here is an example of code: ptrdiff_t SetBitN(ptrdiff_t value, unsigned bitNum) { ptrdiff_t mask = 1 << bitNum; return value | mask; } This code works well on a 32-bit architecture and allows you to set a bit with numbers from 0 to 31 into one. After porting the program to a 64-bit platform you need to set bits from 0 to 63. But this code will never set the bits with the numbers 32-63. Note that the numerical literal "1" has int type and causes an overflow when a shift in 32 positions occurs as shown in Figure 1. As a result, we will get 0 (Figure 1-B) or 1 (Figure 1-C) depending on the compiler implementation. Figure 1 - a) Correct setting of the 31-st bit in a 32-bit code; b,c) - Incorrect setting of the 32-nd bit on a 64-bit system (two variants of behavior) To correct the code we must make the type of the constant "1" the same as that of mask variable: ptrdiff_t mask = ptrdiff_t(1) << bitNum;
  • 2. Note also that the non-corrected code will lead to one more interesting error. When setting the 31-st bit on a 64-bit system, the function's result will be the value 0xffffffff80000000 (see Figure 2). The result of the expression 1 << 31 is the negative number -2147483648. This number is presented in a 64-bit integer variable as 0xffffffff80000000. Figure 2 - The error of setting the 31-st bit on a 64-bit system. You should remember and take into consideration the effects of shifting values of different types. To better understand all said above, consider some interesting expressions with shifts in a 64-bit system shown in Table 1. Table 1 - Expressions with shifts and their results in a 64-bit system (we used Visual C++ 2005 compiler) The type of errors we have described is considered dangerous not only from the viewpoint of program operation correctness but from the viewpoint of security as well. Potentially, by manipulating with the input data of such incorrect functions one can get inadmissible rights when, for example, dealing with processing of access permissions' masks defined by separate bits. Questions related to exploiting errors in 64-bit code for application cracking and compromise are described in the article "Safety of 64-bit code". Now a subtler example: struct BitFieldStruct { unsigned short a:15; unsigned short b:13; }; BitFieldStruct obj; obj.a = 0x4000; size_t addr = obj.a << 17; //Sign Extension
  • 3. printf("addr 0x%Ixn", addr); //Output on 32-bit system: 0x80000000 //Output on 64-bit system: 0xffffffff80000000 In the 32-bit environment, the order of calculating the expression will be as shown in Figure 3. Figure 3 - Calculation of expression in 32-bit code Note that a sign extension of "unsigned short" type to "signed int" takes place when calculating "obj.a << 17". To make it clear, consider the following code: #include <stdio.h> template <typename T> void PrintType(T) { printf("type is %s %d-bitn", (T)-1 < 0 ? "signed" : "unsigned", sizeof(T)*8); } struct BitFieldStruct { unsigned short a:15; unsigned short b:13; }; int main(void)
  • 4. { BitFieldStruct bf; PrintType( bf.a ); PrintType( bf.a << 2); return 0; } Result: type is unsigned 16-bit type is signed 32-bit Now let us see the consequence of the sign extension in a 64-bit code. The sequence of calculating the expression is shown in Figure 4. Figure 4 - Calculation of expression in 64-bit code The member of "obj.a" structure is converted from the bit field of "unsigned short" type to "int". "obj.a << 17" expression has "int" type but it is converted to ptrdiff_t and then to size_t before it is assigned to addr variable. As a result, we will get the value 0xffffffff80000000 instead of 0x0000000080000000 expected.
  • 5. Be careful when working with bit fields. To avoid the situation described in our example we need only to explicitly convert "obj.a" to size_t type. ... size_t addr = size_t(obj.a) << 17; printf("addr 0x%Ixn", addr); //Output on 32-bit system: 0x80000000 //Output on 64-bit system: 0x80000000 Diagnosis Potentially unsafe shifts are detected by PVS-Studio static analyzer when it detects an implicit extension of a 32-bit type to memsize type. The analyzer will warn you about the unsafe construct with the diagnostic warning V101. The shift operation is not suspicious by itself. But the analyzer detects an implicit extension of int type to memsize type when it is assigned to a variable, and informs the programmer about it to check the code fragment that may contain an error. Correspondingly, when there is no extension, the analyzer considers the code safe. For example: "int mask = 1 << bitNum;". The course authors: Andrey Karpov ([email protected]), Evgeniy Ryzhkov ([email protected]). The rightholder of the course "Lessons on development of 64-bit C/C++ applications" is OOO "Program Verification Systems". The company develops software in the sphere of source program code analysis. The company's site: http://www.viva64.com. Contacts: e-mail: [email protected], Tula, 300027, PO box 1800