SlideShare una empresa de Scribd logo
1 de 8
Descargar para leer sin conexión
A 64-bit horse that can count
Author: Andrey Karpov

Date: 11.05.2009


Abstract
The article concerns the peculiarities of Visual C++ compiler's behavior when generating 64-bit code and
possible errors relating to it.


Introduction
The phenomenon of "The Clever Hans", Mr. von Osten's horse, was described in 1911 [1]. The Clever
Hans was famous because of his ability to read and solve mathematical problems by tapping with his
front hoof. Of course, there were a lot of skeptics. That's why a team of experts tested Hans' abilities
and proved that the horse was showing them without any help of Mr. von Osten. But how could a
common horse possess such an intellectual level - a human one?! The psychologist O. Pfungst carried
out some very thorough experiments and discovered that Hans received very faint unintentional hints
from those who were asking him questions. For example, when people asked Hans about anything they
started to stare at his front hoof with the help of which the horse "answered". But as soon as Hans had
tapped the right number, they raised their eyes or head just a little waiting for him to finish his answer.
And the horse, that had been trained to note and use these very subtle motions considered them as
signals to stop his action. From aside it looked as if the horse had given the right answer to the question.

Such a wonderful horse it was that counted and solved arithmetic problems although he was unable to
do it. 64-bit programs turned out to be such digital horses of the beginning of the 21st century, many of
which cannot count either although are successful in pretending to do so. Let's consider this
phenomenon in detail.


1. Potential errors
I am the author and co-author of some articles devoted to the problems of developing 64-bit
applications. You can see the articles on our site: http://www.viva64.com/articles/64-bit-development/.
In these articles, I try to use the term "a potential error" or "a hidden error" rather than just "an error"
[2, 3, 4].

This is explained by that one and the same code can be viewed upon as both correct and incorrect
depending on its purpose. A simple example - using a variable of int type for indexing an array's items. If
we address an array of graphics windows with the help of this variable, everything is alright. We never
need, and moreover it is impossible, to operate billions of windows. But when we use a variable of int
type for indexing an array's items in 64-bit mathematical programs or data bases, it can well be a
problem when the number of items excesses 0..INT_MAX range.

But there is one more much subtler reason to call errors "potential". The point is that it depends not
only on the input data but on the mood of the compiler's optimizer if an error occurs or not. I have been
avoiding this topic for a long time for most of such errors occur explicitly in the debug-version and only
in release-versions they are "potential". But not every program built as debug can be debugged at large
data sizes. There is a situation when the debug-version is tested only at very small sizes of data. And
overload testing and testing by end users at actual data is performed only in release-versions where
errors can be temporarily hidden. That's why I decided to tell you what I know about it. I hope that I will
manage to persuade you that it is dangerous to rely only on the checks of the execution stage (unit-
tests, dynamic analysis, manual testing) when porting a program on a different platform. You will say
that all this is meant for promoting Viva64 tool. Yes, you are right, but still read the horror stories I'm
going to tell you. I am fond of telling them.


2. How it all begun
- Why do you have two identical JMPs in a row in your code?

- What if the first one wouldn't work?



I faced the peculiarities of Visual C++ 2005 compiler's optimization for the first time when developing
PortSample program. This is a project included into Viva64 distribution kit and is intended for
demonstrating all the errors which Viva64 analyzer diagnoses. The examples included into this project
must work correctly in 32-bit mode and cause errors in 64-bit one. Everything was alright in the debug-
version but I faced difficulties in the release-version. The code which was to lead to a hang or crash in
64-bit mode worked successfully! The cause lay in optimization. The solution consisted in additional
redundant complication of the examples' code and adding "volatile" key words which you can see in
PortSample project in a great number.

The same relates to Visual C++ 2008. The code differs a bit but everything written in this article can be
applied both to Visual C++ 2005 and Visual C++ 2008. We won't make any difference between them
further.

If you think that it is good that some errors don't occur, refuse this thought. Code with such errors
becomes very unstable and a smallest change of it not relating directly to an error can cause change of
the code's behavior. To make sure, I would like to point out that this is not the fault of the compiler but
of the hidden defects of the code. Further, we will show sample phantom errors which disappear and
occur in release-versions when smallest alterations of the code are introduced and which you have to
hunt for a long time.


3. Phantoms
The section will be long and boring, so I will begin with a funny story which is an abstract of the section:

Once Heracles was walking by a lake and there he saw Hydra. He ran up to her and cut her single head
off. But instead of one head two more grew. Heracles cut them off too but 4 more appeared. He cut the 4
heads off - and there were 8 ones... So passed one hour, two hours, three hours... And then Heracles cut
Hydra's 32768 heads off and Hydra died for she was 16-bit.

Like in this funny story errors lie in types' overflow which can occur or fail to occur depending on the
code the compiler will generate when optimization is enabled. Let's consider the first example of the
code which works in release mode although it shouldn't be so:

int index = 0;
size_t arraySize = ...;

for (size_t i = 0; i != arraySize; i++)

    array[index++] = BYTE(i);

This code fills the whole array with values correctly even if the array's size is much larger than INT_MAX.
Theoretically it is impossible because index variable has int type. Some time later, because of the
overflow access to items by a negative index must occur. But optimization leads to generating the
following code:

0000000140001040           mov                byte ptr [rcx+rax],cl

