mercredi 19 décembre 2012

The annoying push_back.....

Maybe you know, but maybe not,
but one of the really nice feature coming in the C++11 standard is the "initializer list".

In fact with C++11, you can now write:
std:vector vec = {"blog", "msg"};

see http://en.wikipedia.org/wiki/C%2B%2B11#Core_language_usability_enhancements

But if you are still using the old C++, you can at least try to avoid the push_back usage...

Instead of writing

std:vector vec;
vec.push_back("blog");
vec.push_back("msg");

let's use Boost/Assign to offer a += operator supporting variable number of arguments

#include "boost/assign.hpp"
std:vector vec;
vec += "blog", "msg";

jeudi 8 novembre 2012

When compiler act as Static Analyzer

Today i goes through a strange compiler behavior while compiling a source code with GCC/G++. You may or not be aware of the importance of Security and Sanity checking on the code you write, but it's a fact that in the last decade the "Static Code Analysis" come from space, fly, nuclear domain and is now use in game and all professional development.

For a good introduction to "Static Analysis" take a look at http://www.altdevblogaday.com/2011/12/24/static-code-analysis/ where John Carmack present a review of several existing tools.

But here I try to explain why sometimes a good compiler like GCC "can" act as a static code checker. To demonstrate and explain it, lets talk about the code below.


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>

//inline int func(int tab[], bool toSwitch) //force inline.
//__attribute__ ((noinline)) int func(int tab[], bool toSwitch)  //prevent inline.
int func(int tab[], int idx) //let compiler inline based on its own logic and optimization parameters.
{
  return tab[idx];
}

int main(int argc, char* argv[])
{
  std::cout << argc << " " << std::string(argv[0]) << std::endl;
  int myTab[4] = {1,2,3,4};
  //int myTab[10] = {1,2,3,4,5,6,7,8,9,10};
  std::cout << func(myTab, 0) << std::endl;
  std::cout << func(myTab, 8) << std::endl;

  //At least the line is detected by VS'12 Static Analyzer....
  std::cout << myTab[8] << std::endl;
  return 0;
}

I mainly code using Visual Studio IDE (08,10 at work and 12 at home for now...) but hopefully i also use GCC and we will see why just below. As you can see, i coded 2 buffer overrun by calling "func(myTab, 8)" and "myTab[8]".
  • Visual Studio 2012 
From VS compiler point of view that code is perfect, no error, no warning. But at least the line 20 is detected by VS'12 Static Analyzer


//At least the line is detected by VS'12 Static Analyzer....
std::cout << myTab[8] << std::endl;

stl_usage.cpp(22): warning : C6201: Index '8' is out of valid index range '0' to '3' for possibly stack allocated buffer 'myTab'.
stl_usage.cpp(22): warning : C6385: Reading invalid data from 'myTab': the readable size is '16' bytes, but '36' bytes may be read.

  • GCC
when i compile that source code with the following line:
g++ -Wall -Wextra -Werror -O3 ./gcc-static-analys.cpp
I got the following error:
./gcc-static-analys.cpp: In function âint main(int, char**)â:
./gcc-static-analys.cpp:17: error: âmyTab[8]â is used uninitialized in this function [-Werror=uninitialized]
./gcc-static-analys.cpp:20: error: âmyTab[8]â is used uninitialized in this function [-Werror=uninitialized]
cc1plus: all warnings being treated as errors

But why GCC can detect these 2 buffer overrun at compile-time. For the direct and invalid access to myTab[8] it should be easy but for "func(8)", it's a bit tricky. In fact if you had a look at the 2 comment line 4 and 5, you may have guess that it's mainly come from the "inlining" of "func".

Depending of the optimization level you used GCC can decide to inline some function by itself and in fact case he can detect some error and act as a Stactic Analyzer  preventing use to let something wrong (a security issue) in our code.


mardi 23 octobre 2012

why you should prefer std::algorithm...

Today i worked on a huge legacy code base when i meet (1x more) the following kind of loop:


std::vector<int> vec;
...
int max_value = 0;
for ( int i=0 ; i<(int)vec.size() ; i++ )
  {
    if (vec[i] > max_value)
    {
      max_value = vec[i];
    }
  }

I was wondering why some developer always try to reinvent the wheel ?

C++ comes with a tons of useful algorithm to do that kind of stuff, and with an explicit name. In example that code can be rewrite with:


