SlideShare a Scribd company logo
1 of 4
Download to read offline
Wade not in unknown waters. Part one.
Author: Andrey Karpov
Date: 27.01.2012
We decided to write several small posts on how C/C++ programmers play with fire without knowing it.
The first post will be devoted to an attempt to explicitly call a constructor.
Programmers are lazy creatures. That's why they tend to solve a task using minimal code amount. This
aim is praiseworthy and good. But the main point is not get too involved in the process and stop at the
right time.
For example, programmers are too lazy to create a single initialization function in a class so that it could
be called from various constructors later. They think: "What for do I need an extra function? I'd rather
call one constructor from the other". Unfortunately, sometimes programmers can't solve even such a
simple task. It is to detect such unsuccessful attempts that I'm implementing a new rule in PVS-Studio.
Here is, for instance, a code sample I have found in the eMule project:
class CSlideBarGroup
{
public:
CSlideBarGroup(CString strName,
INT iIconIndex, CListBoxST* pListBox);
CSlideBarGroup(CSlideBarGroup& Group);
...
}
CSlideBarGroup::CSlideBarGroup(CSlideBarGroup& Group)
{
CSlideBarGroup(
Group.GetName(), Group.GetIconIndex(), Group.GetListBox());
}
Let's examine more attentively how the last constructor is implemented. The programmer decided that
the code
CSlideBarGroup(
Group.GetName(), Group.GetIconIndex(), Group.GetListBox());
simply calls the other constructor. Nothing of the kind. A new unnamed object of the CslideBarGroup
type is created and destroyed right after here.
It appears that the programmer has actually called the other constructor. But he/she has done not quite
the same thing he/she intended: the class fields remain uninitialized.
Such errors are just half the trouble. Some people do know how to call the other constructor really. And
they do it. I wish they didn't know :)
For instance, the above given code could be rewritten in this way:
CSlideBarGroup::CSlideBarGroup(CSlideBarGroup& Group)
{
this->CSlideBarGroup::CSlideBarGroup(
Group.GetName(), Group.GetIconIndex(), Group.GetListBox());
}
or in this way:
CSlideBarGroup::CSlideBarGroup(CSlideBarGroup& Group)
{
new (this) CSlideBarGroup(
Group.GetName(), Group.GetIconIndex(),
Group.GetListBox());
}
Now one data initialization constructor is really calling the other constructor.
If you see a programmer doing this, deal him/her one flick on his/her forehead for yourself and one
more flick on my behalf.
The cited examples contain very dangerous code and you should understand well how they
work!
Being written for the purpose of petty optimization (programmers are too lazy to write a separate
function), this code might do more harm than good. Let's see more closely why such constructs
sometimes work but most often don't.
class SomeClass
{
int x,y;
public:
SomeClass() { new (this) SomeClass(0,0); }
SomeClass(int xx, int yy) : x(xx), y(yy) {}
};
This code will work correctly. It is safe and works well, since the class contains primary data types and is
not a descendant of other classes. In this case, a double constructor call is harmless.
Let's consider another code where an explicit constructor call causes an error (the sample is taken from
the discussion on the StackOverflow website):
class Base
{
public:
char *ptr;
std::vector vect;
Base() { ptr = new char[1000]; }
~Base() { delete [] ptr; }
};
class Derived : Base
{
Derived(Foo foo) { }
Derived(Bar bar) {
new (this) Derived(bar.foo);
}
}
When we call the "new (this) Derived(bar.foo);" constructor, the Base object is already created and
fields initialized. The repeated constructor call will cause double initialization. A pointer to the newly
allocated memory area will be written into 'ptr'. As a result, we get memory leak. The result of double
initialization of an object of the std::vector type cannot be predicted at all. But one thing is obvious:
such code is inadmissible.
Conclusion
An explicit constructor call is needed only in very rare cases. In common programming practice, an
explicit constructor call usually appears due to a programmer's wish to reduce the code's size. Don't do
that! Create an ordinary initialization function.
This is how the correct code should look:
class CSlideBarGroup
{
void Init(CString strName, INT iIconIndex,
CListBoxST* pListBox);
public:
CSlideBarGroup(CString strName, INT iIconIndex,
CListBoxST* pListBox)
{
Init(strName, iIconIndex, pListBox);
}
CSlideBarGroup(CSlideBarGroup& Group)
{
Init(Group.GetName(), Group.GetIconIndex(),
Group.GetListBox());
}
...
};
P.S. Explicit call of one constructor from the other in C++11 (delegation)
The new C++11 standard allows you to perform call of constructors from other constructors (known as
delegation). It enables you to create constructors that use behavior of other constructors without added
code. This is an example of correct code:
class MyClass {
std::string m_s;
public:
MyClass(std::string s) : m_s(s) {}
MyClass() : MyClass("default") {}
};