0000000140001043           add                rcx,1

0000000140001047           cmp                rcx,rbx

000000014000104A           jne                wmain+40h (140001040h)

As you can see, 64-bit registers are used and there is no overflow. But let's alter the code a bit:

int index = 0;

for (size_t i = 0; i != arraySize; i++)

{

    array[index] = BYTE(index);

    ++index;

}

Let's consider that the code look more beautiful this way. I think you will agree that functionally it
remains the same. But the result will be quite different - a program crash will occur. Let's examine the
code generated by the compiler:

0000000140001040           movsxd             rcx,r8d

0000000140001043           mov                byte ptr [rcx+rbx],r8b

0000000140001047           add                r8d,1

000000014000104B           sub                rax,1

000000014000104F           jne                wmain+40h (140001040h)

That very overflow occurs that must occur in the previous example as well. r8d = 0x80000000 register's
value extends into rcx as 0xffffffff80000000. The consequence is writing outside the limits of the array.

Let's consider another example of optimization and see how easy it is to spoil everything:

unsigned index = 0;

for (size_t i = 0; i != arraySize; ++i) {

    array[index++] = 1;
if (array[i] != 1) {

        printf("Errorn");

        break;

    }

}

Assembler code:

0000000140001040           mov                byte ptr [rdx],1

0000000140001043           add                rdx,1

0000000140001047           cmp                byte ptr [rcx+rax],1

000000014000104B           jne                wmain+58h (140001058h)

000000014000104D           add                rcx,1

0000000140001051           cmp                rcx,rdi

0000000140001054           jne                wmain+40h (140001040h)

The compiler decided to use 64-bit register rdx for storing index variable. As a result the code may
correctly process arrays with the size more than UINT_MAX.

But the world is fragile. It is enough just to complicate the code a bit and it becomes incorrect:

volatile unsigned volatileVar = 1;

...

unsigned index = 0;

for (size_t i = 0; i != arraySize; ++i) {

    array[index] = 1;

    index += volatileVar;

    if (array[i] != 1) {

        printf("Errorn");

        break;

    }

}

Using "index += volatileVar;" expression instead of index++ leads to participation of 32-bit registers in
the code and therefore occurrence of overflows:

0000000140001040           mov                ecx,r8d
0000000140001043           add               r8d,dword ptr [volatileVar (140003020h)]

000000014000104A           mov               byte ptr [rcx+rax],1

000000014000104E           cmp               byte ptr [rdx+rax],1

0000000140001052           jne               wmain+5Fh (14000105Fh)

0000000140001054           add               rdx,1

0000000140001058           cmp               rdx,rdi

000000014000105B           jne               wmain+40h (140001040h)

In conclusion I will give an interesting but large example. Unfortunately, I didn't manage to abridge it
because it was necessary to show the behavior. It is this why such errors are dangerous for you cannot
foresee the consequence of a smallest alteration of the code.

ptrdiff_t UnsafeCalcIndex(int x, int y, int width) {

    int result = x + y * width;

    return result;

}

...

int domainWidth = 50000;

int domainHeght = 50000;

for (int x = 0; x != domainWidth; ++x)

    for (int y = 0; y != domainHeght; ++y)

      array[UnsafeCalcIndex(x, y, domainWidth)] = 1;

This code cannot fill correctly the array consisting of 50000*50000 items. It is impossible because when
calculating "int result = x + y * width;" an overflow must occur.

Miraculously the array is filled correctly in the release-version. UnsafeCalcIndex function integrates
inside the loop and 64-bit registers are used:

0000000140001052           test              rsi,rsi

0000000140001055           je                wmain+6Ch (14000106Ch)

0000000140001057           lea               rcx,[r9+rax]

000000014000105B           mov               rdx,rsi

000000014000105E           xchg              ax,ax

0000000140001060           mov               byte ptr [rcx],1

0000000140001063           add               rcx,rbx
0000000140001066           sub               rdx,1

000000014000106A           jne               wmain+60h (140001060h)

000000014000106C           add               r9,1

0000000140001070           cmp               r9,rbx

0000000140001073           jne               wmain+52h (140001052h)

All this takes place because UnsafeCalcIndex function is simple and can be integrate easily. But once you
make it a bit more complicated or the compiler considers that it shouldn't be integrated, an error occurs
at large data sizes.

Let's modify (complicate) UnsafeCalcIndex function a bit. Pay attention that the function's logic has not
been changed at all:

ptrdiff_t UnsafeCalcIndex(int x, int y, int width) {

    int result = 0;

    if (width != 0)

      result = y * width;

    return result + x;

}

The result is a program crash when the array's limits are exceeded:

0000000140001050           test              esi,esi

0000000140001052           je                wmain+7Ah (14000107Ah)

0000000140001054           mov               r8d,ecx

0000000140001057           mov               r9d,esi

000000014000105A           xchg              ax,ax

000000014000105D           xchg              ax,ax

0000000140001060           mov               eax,ecx

0000000140001062           test              ebx,ebx

0000000140001064           cmovne            eax,r8d

0000000140001068           add               r8d,ebx

000000014000106B           cdqe

000000014000106D           add               rax,rdx

0000000140001070           sub               r9,1

0000000140001074           mov               byte ptr [rax+rdi],1
0000000140001078           jne                wmain+60h (140001060h)

000000014000107A           add                rdx,1