#include <algorithm>
...
std::vector<int> vec;
...
int max_value = *std::max_element<std::vector<int>::iterator >(vec.begin(), vec.end());

it's shorter and more explicit...

Note for C++11 users:



auto max_value = *std::max_element<std::vector<int>::iterator >(begin(vec), end(vec));

mercredi 17 octobre 2012

VS - How To Collapse your Solution Explorer.


You may have notice (or maybe not) that VS'08 often expand the whole Solution Explorer  when you open a solution.

With VS'12 The VS Team added the solution explorer collapse button, but we can add that functionnality to our old VS using a simple VB Macro.

You have to follow some few step and play! 
  1. unzip SolutionCollapse.zip (in Users\YOU\Documents\Visual Studio 2008\Projects\VSMacros80 for example)  
  2. Open  VS'08 – View – Other windows – Macros Explorer 3)       Dans l’explorateur de macro – Load Macro Project – And select SolutionCollapse  
  3. Now in  Tools –Customize  – Keyboard 
    1.  in "Show command containing" enter « Collapse », Scroll the results to find "Macros.SolutionCollapse.CollapseAll"
    2.  Set a shortcut  (CTRL-M + CTRL-C for example)

Done.


CppCheck VS integration

1st, download and setup CppCheck from http://cppcheck.sourceforge.net/

Next in VS, Open Tools => Extension and Add the following command


argument line: --enable=all --verbose --template=vs "$(ProjectDir)"

Get back and you will see something like that in your Tools menu.



To add a keyboard shortcut, Go to Tools => Customize => click on the "Keyboard" button, "Show commands containing "Tools.Exter", Select the "ExternalCommand1" if you placed "your CppCheck command on the top of the list and define the shortcut you want. For example, i used CTRL+ALT+C.


Now when working on C/C++ Project and source code in VS, just press your shortcut, to see CppCheck message in the "Output" windows. Click on a message to go immediately into the incriminate code.

Good luck.

jeudi 4 octobre 2012

How to map array into a std::vector and display value.

As C++ user, you may have to check if a given value is allow in your software and if not display the list of allowed values.

To do that job, you can write code based on C++/STL and use as few "if"s, "while"s, "for"s and other builtin constructs as possible. In the following  example, I try to demonstrate 3 things:
  1. Init a vector within a array. Note that in the new C++ standard, you can implement that with a single line.
  2. Check if a value is in the vector using the 'find' algorithm.
  3. Display on stdout or format into a string all values using 'copy'.


#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
#include <sstream>

int _tmain(int argc, _TCHAR* argv[])
{

  int tab[5] = {1,2,3,4,5};
  std::vector<int> test(tab, tab+5);

  int valueForChecking = -1;
  std::cin >> valueForChecking;

  if(std::find(test.begin(), test.end(), valueForChecking) == test.end())
  {  
    std::copy(test.begin(), test.end(), std::ostream_iterator<int>(std::cout," ")); 
    std::cout << std::endl;
  }
  else
    std::cout << "is in" << std::endl;

  //or

  if(std::find(test.begin(), test.end(), valueForChecking) == test.end())
  {
    std::ostringstream s;
    std::copy(test.begin(), test.end(), std::ostream_iterator<int>(s," "));
    std::cout << "string from vector : " << s.str() << std::endl;
  }
  else
    std::cout << "is in" << std::endl;

  return 0;
}

mardi 2 octobre 2012

A Simple polymorphism example...

It seems that the term "Polymorphism" is not so clear that it should to some of team member (and sometimes it also a mess to me to understand object design we made !!!)... So every time, every time i will use polymorphism in my own work, i will try to extract a demonstration/example.

Let's start with the following example in which we can show that we can define a function to call the f function of a 'Base' object, but accessing finally the f function implemented by the child....


class A
{
public:
  virtual void f()
  {
    std::cout << "A::f()" <<std::endl;
  }
};

class B : public A
{
public:
  virtual void f()
  {
    std::cout << "B::f()" << std::endl;
  }
};

class AI : public A
{

};

class BI : public B
{

};

void master_f(A& base_ref)
{
  base_ref.f();
}

int _tmain(int argc, _TCHAR* argv[])
{
  AI oAI;
  BI oBI;

  master_f(oAI);
  master_f(oBI);

 return 0;
}

dimanche 2 septembre 2012

New VS'12 IDE but build with your old compiler.


Visual Studio project allow to configure the set of tool you want use to build.