More Related Content

What's hot

History & Practices for UniRx(EN)
History & Practices for UniRx(EN)History & Practices for UniRx(EN)
History & Practices for UniRx(EN)Yoshifumi Kawai
 
Making Java Groovy (JavaOne 2013)
Making Java Groovy (JavaOne 2013)Making Java Groovy (JavaOne 2013)
Making Java Groovy (JavaOne 2013)Ken Kousen
 
Intel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correctionIntel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correctionAndrey Karpov
 
Intel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correctionIntel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correctionPVS-Studio
 
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
 
Let's talks about string operations in C++17
Let's talks about string operations in C++17Let's talks about string operations in C++17
Let's talks about string operations in C++17Bartlomiej Filipek
 
PVS-Studio vs Chromium - Continuation
PVS-Studio vs Chromium - ContinuationPVS-Studio vs Chromium - Continuation
PVS-Studio vs Chromium - ContinuationPVS-Studio
 
Still Comparing "this" Pointer to Null?
Still Comparing "this" Pointer to Null?Still Comparing "this" Pointer to Null?
Still Comparing "this" Pointer to Null?Andrey Karpov
 
Writing Apps with HotCocoa and MacRuby
Writing Apps with HotCocoa and MacRubyWriting Apps with HotCocoa and MacRuby
Writing Apps with HotCocoa and MacRubyRenzo Borgatti
 
Analyzing the Blender project with PVS-Studio
Analyzing the Blender project with PVS-StudioAnalyzing the Blender project with PVS-Studio
Analyzing the Blender project with PVS-StudioPVS-Studio
 
DRb at the Ruby Drink-up of Sophia, December 2011
DRb at the Ruby Drink-up of Sophia, December 2011DRb at the Ruby Drink-up of Sophia, December 2011
DRb at the Ruby Drink-up of Sophia, December 2011rivierarb
 
Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Arthur Puthin
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimizedWoody Pewitt
 
C++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingC++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingFrancesco Casalegno
 
Python and Ruby implementations compared by the error density
Python and Ruby implementations compared by the error densityPython and Ruby implementations compared by the error density
Python and Ruby implementations compared by the error densityPVS-Studio
 
A Brief History of UniRx/UniTask, IUniTaskSource in Depth
A Brief History of UniRx/UniTask, IUniTaskSource in DepthA Brief History of UniRx/UniTask, IUniTaskSource in Depth
A Brief History of UniRx/UniTask, IUniTaskSource in DepthYoshifumi Kawai
 
PVS-Studio vs Chromium. 3-rd Check
PVS-Studio vs Chromium. 3-rd CheckPVS-Studio vs Chromium. 3-rd Check
PVS-Studio vs Chromium. 3-rd CheckAndrey Karpov
 

What's hot (20)

History & Practices for UniRx(EN)
History & Practices for UniRx(EN)History & Practices for UniRx(EN)
History & Practices for UniRx(EN)
 
Namespaces
NamespacesNamespaces
Namespaces
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 
Making Java Groovy (JavaOne 2013)
Making Java Groovy (JavaOne 2013)Making Java Groovy (JavaOne 2013)
Making Java Groovy (JavaOne 2013)
 
Intel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correctionIntel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correction
 
Intel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correctionIntel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correction
 
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
 
Let's talks about string operations in C++17
Let's talks about string operations in C++17Let's talks about string operations in C++17
Let's talks about string operations in C++17
 
PVS-Studio vs Chromium - Continuation
PVS-Studio vs Chromium - ContinuationPVS-Studio vs Chromium - Continuation
PVS-Studio vs Chromium - Continuation
 
Still Comparing "this" Pointer to Null?
Still Comparing "this" Pointer to Null?Still Comparing "this" Pointer to Null?
Still Comparing "this" Pointer to Null?
 
Writing Apps with HotCocoa and MacRuby
Writing Apps with HotCocoa and MacRubyWriting Apps with HotCocoa and MacRuby
Writing Apps with HotCocoa and MacRuby
 