000000014000107E           cmp                rdx,r12

0000000140001081           jne                wmain+50h (140001050h)

I think you have become bored by this moment. I am sorry. I just wanted to show you how simply an
efficient 64-bit program may fail after introducing most harmless alterations into it or building it by
another version of the compiler.


4. Diagnosis of potential errors
                                                              A program is a sequence of processing errors.
                                                                                   (c) An unknown author

I suppose that many already existing 64-bit applications or those which will be soon ported on 64-bit
systems, can suddenly spring more and more unpleasant surprises. A lot of defects may be found in
them when increasing the size of input data which was unavailable for processing in 32-bit systems.
Hidden defects can suddenly occur during further modification of the program code or change of
libraries or a compiler.

Like in the story about the horse, the first impression can be deceptive. It can only seem to you that
your program processes large data sizes successfully. You need to perform a more thorough check to
see exactly if your 64-bit horse can actually count.

To make sure that a 64-bit program is correct, the minimum thing you can do is to use not only the
release-version but the debug-version as well at all stages of testing. Keep in mind that it is a necessary
but far not sufficient condition. If your tests use data sets which, for example, don't cover a large main
memory size, an error can fail to occur both in release- and debug-versions [5]. It is necessary to extend
unit-tests and data sets for overload and manual testing. It is necessary to make algorithms process new
data combinations which are available only in 64-bit systems [6].

An alternative way of diagnosing 64-bit errors lies in using static analysis tools. It is much more radical
and safe than guessing if you have added enough tests or not. It is convenient for it doesn't demand
using the debug-version for crunching gigabytes of data.

The point of the method is to perform a full analysis of a project for a single time when porting the
program and look through all the diagnostic messages on suspicious sections in the code. Many are
frightened off by the list of thousands and tens of thousands of warnings. But the total time spent at
once on analyzing them will be much less than the time spent on correcting various bug-reports
appearing literally from nowhere for many years. It will be those very phantoms described above.
Besides, when you start working with the list of warnings you will soon find out that most of them can
be filtered and there will be much less work than you have expected. Further, you will have only to use
static analysis for a new code and it doesn't take much time.

Of course, when speaking about a toolkit for searching 64-bit phantoms, I offer the tool that we develop
- Viva64. By the way, this tool will soon be included into PVS-Studio which will unite all our static
analysis tools.
To be more objective and avoid constantly being driven out from sites with this article as an advertising
one, I will mention other tools as well. We should list Gimpel PC-Lint and Parasoft C++test. Rules for
testing 64-bit errors are implemented in them too, but they possess less diagnostic abilities than a highly
tailored Viva64 [7]. There is also Abraxas CodeCheck in the new version of which (14.5) functions of
diagnosing 64-bit errors are also implemented but I don't possess more detailed information about it.


Conclusion
I will be glad if this article helps you master new platforms easier, for you will know what hidden
problems can occur. Thank you for attention.


References
    1. Wikipedia. Clever Hans. http://www.viva64.com/go.php?url=223.
    2. Andrey Karpov. 64 bits, Wp64, Visual Studio 2008, Viva64 and all the rest...
       http://www.viva64.com/art-1-2-621693540.html
    3. Andrey Karpov, Evgeniy Ryzhkov. Static code analysis for verification of the 64-bit applications.
       http://www.viva64.com/art-1-2-184080346.html
    4. Andrey Karpov. Seven Steps of Migrating a Program to a 64-bit System.
       http://www.viva64.com/art-1-2-850243650.html
    5. Andrey Karpov, Evgeniy Ryzhkov. 20 issues of porting C++ code on the 64-bit platform.
       http://www.viva64.com/art-1-2-599168895.html
    6. Andrey Karpov, Evgeniy Ryzhkov. Traps detection during migration of C and C++ code to 64-bit
       Windows. http://www.viva64.com/art-1-2-2140958669.html
    7. Andrey Karpov. Comparison of analyzers' diagnostic possibilities at checking 64-bit code.
       http://www.viva64.com/art-1-2-914146540.html

Más contenido relacionado

La actualidad más candente

A collection of examples of 64 bit errors in real programs
A collection of examples of 64 bit errors in real programsA collection of examples of 64 bit errors in real programs
A collection of examples of 64 bit errors in real programsMichael Scovetta
 
Acm aleppo cpc training fifth session
Acm aleppo cpc training fifth sessionAcm aleppo cpc training fifth session
Acm aleppo cpc training fifth sessionAhmad Bashar Eter
 
Mathematicians: Trust, but Verify
Mathematicians: Trust, but VerifyMathematicians: Trust, but Verify
Mathematicians: Trust, but VerifyAndrey Karpov
 
Intel JIT Talk
Intel JIT TalkIntel JIT Talk
Intel JIT Talkiamdvander
 
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2PVS-Studio
 
Big Brother helps you
Big Brother helps youBig Brother helps you
Big Brother helps youPVS-Studio
 
Technologies used in the PVS-Studio code analyzer for finding bugs and potent...
Technologies used in the PVS-Studio code analyzer for finding bugs and potent...Technologies used in the PVS-Studio code analyzer for finding bugs and potent...
Technologies used in the PVS-Studio code analyzer for finding bugs and potent...Andrey Karpov
 