If you setup on the same platform VS'08, 2010 and 2012, you can use all the recent tools and functionality of the VS IDE, but still use the old compiler, and don't have to deal with all the recent change in C++ standard or in the compiler.
Property box of a C++ project.


vendredi 25 mai 2012

C++11 - for_each, auto, constexpr, the begin & the end...

Auto:

It's a new keyword really usefull to code faster but it can be scary to use as it leads to more flexibility and less readability.

srand(1234);

 auto vector_size = 10;

 std::vector<int> a(vector_size);
 auto b = std::vector<int>(vector_size);

 auto lambda = [](int& i){i = abs(i);};

 std::for_each(begin(a), end(a), lambda);

 for each (auto var in a)
 {
  std::cout << var << ",";
 }
 std::cout << std::endl;

and you can also use 'auto' as return type qualifier.

int foo() { return 5; } 
       auto j = foo();

==>  Allows to avoid typos
BUT i recommend an extensive usage of VisualAssistX to change function or variable signature and unit-test improvements.

ConstExpr:

As you may know, C98 doesn't allow to declare an array with an expression.

// Comment
//constexpr int f() //Maybe available in VS'11 Final ...
//{
// return 5;
//}

const int g()
{
 return 5;
}

void ConstExpressionDemo()
{
 const int vector_size = 10;
 int A[vector_size];

 int B[g()];//C++98 cannot compile
 /*int B[f()];*///C++11 should compile if constexpr available.
 
 return;
}

Visual C++ 11: Not available.

But using the compiler static analysis, the following code couldn't compile.

// Comment
constexpr int f() //shouldn't compile ...
{
 return rand();
}


for_each and for-loop improvement:

C# and modern languages provided tools to easily iterate over list, collection or array. Before C++11 programmers who wants to iterate on containers elements wrote loops like:
const auto vector_size = 10;
std::vector<int> a(vector_size);
srand(1234);
  
auto lambda_random_init = [](int& i){i = rand();};

for (std::vector<int>::iterator it = a.begin() ; it != a.end() ;  ++it)
{
  *it = rand();
}

But now we can use auto, lambda, std::for_each and range base for to provide compact, and elegant code.
As example, with the following code we can dump vector, deque or array, in fact any container containing any kind of object supporting "cout".

template<class T> void cout_container(T _Container)
{
    for each (auto var in _Container)
    {
        std::cout << var << ",";
    }
    std::cout << std::endl;
}

cout_container<std::vector<int>>(a);

in the following example i implemented vector initialization using a lambda and several vector accumulation based on different loop-style.

const auto vector_size = 10;
    std::vector<int> a(vector_size);

    srand(1234);

    auto lambda_random_init = [](int& i){i = rand();};

    //init using begin & end 
    std::for_each(begin(a), end(a), lambda_random_init);

    cout_container<std::vector<int>>(a);

    //for_each with lambda capture by ref and return sum
    int sum_of_elems = std::accumulate(begin(a), end(a), 0);
    std::cout << sum_of_elems << std::endl;

    std::for_each(begin(a), end(a), [&sum_of_elems](int& n){ sum_of_elems += n; }); //only 1 elt by ref
    std::cout << sum_of_elems << std::endl;
    std::for_each(begin(a), end(a), [&](int& n){ sum_of_elems += n; });//all elt by ref
    std::cout << sum_of_elems << std::endl;

    int tmp = 0;
    //std::for_each(begin(a), end(a), [&sum_of_elems](int& n){ sum_of_elems += n; tmp = 0; });//cannot compile as tmp is not in the capture list!!!
    std::for_each(begin(a), end(a), [&sum_of_elems, &tmp](int& n){ sum_of_elems += n; tmp += n; });//target several output captured by value !!!
    std::cout << sum_of_elems << " " << tmp << std::endl;

    for each (int& n : A) 
    {
        sum_of_elems += n;
    }
    std::cout << sum_of_elems << std::endl;

    cout_container<std::vector<int>>(a);;

mercredi 9 mai 2012

C#: prefer LINQ instead of foreach

In this post, i want to focus in LINQ and its advantage on foreach.

In fact, i meet yesterday the following case: i had a list and i would remove some elements matching a criteria.

As you know C# provide a lots of interface like IQueryable, IEnumerable, etc.... And face to my problem i started by using my list as an IEnumerable through a foreach.... so wrong am i.

In fact if you try something like this:

 var collect = new Collection<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 foreach (var x in collect)
 {
    if (x % 2 == 0)
    {
       collect.Remove(x);
    }
 }