Analyzing the Blender project with PVS-Studio
Analyzing the Blender project with PVS-StudioAnalyzing the Blender project with PVS-Studio
Analyzing the Blender project with PVS-Studio
 
DRb at the Ruby Drink-up of Sophia, December 2011
DRb at the Ruby Drink-up of Sophia, December 2011DRb at the Ruby Drink-up of Sophia, December 2011
DRb at the Ruby Drink-up of Sophia, December 2011
 
Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimized
 
C++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect ForwardingC++11: Rvalue References, Move Semantics, Perfect Forwarding
C++11: Rvalue References, Move Semantics, Perfect Forwarding
 
Analyzing Firebird 3.0
Analyzing Firebird 3.0Analyzing Firebird 3.0
Analyzing Firebird 3.0
 
Python and Ruby implementations compared by the error density
Python and Ruby implementations compared by the error densityPython and Ruby implementations compared by the error density
Python and Ruby implementations compared by the error density
 
A Brief History of UniRx/UniTask, IUniTaskSource in Depth
A Brief History of UniRx/UniTask, IUniTaskSource in DepthA Brief History of UniRx/UniTask, IUniTaskSource in Depth
A Brief History of UniRx/UniTask, IUniTaskSource in Depth
 
PVS-Studio vs Chromium. 3-rd Check
PVS-Studio vs Chromium. 3-rd CheckPVS-Studio vs Chromium. 3-rd Check
PVS-Studio vs Chromium. 3-rd Check
 

Viewers also liked

Farewell to #define private public
Farewell to #define private publicFarewell to #define private public
Farewell to #define private publicPVS-Studio
 
Leo Tolstoy and static code analysis
Leo Tolstoy and static code analysisLeo Tolstoy and static code analysis
Leo Tolstoy and static code analysisPVS-Studio
 
Myths about static analysis. The fifth myth - a small test program is enough ...
Myths about static analysis. The fifth myth - a small test program is enough ...Myths about static analysis. The fifth myth - a small test program is enough ...
Myths about static analysis. The fifth myth - a small test program is enough ...PVS-Studio
 
Analyzing the Dolphin-emu project
Analyzing the Dolphin-emu projectAnalyzing the Dolphin-emu project
Analyzing the Dolphin-emu projectPVS-Studio
 
Checking Intel IPP Samples for Windows - Continuation
Checking Intel IPP Samples for Windows - ContinuationChecking Intel IPP Samples for Windows - Continuation
Checking Intel IPP Samples for Windows - ContinuationPVS-Studio
 
An ideal static analyzer, or why ideals are unachievable
An ideal static analyzer, or why ideals are unachievableAn ideal static analyzer, or why ideals are unachievable
An ideal static analyzer, or why ideals are unachievablePVS-Studio
 
Studying methods of attracting people to a software product's website
Studying methods of attracting people to a software product's websiteStudying methods of attracting people to a software product's website
Studying methods of attracting people to a software product's websitePVS-Studio
 
Intel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correctionIntel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correctionPVS-Studio
 
Software diseases: memset
Software diseases: memsetSoftware diseases: memset
Software diseases: memsetPVS-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
 
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
 
What comments hide
What comments hideWhat comments hide
What comments hidePVS-Studio
 
Wade Not in Unknown Waters. Part Four.
Wade Not in Unknown Waters. Part Four.Wade Not in Unknown Waters. Part Four.
Wade Not in Unknown Waters. Part Four.PVS-Studio
 
Visual Studio tool windows
Visual Studio tool windowsVisual Studio tool windows
Visual Studio tool windowsPVS-Studio
 
Comparing static analysis in Visual Studio 2012 (Visual C++ 2012) and PVS-Studio
Comparing static analysis in Visual Studio 2012 (Visual C++ 2012) and PVS-StudioComparing static analysis in Visual Studio 2012 (Visual C++ 2012) and PVS-Studio
Comparing static analysis in Visual Studio 2012 (Visual C++ 2012) and PVS-StudioPVS-Studio
 
Lesson 7. The issues of detecting 64-bit errors
Lesson 7. The issues of detecting 64-bit errorsLesson 7. The issues of detecting 64-bit errors
Lesson 7. The issues of detecting 64-bit errorsPVS-Studio
 
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
 
9/13-14 1st Americans Kennewick Man
9/13-14 1st Americans Kennewick Man9/13-14 1st Americans Kennewick Man
9/13-14 1st Americans Kennewick Manlnelson7
 

Viewers also liked (20)