PVS-Studio vs Chromium - Continuation
PVS-Studio vs Chromium - ContinuationPVS-Studio vs Chromium - Continuation
PVS-Studio vs Chromium - ContinuationPVS-Studio
 
Java căn bản - Chapter6
Java căn bản - Chapter6Java căn bản - Chapter6
Java căn bản - Chapter6Vince Vo
 
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source CodeA Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source CodePVS-Studio
 
05. Conditional Statements
05. Conditional Statements05. Conditional Statements
05. Conditional StatementsIntro C# Book
 
Errors that static code analysis does not find because it is not used
Errors that static code analysis does not find because it is not usedErrors that static code analysis does not find because it is not used
Errors that static code analysis does not find because it is not usedAndrey Karpov
 
Sensors and Journalism Seminar, University of British Columbia - Day 1
Sensors and Journalism Seminar, University of British Columbia - Day 1Sensors and Journalism Seminar, University of British Columbia - Day 1
Sensors and Journalism Seminar, University of British Columbia - Day 1ferguspitt
 
A look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
A look into the sanitizer family (ASAN & UBSAN) by Akul PillaiA look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
A look into the sanitizer family (ASAN & UBSAN) by Akul PillaiCysinfo Cyber Security Community
 

La actualidad más candente (18)

A collection of examples of 64 bit errors in real programs
A collection of examples of 64 bit errors in real programsA collection of examples of 64 bit errors in real programs
A collection of examples of 64 bit errors in real programs
 
Acm aleppo cpc training fifth session
Acm aleppo cpc training fifth sessionAcm aleppo cpc training fifth session
Acm aleppo cpc training fifth session
 
Mathematicians: Trust, but Verify
Mathematicians: Trust, but VerifyMathematicians: Trust, but Verify
Mathematicians: Trust, but Verify
 
Intel JIT Talk
Intel JIT TalkIntel JIT Talk
Intel JIT Talk
 
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 2
 
Big Brother helps you
Big Brother helps youBig Brother helps you
Big Brother helps you
 
Technologies used in the PVS-Studio code analyzer for finding bugs and potent...
Technologies used in the PVS-Studio code analyzer for finding bugs and potent...Technologies used in the PVS-Studio code analyzer for finding bugs and potent...
Technologies used in the PVS-Studio code analyzer for finding bugs and potent...
 
PVS-Studio vs Chromium - Continuation
PVS-Studio vs Chromium - ContinuationPVS-Studio vs Chromium - Continuation
PVS-Studio vs Chromium - Continuation
 
Java căn bản - Chapter6
Java căn bản - Chapter6Java căn bản - Chapter6
Java căn bản - Chapter6
 
Primitive Data Types and Variables Lesson 02
Primitive Data Types and Variables Lesson 02Primitive Data Types and Variables Lesson 02
Primitive Data Types and Variables Lesson 02
 
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source CodeA Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
A Unicorn Seeking Extraterrestrial Life: Analyzing SETI@home's Source Code
 
05. Conditional Statements
05. Conditional Statements05. Conditional Statements
05. Conditional Statements
 
Cppcheck
CppcheckCppcheck
Cppcheck
 
Errors that static code analysis does not find because it is not used
Errors that static code analysis does not find because it is not usedErrors that static code analysis does not find because it is not used
Errors that static code analysis does not find because it is not used
 
C# loops
C# loopsC# loops
C# loops
 
Sensors and Journalism Seminar, University of British Columbia - Day 1
Sensors and Journalism Seminar, University of British Columbia - Day 1Sensors and Journalism Seminar, University of British Columbia - Day 1
Sensors and Journalism Seminar, University of British Columbia - Day 1
 
C++ Presentation
C++ PresentationC++ Presentation
C++ Presentation
 
A look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
A look into the sanitizer family (ASAN & UBSAN) by Akul PillaiA look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
A look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
 

Similar a A 64-bit horse that can count

Lesson 24. Phantom errors
Lesson 24. Phantom errorsLesson 24. Phantom errors
Lesson 24. Phantom errorsPVS-Studio
 
How to avoid bugs using modern C++
How to avoid bugs using modern C++How to avoid bugs using modern C++
How to avoid bugs using modern C++PVS-Studio
 
Optimization in the world of 64-bit errors
Optimization  in the world of 64-bit errorsOptimization  in the world of 64-bit errors
Optimization in the world of 64-bit errorsPVS-Studio
 
Monitoring a program that monitors computer networks
Monitoring a program that monitors computer networksMonitoring a program that monitors computer networks
Monitoring a program that monitors computer networksPVS-Studio
 
I just had to check ICQ project
I just had to check ICQ projectI just had to check ICQ project
I just had to check ICQ projectPVS-Studio
 
Tesseract. Recognizing Errors in Recognition Software
Tesseract. Recognizing Errors in Recognition SoftwareTesseract. Recognizing Errors in Recognition Software
Tesseract. Recognizing Errors in Recognition SoftwareAndrey Karpov
 
Re-checking the ReactOS project - a large report
Re-checking the ReactOS project - a large reportRe-checking the ReactOS project - a large report
Re-checking the ReactOS project - a large reportPVS-Studio
 
Lesson 13. Pattern 5. Address arithmetic
Lesson 13. Pattern 5. Address arithmeticLesson 13. Pattern 5. Address arithmetic
Lesson 13. Pattern 5. Address arithmeticPVS-Studio
 