You will meet an exception: System.InvalidOperationException :  .... Because you change the collection itself during the enumeration.

But some very simple solutions exists.
1) If the collection is a List of something implementing the IList Interface you can use "RemoveAll"

collect.RemoveAll(x => x % 2 == 0);


2) If your collection doesn't implement IList, you can use the following code:

 foreach (var x in collect.Where(x => x % 2 == 0).ToList())
 {
    collect.Remove(x);
 } 


  As ToList doesn't provide a new object of type List containing only the element we want to remove and we get through this new list.

No more problems !

jeudi 26 avril 2012

Switch from MSTest to NUnit.

Maybe the 1st post of a long series dedicated to the .Net Universe.

Visual Studio (VS) is well known to come with plenty of plugins or project template to create unit-test project.

But sometimes you would change the unit test framework a project used to.

Indeed it's not so easy but please found below several useful tips&tricks to move a MSTest project and code to a NUnit project.

1) Remove the MSTest Framework reference

2) Add nunit.framework instead.

3) Use the following side by side attribute dictionary to replace all MSTest attribute by their equivalent in the NUnit framework.

4) build & load your assembly with nunit... Every should work! IBut...

5) try to start nunit from your VS and now VS claims that there is no test inside!

6) So edit your vcproj file and search for the <ProjectTypeGUID>. If you found 2 GUID inside, goto to this page to lean more about the existing project type and their GUID. Remove the test GUID {3AC096D0-A1C2-E12C-1390-A8335801FDAB}, save, and reload the project.

And... THE END !

jeudi 15 mars 2012

Book review: Extreme programming Explained

Extreme programming Explained
Embrace change 2nd Edition
Written Kent Beck with Cynthia Andrea & Forewords by Eric Gamma
ISBN-13: 978-0-321-27865-4


My opinion... 6/10. I like & follow some XP practices since at least 6 years at work and in my homework.....But, let's get started with more details about the book, i hope it help you deciding if you would read it or not!

The author presents XP in 3 steps. First he presents XP's values. This part looks very long but they are the reason why XP is. And Values & Principles are notions that you can take in your bag for your own lifestyle improvement! Too much psychological to me (but maybe it can push for change like a hidden message)

Communication,Simplicity,Feedback,Courage,Respect are basic XP values.

Chapter about Principles was quick & full of interest. They are: Humanity, Economics, Mutual Benefit, Self-Similarity, Improvement, Diversity, Reflection, Flow, Opportunity, Redundancy, Failure, Quality, Baby Steps and Accepted Responsibility. In fact they are just global notions to give a better view of what the practices are intended to accomplish.

I read the chapter about Practices really easily. Author describes team & resources organization, "Sit together" or in other words build a comfortable open space while maintaining place for personal space,
install place for project informations (to quickly see how projects goes).

About "pair programming", it give some advice that we could follow. In my own experience of "pairing", i was a bit frustrated at the end of day. I felt i should have make much more. But after, reading i think i could plan more dev in pair!

Stories definition is also really good. And it was follow by cycles definition. The "quick iteration" and the "quarterly cycle". Priority management of user stories and how put in place a slack of task that the team can made (refactoring, optimization, design, research on a future topic) without interfering with new features development.

Ten-minute build is something we should work. The quicker you have feedback, the quicker you can change or fix! Continuous integration, Test-First are also something i use but being more Extreme could help!

Incremental Design is the last but not the least as XP is about change. It explain why we try to start with a basic & simple design and every time we need, we improve it based on experience & feedback.

The corollary practices are: customer involvement, incremental deployment, Team continuity, Shrinking teams, root cause analysis, shared code, code & test, single code base, daily deployment.

A chapter talk about roles in XP team.But in the end of this book the 2 most interesting chapters from my developer point of view are 13 and 14. Chapter 13 talk of testing (first, early and often) of test automation 

I think that deploy a beta version at the end of each iteration or at least at the end each important user story implementation to use & demonstrate, is a target i should keep in my mind.

And 14 is about design (it's funny as we are talking about design at work those last days...). The author recall that design for design is not a good thing and that perfection is not in this world. Even if you start with 2 weeks of design, you will have to rework it a some point because of change. So use basic principles, KISS, DRY, but don't procrastinate yourself when, based on experience, feedback and need, you have to modify the design!

I had a look for the remaining chapter but they are more for manager, describing how XP can scale when team or organization grows, how measure XP usage and effectiveness.