Farewell to #define private public
Farewell to #define private publicFarewell to #define private public
Farewell to #define private public
 
Leo Tolstoy and static code analysis
Leo Tolstoy and static code analysisLeo Tolstoy and static code analysis
Leo Tolstoy and static code analysis
 
Myths about static analysis. The fifth myth - a small test program is enough ...
Myths about static analysis. The fifth myth - a small test program is enough ...Myths about static analysis. The fifth myth - a small test program is enough ...
Myths about static analysis. The fifth myth - a small test program is enough ...
 
Analyzing the Dolphin-emu project
Analyzing the Dolphin-emu projectAnalyzing the Dolphin-emu project
Analyzing the Dolphin-emu project
 
Checking Intel IPP Samples for Windows - Continuation
Checking Intel IPP Samples for Windows - ContinuationChecking Intel IPP Samples for Windows - Continuation
Checking Intel IPP Samples for Windows - Continuation
 
An ideal static analyzer, or why ideals are unachievable
An ideal static analyzer, or why ideals are unachievableAn ideal static analyzer, or why ideals are unachievable
An ideal static analyzer, or why ideals are unachievable
 
Studying methods of attracting people to a software product's website
Studying methods of attracting people to a software product's websiteStudying methods of attracting people to a software product's website
Studying methods of attracting people to a software product's website
 
Intel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correctionIntel IPP Samples for Windows - error correction
Intel IPP Samples for Windows - error correction
 
Software diseases: memset
Software diseases: memsetSoftware diseases: memset
Software diseases: memset
 
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.
 
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
 
What comments hide
What comments hideWhat comments hide
What comments hide
 
Wade Not in Unknown Waters. Part Four.
Wade Not in Unknown Waters. Part Four.Wade Not in Unknown Waters. Part Four.
Wade Not in Unknown Waters. Part Four.
 
Visual Studio tool windows
Visual Studio tool windowsVisual Studio tool windows
Visual Studio tool windows
 
Comparing static analysis in Visual Studio 2012 (Visual C++ 2012) and PVS-Studio
Comparing static analysis in Visual Studio 2012 (Visual C++ 2012) and PVS-StudioComparing static analysis in Visual Studio 2012 (Visual C++ 2012) and PVS-Studio
Comparing static analysis in Visual Studio 2012 (Visual C++ 2012) and PVS-Studio
 
Cppcheck
CppcheckCppcheck
Cppcheck
 
Lesson 7. The issues of detecting 64-bit errors
Lesson 7. The issues of detecting 64-bit errorsLesson 7. The issues of detecting 64-bit errors
Lesson 7. The issues of detecting 64-bit errors
 
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
 
9/13-14 1st Americans Kennewick Man
9/13-14 1st Americans Kennewick Man9/13-14 1st Americans Kennewick Man
9/13-14 1st Americans Kennewick Man
 
ICT
ICTICT
ICT
 

Similar to Wade not in unknown waters. Part one.

Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016PVS-Studio
 
The Little Unicorn That Could
The Little Unicorn That CouldThe Little Unicorn That Could
The Little Unicorn That CouldPVS-Studio
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Workhorse Computing
 
Cool Object Building With PHP
Cool Object Building With PHPCool Object Building With PHP
Cool Object Building With PHPwensheng wei
 
Top 10 C# projects errors found in 2016
Top 10 C# projects errors found in 2016Top 10 C# projects errors found in 2016
Top 10 C# projects errors found in 2016PVS-Studio
 
Cppcheck and PVS-Studio compared
Cppcheck and PVS-Studio comparedCppcheck and PVS-Studio compared
Cppcheck and PVS-Studio comparedPVS-Studio
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceJesse Vincent
 
Of complicacy of programming, or won't C# save us?
Of complicacy of programming, or won't C# save us?Of complicacy of programming, or won't C# save us?
Of complicacy of programming, or won't C# save us?PVS-Studio
 
Analyzing FreeCAD's Source Code and Its "Sick" Dependencies
Analyzing FreeCAD's Source Code and Its "Sick" DependenciesAnalyzing FreeCAD's Source Code and Its "Sick" Dependencies
Analyzing FreeCAD's Source Code and Its "Sick" DependenciesPVS-Studio
 
C++ interview questions
C++ interview questionsC++ interview questions
C++ interview questionsarjavi
 
PVS-Studio: analyzing ReactOS's code
PVS-Studio: analyzing ReactOS's codePVS-Studio: analyzing ReactOS's code
PVS-Studio: analyzing ReactOS's codePVS-Studio
 