Lesson 9. Pattern 1. Magic numbers
Lesson 9. Pattern 1. Magic numbersLesson 9. Pattern 1. Magic numbers
Lesson 9. Pattern 1. Magic numbersPVS-Studio
 
How to make fewer errors at the stage of code writing. Part N1.
How to make fewer errors at the stage of code writing. Part N1.How to make fewer errors at the stage of code writing. Part N1.
How to make fewer errors at the stage of code writing. Part N1.PVS-Studio
 
Archeology for Entertainment, or Checking Microsoft Word 1.1a with PVS-Studio
Archeology for Entertainment, or Checking Microsoft Word 1.1a with PVS-StudioArcheology for Entertainment, or Checking Microsoft Word 1.1a with PVS-Studio
Archeology for Entertainment, or Checking Microsoft Word 1.1a with PVS-StudioAndrey Karpov
 
A nice 64-bit error in C
A  nice 64-bit error in CA  nice 64-bit error in C
A nice 64-bit error in CPVS-Studio
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youAndrey Karpov
 
A fresh eye on Oracle VM VirtualBox
A fresh eye on Oracle VM VirtualBoxA fresh eye on Oracle VM VirtualBox
A fresh eye on Oracle VM VirtualBoxPVS-Studio
 
LibRaw, Coverity SCAN, PVS-Studio
LibRaw, Coverity SCAN, PVS-StudioLibRaw, Coverity SCAN, PVS-Studio
LibRaw, Coverity SCAN, PVS-StudioAndrey Karpov
 
Accord.Net: Looking for a Bug that Could Help Machines Conquer Humankind
Accord.Net: Looking for a Bug that Could Help Machines Conquer HumankindAccord.Net: Looking for a Bug that Could Help Machines Conquer Humankind
Accord.Net: Looking for a Bug that Could Help Machines Conquer HumankindPVS-Studio
 
Wade not in unknown waters. Part three.
Wade not in unknown waters. Part three.Wade not in unknown waters. Part three.
Wade not in unknown waters. Part three.PVS-Studio
 
CppCat Static Analyzer Review
CppCat Static Analyzer ReviewCppCat Static Analyzer Review
CppCat Static Analyzer ReviewAndrey Karpov
 
Analysis of Godot Engine's Source Code
Analysis of Godot Engine's Source CodeAnalysis of Godot Engine's Source Code
Analysis of Godot Engine's Source CodePVS-Studio
 
PVS-Studio for Linux Went on a Tour Around Disney
PVS-Studio for Linux Went on a Tour Around DisneyPVS-Studio for Linux Went on a Tour Around Disney
PVS-Studio for Linux Went on a Tour Around DisneyPVS-Studio
 

Similar a A 64-bit horse that can count (20)

Lesson 24. Phantom errors
Lesson 24. Phantom errorsLesson 24. Phantom errors
Lesson 24. Phantom errors
 
How to avoid bugs using modern C++
How to avoid bugs using modern C++How to avoid bugs using modern C++
How to avoid bugs using modern C++
 
Optimization in the world of 64-bit errors
Optimization  in the world of 64-bit errorsOptimization  in the world of 64-bit errors
Optimization in the world of 64-bit errors
 
Monitoring a program that monitors computer networks
Monitoring a program that monitors computer networksMonitoring a program that monitors computer networks
Monitoring a program that monitors computer networks
 
I just had to check ICQ project
I just had to check ICQ projectI just had to check ICQ project
I just had to check ICQ project
 
Tesseract. Recognizing Errors in Recognition Software
Tesseract. Recognizing Errors in Recognition SoftwareTesseract. Recognizing Errors in Recognition Software
Tesseract. Recognizing Errors in Recognition Software
 
Re-checking the ReactOS project - a large report
Re-checking the ReactOS project - a large reportRe-checking the ReactOS project - a large report
Re-checking the ReactOS project - a large report
 
Lesson 13. Pattern 5. Address arithmetic
Lesson 13. Pattern 5. Address arithmeticLesson 13. Pattern 5. Address arithmetic
Lesson 13. Pattern 5. Address arithmetic
 
Lesson 9. Pattern 1. Magic numbers
Lesson 9. Pattern 1. Magic numbersLesson 9. Pattern 1. Magic numbers
Lesson 9. Pattern 1. Magic numbers
 
How to make fewer errors at the stage of code writing. Part N1.
How to make fewer errors at the stage of code writing. Part N1.How to make fewer errors at the stage of code writing. Part N1.
How to make fewer errors at the stage of code writing. Part N1.
 
Archeology for Entertainment, or Checking Microsoft Word 1.1a with PVS-Studio
Archeology for Entertainment, or Checking Microsoft Word 1.1a with PVS-StudioArcheology for Entertainment, or Checking Microsoft Word 1.1a with PVS-Studio
Archeology for Entertainment, or Checking Microsoft Word 1.1a with PVS-Studio
 
A nice 64-bit error in C
A  nice 64-bit error in CA  nice 64-bit error in C
A nice 64-bit error in C
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for you
 
A fresh eye on Oracle VM VirtualBox
A fresh eye on Oracle VM VirtualBoxA fresh eye on Oracle VM VirtualBox
A fresh eye on Oracle VM VirtualBox
 
LibRaw, Coverity SCAN, PVS-Studio
LibRaw, Coverity SCAN, PVS-StudioLibRaw, Coverity SCAN, PVS-Studio
LibRaw, Coverity SCAN, PVS-Studio
 