Constructors and destructors in C++
Constructors and destructors in  C++Constructors and destructors in  C++
Constructors and destructors in C++RAJ KUMAR
 
Constructors & Destructors [Compatibility Mode].pdf
Constructors & Destructors [Compatibility Mode].pdfConstructors & Destructors [Compatibility Mode].pdf
Constructors & Destructors [Compatibility Mode].pdfLadallaRajKumar
 
PVS-Studio: analyzing ReactOS's code
PVS-Studio: analyzing ReactOS's codePVS-Studio: analyzing ReactOS's code
PVS-Studio: analyzing ReactOS's codeAndrey Karpov
 
The First C# Project Analyzed
The First C# Project AnalyzedThe First C# Project Analyzed
The First C# Project AnalyzedPVS-Studio
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSPVS-Studio
 
Latest C++ Interview Questions and Answers
Latest C++ Interview Questions and AnswersLatest C++ Interview Questions and Answers
Latest C++ Interview Questions and AnswersDaisyWatson5
 
LibRaw, Coverity SCAN, PVS-Studio
LibRaw, Coverity SCAN, PVS-StudioLibRaw, Coverity SCAN, PVS-Studio
LibRaw, Coverity SCAN, PVS-StudioAndrey Karpov
 
[2012 02 03]clean_code 4장
[2012 02 03]clean_code 4장[2012 02 03]clean_code 4장
[2012 02 03]clean_code 4장Jong Pil Won
 

Similar to Wade not in unknown waters. Part one. (20)

Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016
 
The Little Unicorn That Could
The Little Unicorn That CouldThe Little Unicorn That Could
The Little Unicorn That Could
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.
 
Cool Object Building With PHP
Cool Object Building With PHPCool Object Building With PHP
Cool Object Building With PHP
 
Top 10 C# projects errors found in 2016
Top 10 C# projects errors found in 2016Top 10 C# projects errors found in 2016
Top 10 C# projects errors found in 2016
 
Assign
AssignAssign
Assign
 
Cppcheck and PVS-Studio compared
Cppcheck and PVS-Studio comparedCppcheck and PVS-Studio compared
Cppcheck and PVS-Studio compared
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
 
Of complicacy of programming, or won't C# save us?
Of complicacy of programming, or won't C# save us?Of complicacy of programming, or won't C# save us?
Of complicacy of programming, or won't C# save us?
 
Analyzing FreeCAD's Source Code and Its "Sick" Dependencies
Analyzing FreeCAD's Source Code and Its "Sick" DependenciesAnalyzing FreeCAD's Source Code and Its "Sick" Dependencies
Analyzing FreeCAD's Source Code and Its "Sick" Dependencies
 
C++ interview questions
C++ interview questionsC++ interview questions
C++ interview questions
 
PVS-Studio: analyzing ReactOS's code
PVS-Studio: analyzing ReactOS's codePVS-Studio: analyzing ReactOS's code
PVS-Studio: analyzing ReactOS's code
 
Constructors and destructors in C++
Constructors and destructors in  C++Constructors and destructors in  C++
Constructors and destructors in C++
 
Constructors & Destructors [Compatibility Mode].pdf
Constructors & Destructors [Compatibility Mode].pdfConstructors & Destructors [Compatibility Mode].pdf
Constructors & Destructors [Compatibility Mode].pdf
 
PVS-Studio: analyzing ReactOS's code
PVS-Studio: analyzing ReactOS's codePVS-Studio: analyzing ReactOS's code
PVS-Studio: analyzing ReactOS's code
 
The First C# Project Analyzed
The First C# Project AnalyzedThe First C# Project Analyzed
The First C# Project Analyzed
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMS
 
Latest C++ Interview Questions and Answers
Latest C++ Interview Questions and AnswersLatest C++ Interview Questions and Answers
Latest C++ Interview Questions and Answers
 
LibRaw, Coverity SCAN, PVS-Studio
LibRaw, Coverity SCAN, PVS-StudioLibRaw, Coverity SCAN, PVS-Studio
LibRaw, Coverity SCAN, PVS-Studio
 
[2012 02 03]clean_code 4장
[2012 02 03]clean_code 4장[2012 02 03]clean_code 4장
[2012 02 03]clean_code 4장
 