Accord.Net: Looking for a Bug that Could Help Machines Conquer Humankind
Accord.Net: Looking for a Bug that Could Help Machines Conquer HumankindAccord.Net: Looking for a Bug that Could Help Machines Conquer Humankind
Accord.Net: Looking for a Bug that Could Help Machines Conquer Humankind
 
Wade not in unknown waters. Part three.
Wade not in unknown waters. Part three.Wade not in unknown waters. Part three.
Wade not in unknown waters. Part three.
 
CppCat Static Analyzer Review
CppCat Static Analyzer ReviewCppCat Static Analyzer Review
CppCat Static Analyzer Review
 
Analysis of Godot Engine's Source Code
Analysis of Godot Engine's Source CodeAnalysis of Godot Engine's Source Code
Analysis of Godot Engine's Source Code
 
PVS-Studio for Linux Went on a Tour Around Disney
PVS-Studio for Linux Went on a Tour Around DisneyPVS-Studio for Linux Went on a Tour Around Disney
PVS-Studio for Linux Went on a Tour Around Disney
 

Más de Andrey Karpov

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программистаAndrey Karpov
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developerAndrey Karpov
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Andrey Karpov
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesAndrey Karpov
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewAndrey Karpov
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокAndrey Karpov
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Andrey Karpov
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesAndrey Karpov
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?Andrey Karpov
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaAndrey Karpov
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)Andrey Karpov
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Andrey Karpov
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerAndrey Karpov
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareAndrey Karpov
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineAndrey Karpov
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsAndrey Karpov
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++Andrey Karpov
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?Andrey Karpov
 
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOpsPVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOpsAndrey Karpov
 

Más de Andrey Karpov (20)

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developer
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature Overview
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
PVS-Studio в 2021
PVS-Studio в 2021PVS-Studio в 2021
PVS-Studio в 2021
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and Java
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal Engine
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOpsPVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
 

Último

Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 

Último (20)

Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 