Wade not in unknown waters. Part one.

  • 1. Wade not in unknown waters. Part one. Author: Andrey Karpov Date: 27.01.2012 We decided to write several small posts on how C/C++ programmers play with fire without knowing it. The first post will be devoted to an attempt to explicitly call a constructor. Programmers are lazy creatures. That's why they tend to solve a task using minimal code amount. This aim is praiseworthy and good. But the main point is not get too involved in the process and stop at the right time. For example, programmers are too lazy to create a single initialization function in a class so that it could be called from various constructors later. They think: "What for do I need an extra function? I'd rather call one constructor from the other". Unfortunately, sometimes programmers can't solve even such a simple task. It is to detect such unsuccessful attempts that I'm implementing a new rule in PVS-Studio. Here is, for instance, a code sample I have found in the eMule project: class CSlideBarGroup { public: CSlideBarGroup(CString strName, INT iIconIndex, CListBoxST* pListBox); CSlideBarGroup(CSlideBarGroup& Group); ... } CSlideBarGroup::CSlideBarGroup(CSlideBarGroup& Group) { CSlideBarGroup( Group.GetName(), Group.GetIconIndex(), Group.GetListBox()); } Let's examine more attentively how the last constructor is implemented. The programmer decided that the code CSlideBarGroup( Group.GetName(), Group.GetIconIndex(), Group.GetListBox());
  • 2. simply calls the other constructor. Nothing of the kind. A new unnamed object of the CslideBarGroup type is created and destroyed right after here. It appears that the programmer has actually called the other constructor. But he/she has done not quite the same thing he/she intended: the class fields remain uninitialized. Such errors are just half the trouble. Some people do know how to call the other constructor really. And they do it. I wish they didn't know :) For instance, the above given code could be rewritten in this way: CSlideBarGroup::CSlideBarGroup(CSlideBarGroup& Group) { this->CSlideBarGroup::CSlideBarGroup( Group.GetName(), Group.GetIconIndex(), Group.GetListBox()); } or in this way: CSlideBarGroup::CSlideBarGroup(CSlideBarGroup& Group) { new (this) CSlideBarGroup( Group.GetName(), Group.GetIconIndex(), Group.GetListBox()); } Now one data initialization constructor is really calling the other constructor. If you see a programmer doing this, deal him/her one flick on his/her forehead for yourself and one more flick on my behalf. The cited examples contain very dangerous code and you should understand well how they work! Being written for the purpose of petty optimization (programmers are too lazy to write a separate function), this code might do more harm than good. Let's see more closely why such constructs sometimes work but most often don't. class SomeClass { int x,y; public: SomeClass() { new (this) SomeClass(0,0); }
  • 3. SomeClass(int xx, int yy) : x(xx), y(yy) {} }; This code will work correctly. It is safe and works well, since the class contains primary data types and is not a descendant of other classes. In this case, a double constructor call is harmless. Let's consider another code where an explicit constructor call causes an error (the sample is taken from the discussion on the StackOverflow website): class Base { public: char *ptr; std::vector vect; Base() { ptr = new char[1000]; } ~Base() { delete [] ptr; } }; class Derived : Base { Derived(Foo foo) { } Derived(Bar bar) { new (this) Derived(bar.foo); } } When we call the "new (this) Derived(bar.foo);" constructor, the Base object is already created and fields initialized. The repeated constructor call will cause double initialization. A pointer to the newly allocated memory area will be written into 'ptr'. As a result, we get memory leak. The result of double initialization of an object of the std::vector type cannot be predicted at all. But one thing is obvious: such code is inadmissible. Conclusion An explicit constructor call is needed only in very rare cases. In common programming practice, an explicit constructor call usually appears due to a programmer's wish to reduce the code's size. Don't do that! Create an ordinary initialization function. This is how the correct code should look: class CSlideBarGroup
  • 4. { void Init(CString strName, INT iIconIndex, CListBoxST* pListBox); public: CSlideBarGroup(CString strName, INT iIconIndex, CListBoxST* pListBox) { Init(strName, iIconIndex, pListBox); } CSlideBarGroup(CSlideBarGroup& Group) { Init(Group.GetName(), Group.GetIconIndex(), Group.GetListBox()); } ... }; P.S. Explicit call of one constructor from the other in C++11 (delegation) The new C++11 standard allows you to perform call of constructors from other constructors (known as delegation). It enables you to create constructors that use behavior of other constructors without added code. This is an example of correct code: class MyClass { std::string m_s; public: MyClass(std::string s) : m_s(s) {} MyClass() : MyClass("default") {} };