A 64-bit horse that can count

  • 1. A 64-bit horse that can count Author: Andrey Karpov Date: 11.05.2009 Abstract The article concerns the peculiarities of Visual C++ compiler's behavior when generating 64-bit code and possible errors relating to it. Introduction The phenomenon of "The Clever Hans", Mr. von Osten's horse, was described in 1911 [1]. The Clever Hans was famous because of his ability to read and solve mathematical problems by tapping with his front hoof. Of course, there were a lot of skeptics. That's why a team of experts tested Hans' abilities and proved that the horse was showing them without any help of Mr. von Osten. But how could a common horse possess such an intellectual level - a human one?! The psychologist O. Pfungst carried out some very thorough experiments and discovered that Hans received very faint unintentional hints from those who were asking him questions. For example, when people asked Hans about anything they started to stare at his front hoof with the help of which the horse "answered". But as soon as Hans had tapped the right number, they raised their eyes or head just a little waiting for him to finish his answer. And the horse, that had been trained to note and use these very subtle motions considered them as signals to stop his action. From aside it looked as if the horse had given the right answer to the question. Such a wonderful horse it was that counted and solved arithmetic problems although he was unable to do it. 64-bit programs turned out to be such digital horses of the beginning of the 21st century, many of which cannot count either although are successful in pretending to do so. Let's consider this phenomenon in detail. 1. Potential errors I am the author and co-author of some articles devoted to the problems of developing 64-bit applications. You can see the articles on our site: http://www.viva64.com/articles/64-bit-development/. In these articles, I try to use the term "a potential error" or "a hidden error" rather than just "an error" [2, 3, 4]. This is explained by that one and the same code can be viewed upon as both correct and incorrect depending on its purpose. A simple example - using a variable of int type for indexing an array's items. If we address an array of graphics windows with the help of this variable, everything is alright. We never need, and moreover it is impossible, to operate billions of windows. But when we use a variable of int type for indexing an array's items in 64-bit mathematical programs or data bases, it can well be a problem when the number of items excesses 0..INT_MAX range. But there is one more much subtler reason to call errors "potential". The point is that it depends not only on the input data but on the mood of the compiler's optimizer if an error occurs or not. I have been avoiding this topic for a long time for most of such errors occur explicitly in the debug-version and only in release-versions they are "potential". But not every program built as debug can be debugged at large
  • 2. data sizes. There is a situation when the debug-version is tested only at very small sizes of data. And overload testing and testing by end users at actual data is performed only in release-versions where errors can be temporarily hidden. That's why I decided to tell you what I know about it. I hope that I will manage to persuade you that it is dangerous to rely only on the checks of the execution stage (unit- tests, dynamic analysis, manual testing) when porting a program on a different platform. You will say that all this is meant for promoting Viva64 tool. Yes, you are right, but still read the horror stories I'm going to tell you. I am fond of telling them. 2. How it all begun - Why do you have two identical JMPs in a row in your code? - What if the first one wouldn't work? I faced the peculiarities of Visual C++ 2005 compiler's optimization for the first time when developing PortSample program. This is a project included into Viva64 distribution kit and is intended for demonstrating all the errors which Viva64 analyzer diagnoses. The examples included into this project must work correctly in 32-bit mode and cause errors in 64-bit one. Everything was alright in the debug- version but I faced difficulties in the release-version. The code which was to lead to a hang or crash in 64-bit mode worked successfully! The cause lay in optimization. The solution consisted in additional redundant complication of the examples' code and adding "volatile" key words which you can see in PortSample project in a great number. The same relates to Visual C++ 2008. The code differs a bit but everything written in this article can be applied both to Visual C++ 2005 and Visual C++ 2008. We won't make any difference between them further. If you think that it is good that some errors don't occur, refuse this thought. Code with such errors becomes very unstable and a smallest change of it not relating directly to an error can cause change of the code's behavior. To make sure, I would like to point out that this is not the fault of the compiler but of the hidden defects of the code. Further, we will show sample phantom errors which disappear and occur in release-versions when smallest alterations of the code are introduced and which you have to hunt for a long time. 3. Phantoms The section will be long and boring, so I will begin with a funny story which is an abstract of the section: Once Heracles was walking by a lake and there he saw Hydra. He ran up to her and cut her single head off. But instead of one head two more grew. Heracles cut them off too but 4 more appeared. He cut the 4 heads off - and there were 8 ones... So passed one hour, two hours, three hours... And then Heracles cut Hydra's 32768 heads off and Hydra died for she was 16-bit. Like in this funny story errors lie in types' overflow which can occur or fail to occur depending on the code the compiler will generate when optimization is enabled. Let's consider the first example of the code which works in release mode although it shouldn't be so: int index = 0;
  • 3. size_t arraySize = ...; for (size_t i = 0; i != arraySize; i++) array[index++] = BYTE(i); This code fills the whole array with values correctly even if the array's size is much larger than INT_MAX. Theoretically it is impossible because index variable has int type. Some time later, because of the overflow access to items by a negative index must occur. But optimization leads to generating the following code: 0000000140001040 mov byte ptr [rcx+rax],cl 0000000140001043 add rcx,1 0000000140001047 cmp rcx,rbx 000000014000104A jne wmain+40h (140001040h) As you can see, 64-bit registers are used and there is no overflow. But let's alter the code a bit: int index = 0; for (size_t i = 0; i != arraySize; i++) { array[index] = BYTE(index); ++index; } Let's consider that the code look more beautiful this way. I think you will agree that functionally it remains the same. But the result will be quite different - a program crash will occur. Let's examine the code generated by the compiler: 0000000140001040 movsxd rcx,r8d 0000000140001043 mov byte ptr [rcx+rbx],r8b 0000000140001047 add r8d,1 000000014000104B sub rax,1 000000014000104F jne wmain+40h (140001040h) That very overflow occurs that must occur in the previous example as well. r8d = 0x80000000 register's value extends into rcx as 0xffffffff80000000. The consequence is writing outside the limits of the array. Let's consider another example of optimization and see how easy it is to spoil everything: unsigned index = 0; for (size_t i = 0; i != arraySize; ++i) { array[index++] = 1;
  • 4. if (array[i] != 1) { printf("Errorn"); break; } } Assembler code: 0000000140001040 mov byte ptr [rdx],1 0000000140001043 add rdx,1 0000000140001047 cmp byte ptr [rcx+rax],1 000000014000104B jne wmain+58h (140001058h) 000000014000104D add rcx,1 0000000140001051 cmp rcx,rdi 0000000140001054 jne wmain+40h (140001040h) The compiler decided to use 64-bit register rdx for storing index variable. As a result the code may correctly process arrays with the size more than UINT_MAX. But the world is fragile. It is enough just to complicate the code a bit and it becomes incorrect: volatile unsigned volatileVar = 1; ... unsigned index = 0; for (size_t i = 0; i != arraySize; ++i) { array[index] = 1; index += volatileVar; if (array[i] != 1) { printf("Errorn"); break; } } Using "index += volatileVar;" expression instead of index++ leads to participation of 32-bit registers in the code and therefore occurrence of overflows: 0000000140001040 mov ecx,r8d
  • 5. 0000000140001043 add r8d,dword ptr [volatileVar (140003020h)] 000000014000104A mov byte ptr [rcx+rax],1 000000014000104E cmp byte ptr [rdx+rax],1 0000000140001052 jne wmain+5Fh (14000105Fh) 0000000140001054 add rdx,1 0000000140001058 cmp rdx,rdi 000000014000105B jne wmain+40h (140001040h) In conclusion I will give an interesting but large example. Unfortunately, I didn't manage to abridge it because it was necessary to show the behavior. It is this why such errors are dangerous for you cannot foresee the consequence of a smallest alteration of the code. ptrdiff_t UnsafeCalcIndex(int x, int y, int width) { int result = x + y * width; return result; } ... int domainWidth = 50000; int domainHeght = 50000; for (int x = 0; x != domainWidth; ++x) for (int y = 0; y != domainHeght; ++y) array[UnsafeCalcIndex(x, y, domainWidth)] = 1; This code cannot fill correctly the array consisting of 50000*50000 items. It is impossible because when calculating "int result = x + y * width;" an overflow must occur. Miraculously the array is filled correctly in the release-version. UnsafeCalcIndex function integrates inside the loop and 64-bit registers are used: 0000000140001052 test rsi,rsi 0000000140001055 je wmain+6Ch (14000106Ch) 0000000140001057 lea rcx,[r9+rax] 000000014000105B mov rdx,rsi 000000014000105E xchg ax,ax 0000000140001060 mov byte ptr [rcx],1 0000000140001063 add rcx,rbx
  • 6. 0000000140001066 sub rdx,1 000000014000106A jne wmain+60h (140001060h) 000000014000106C add r9,1 0000000140001070 cmp r9,rbx 0000000140001073 jne wmain+52h (140001052h) All this takes place because UnsafeCalcIndex function is simple and can be integrate easily. But once you make it a bit more complicated or the compiler considers that it shouldn't be integrated, an error occurs at large data sizes. Let's modify (complicate) UnsafeCalcIndex function a bit. Pay attention that the function's logic has not been changed at all: ptrdiff_t UnsafeCalcIndex(int x, int y, int width) { int result = 0; if (width != 0) result = y * width; return result + x; } The result is a program crash when the array's limits are exceeded: 0000000140001050 test esi,esi 0000000140001052 je wmain+7Ah (14000107Ah) 0000000140001054 mov r8d,ecx 0000000140001057 mov r9d,esi 000000014000105A xchg ax,ax 000000014000105D xchg ax,ax 0000000140001060 mov eax,ecx 0000000140001062 test ebx,ebx 0000000140001064 cmovne eax,r8d 0000000140001068 add r8d,ebx 000000014000106B cdqe 000000014000106D add rax,rdx 0000000140001070 sub r9,1 0000000140001074 mov byte ptr [rax+rdi],1
  • 7. 0000000140001078 jne wmain+60h (140001060h) 000000014000107A add rdx,1 000000014000107E cmp rdx,r12 0000000140001081 jne wmain+50h (140001050h) I think you have become bored by this moment. I am sorry. I just wanted to show you how simply an efficient 64-bit program may fail after introducing most harmless alterations into it or building it by another version of the compiler. 4. Diagnosis of potential errors A program is a sequence of processing errors. (c) An unknown author I suppose that many already existing 64-bit applications or those which will be soon ported on 64-bit systems, can suddenly spring more and more unpleasant surprises. A lot of defects may be found in them when increasing the size of input data which was unavailable for processing in 32-bit systems. Hidden defects can suddenly occur during further modification of the program code or change of libraries or a compiler. Like in the story about the horse, the first impression can be deceptive. It can only seem to you that your program processes large data sizes successfully. You need to perform a more thorough check to see exactly if your 64-bit horse can actually count. To make sure that a 64-bit program is correct, the minimum thing you can do is to use not only the release-version but the debug-version as well at all stages of testing. Keep in mind that it is a necessary but far not sufficient condition. If your tests use data sets which, for example, don't cover a large main memory size, an error can fail to occur both in release- and debug-versions [5]. It is necessary to extend unit-tests and data sets for overload and manual testing. It is necessary to make algorithms process new data combinations which are available only in 64-bit systems [6]. An alternative way of diagnosing 64-bit errors lies in using static analysis tools. It is much more radical and safe than guessing if you have added enough tests or not. It is convenient for it doesn't demand using the debug-version for crunching gigabytes of data. The point of the method is to perform a full analysis of a project for a single time when porting the program and look through all the diagnostic messages on suspicious sections in the code. Many are frightened off by the list of thousands and tens of thousands of warnings. But the total time spent at once on analyzing them will be much less than the time spent on correcting various bug-reports appearing literally from nowhere for many years. It will be those very phantoms described above. Besides, when you start working with the list of warnings you will soon find out that most of them can be filtered and there will be much less work than you have expected. Further, you will have only to use static analysis for a new code and it doesn't take much time. Of course, when speaking about a toolkit for searching 64-bit phantoms, I offer the tool that we develop - Viva64. By the way, this tool will soon be included into PVS-Studio which will unite all our static analysis tools.
  • 8. To be more objective and avoid constantly being driven out from sites with this article as an advertising one, I will mention other tools as well. We should list Gimpel PC-Lint and Parasoft C++test. Rules for testing 64-bit errors are implemented in them too, but they possess less diagnostic abilities than a highly tailored Viva64 [7]. There is also Abraxas CodeCheck in the new version of which (14.5) functions of diagnosing 64-bit errors are also implemented but I don't possess more detailed information about it. Conclusion I will be glad if this article helps you master new platforms easier, for you will know what hidden problems can occur. Thank you for attention. References 1. Wikipedia. Clever Hans. http://www.viva64.com/go.php?url=223. 2. Andrey Karpov. 64 bits, Wp64, Visual Studio 2008, Viva64 and all the rest... http://www.viva64.com/art-1-2-621693540.html 3. Andrey Karpov, Evgeniy Ryzhkov. Static code analysis for verification of the 64-bit applications. http://www.viva64.com/art-1-2-184080346.html 4. Andrey Karpov. Seven Steps of Migrating a Program to a 64-bit System. http://www.viva64.com/art-1-2-850243650.html 5. Andrey Karpov, Evgeniy Ryzhkov. 20 issues of porting C++ code on the 64-bit platform. http://www.viva64.com/art-1-2-599168895.html 6. Andrey Karpov, Evgeniy Ryzhkov. Traps detection during migration of C and C++ code to 64-bit Windows. http://www.viva64.com/art-1-2-2140958669.html 7. Andrey Karpov. Comparison of analyzers' diagnostic possibilities at checking 64-bit code. http://www.viva64.com/art-1-2-914146540.html