Source: Marcel Duchamp, Mile of String

There are more string types in C++ than the Boston Symphony Orchestra.

Audience laughs

There are so many different string types in C++ that it’s easier to master string theory in physics.

More laughter

I try to write simple, cross-platform software whenever possible, particularly for helper functions that I find myself using often no matter if I am running under Windows or Linux.  When it comes to strings, I prefer to keep it simple with the ISO standard <string> class along with a few STL classes for manipulation.  I know that there are many other string types in VC++ that are optimized to perform better and offer more features, but most of them run on Windows only.

The two functions below will handle these conversations quite nicely.  Converting a number into a string is straightforward, but converting a string into a number can have a few pitfalls, especially if the string is not a number.  Make sure to check for these conditions before or during the conversion.  One other thing, you may want to consider using a template to handle the various number types—long, short, float, etc.  The examples below are for integers only.

Audience now can’t stop laughing for no apparent reason

#include <string>
#include <iostream>
#include <sstream>

using namespace std;

// Convert an integer into a string
string convertIntToString
(
  int iNum
)
{
  ostringstream sStr;

  sStr << iNum;

  return sStr.str();
}

// Convert a string into an integer
int convertStringToInt
(
  string sStr
)
{
  int iNum = 0;

  // Maybe do a custom trim() call first to 
  // eliminate leading and trailing white-spaces

  istringstream sTmpStr(sStr);

  // If returns false, then the string is not a number

  if ( !(sTmpStr >> iNum) )
  {
     // Throw some exception here because     
    // string was not a number…e.g.:
    throw ( ... );
  }

  return iNum;
}

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
Tagged with:  

A Few Ways to Access Argc and Argv in C++

Source: http://www.gunpundit.com/434.php

There are a few ways to access program name and command line arguments in C++ on Windows.  If your program is a console application with main(), then you can you use the well-known argc and argv values.  In fact, you should be able to do this on any OS platform.  You can also access these variables as __argc and __argv respectively, but they may not be supported everywhere.  For Windows, they exist in Visual Studio and are quite useful if you are trying to access them in a static or dynamic library.  If portability is a concern, however, then avoid __argc and __argv altogether.

Code:

#include <iostream>

using namespace std;

void showArgs();

int main (int argc, char **argv)
{
  cout << endl << "ARGV:" << endl << endl;

  for ( int i = 0; i < argc; i++ )
  {
    cout << i << ": " << argv[i] << endl;
  }

  showArgs();

  return 0;
}

void showArgs()
{
  cout << endl << "__ARGV:" << endl << endl;

  for ( int i = 0; i < __argc; i++ )
  {
    cout << i << ": " << __argv[i] << endl;
  }

  return;
}

Output:

% Demo.exe one two three four five

ARGV:

0: Demo.exe
1: one
2: two
3: three
4: four
5: five

__ARGV:

0: Demo.exe
1: one
2: two
3: three
4: four
5: five
Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
 

Randomness is a test developer’s best friend.  The following example is a C++ class called CRandomNumbers.  It has two public static methods that generate random numbers.  CRandomNumbers::getRandomNumber() returns a single random number between iMin and iMax and CRandomNumbers::getRandomNumbers() returns a vector of random numbers between iMin and iMax with the total number set as iSize.  The latter leverages the former to generate its numbers.  You can set bUniqueOnlyFlag to true to ensure that all numbers in the vector are unique.

The private CRandomNumbers::initialize() method should be called only once.  It sets the pseudo-random seed using the time() function.  I also rand() to ensure to flush out the first, possibly predicable, number.  I noticed on my system that if I didn’t do this then the first number was always the same.  Finally, I used a map to do number lookups quicker when checking for unique values.

Don’t forget to add some error checking in this code.  You may want to consider using templates as well since then you can support other numeric types like longs and doubles.

// RandomNumbers.h
#pragma once

#include <vector>

using namespace std;

class CRandomNumbers
{

public:

  static int getRandomNumber(
     int iMin, 
     int iMax
     );

  static vector getRandomNumbers(
     int iMin,  
     int iMax, 
     int iSize,  
     bool bUniqueOnlyFlag
     );

protected:

private:

  static void initialize();

};
// RandomNumbers.cpp

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <map>
#include "RandomNumbers.h"

int CRandomNumbers::getRandomNumber
(
   int iMin, 
   int iMax
)
{
  static bool bIsInitialized = false;

  if ( !bIsInitialized )
  {
    initialize();

    bIsInitialized = true;
  }

  return ( iMin + int( (iMax - iMin + 1) * 
             rand() /(RAND_MAX + 1.0) ) );
}

vector CRandomNumbers::getRandomNumbers
(
   int iMin, 
   int iMax, 
   int iSize, 
   bool bUniqueOnlyFlag
)
{
  vector viRandomNumbers;

  viRandomNumbers.clear();

  if ( !bUniqueOnlyFlag ) 
  {
    for ( int i = 0; i < iSize; i++ )
    {
      viRandomNumbers.push_back(getRandomNumber(iMin, iMax));
    }

    return viRandomNumbers;
  }

  map  viUniqueRandomNumbers;

  for ( int i = 0; i < iSize; )
  {
    int iRandomNumber = getRandomNumber(iMin, iMax);

    if ( viUniqueRandomNumbers.find(iRandomNumber) == 
         viUniqueRandomNumbers.end() )
    {
      viRandomNumbers.push_back(iRandomNumber);

      viUniqueRandomNumbers[iRandomNumber] = true;

      ++i;
    }
  }

  return viRandomNumbers;
}

void CRandomNumbers::initialize()
{
  srand((unsigned)time(0));

  rand();

  return;
}
Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
Tagged with:  

Delegate a C++ Class Member to a Thread MFC Style

I spent the better half of today trying to figure how to assign a C++ class member to a thread in an MFC environment.   It’s not as easy as you think.  I think the word convoluted comes to mind, but that’s just because I am used to simpler implementations in C, C#, and Python.  The purpose of this article is to save you precious time.

Let’s start with a simple MFC application that delegates a simple function to a thread.

#include <iostream>
#include <iafxwin.h>
#include <ivector>
#include <icstdlib>
#include <ictime>

using namespace std;

UINT procrastinate( LPVOID params )
{
  int *i = reinterpret_cast(params);

  srand( (unsigned int)time(NULL) + *i );

  int iSecs = rand() % 5 + 1;

  cout << "I will now procrastinate " << iSecs
       << " for seconds" << endl;

  Sleep(iSecs * 1000);

  return 0;
}

int main( int argc, char **argv )
{
  for ( int i = 0; i < 10; i++ )
  {
    CWinThread *pThread =
        AfxBeginThread(procrastinate, reinterpret_cast(&i));

    WaitForSingleObject(pThread->m_hThread, INFINITE);
  }
  return 0;
}

The AfxBeginThread() function is what kicks off the thread.  The function that follows AfxBeginThread() is called WaitforSingleObject(). We use it to wait for the thread to complete.  If we didn’t use WaitforSingleObject() then the program itself would terminate before the thread(s) could complete. Trust me on this; I wasted about an hour before I figured out what was happening.

Now let’s take a closer look at our example of AfxBeginThread().  The first argument is a function with UINT as the return value and a LPVOID pointer as its parameter.  If you don’t know what LPVOID does, then just think of it as a special pointer that can point to anything – this includes functions, classes, structs, integers, dogs, cats—you name it, it can pass it.  If you don’t want to pass anything then just set the argument to 0 or NULL.  In our case, I am passing the address of the for loop integer.  I am using the C++ standard reinterpret_cast operator to make the transition from integer to LPVOID.  I don’t know how it works behind the scenes, but just remember you will need to call it in pairs.  Once to transform into something else and once to change it back to its original type.  We do the latter in our function.

The function itself doesn’t do anything special except generate a random number of seconds to sleep.  When we call it in the loop in the main function, it executes then waits to complete.  We just want to keep things simple here.  Normally, you would want to fire a bunch of threads off at the same time then wait for them to complete; otherwise, what is the point of using threads in the first place.  It’s all about concurrency.

Here’s the output of our program.

% ThreddFoxxFunctionOnly.exe
I will now procrastinate 5 seconds
I will now procrastinate 4 seconds
I will now procrastinate 5 seconds
I will now procrastinate 5 seconds
I will now procrastinate 5 seconds
I will now procrastinate 4 seconds
I will now procrastinate 1 seconds
I will now procrastinate 2 seconds
I will now procrastinate 2 seconds
I will now procrastinate 2 seconds

Once you have all the pieces together, running threads with a simple function is rather easy in an MFC application.  I encourage you to look at the code and try different options.  I am sure that there are many other ways of doing the same thing, maybe even better than our example.

So now we want to do the same thing, but this time let’s call a member of a class.  Instinctively, you are probably thinking that this should be an easy thing to do—just pass the object-method as the first argument to AfxBeginThread().  At least, that is what I thought too.  Unfortunately, it doesn’t work that way.  You have to use some trickery and shenanigans to make this happen, but first some learning.

Functions and class members use different calling conventions under the C++ hood.  Functions use __stdcall and class members use __thiscallAfxBeginThread() expects its functions to use __stdcall.   If anything else is used, then your code will not compile.  You will soon become angry and frustrated, like I did.  Eventually you will abandon C++ for something more appealing, like being a bedpan orderly in a mental hospital—or a patient—if you spend too much time fretting over this quandary.

There is loophole though and our example shows it.  First, create a class like you normally would.  You then create a static method in the class.  This is the method that AfxBeginThread() will call from main.  Static methods in classes use __stdcall—that’s the first part of the loophole.  The second part is LPVOID.  Do you remember that I told you that you can pass anything with it?  Well, why not pass an instance of the class itself—that class we created in our example is called ThreddFoxx.  The class contains a static method called RunThread(). We will pass ThreddFoxx::RunThread() as the first argument to AfxBeginThread().  Next we will pass as a second argument to AfxBeginThread() a pointer to an ThreddFoxx object that we will instantiate in main just before calling AfxBeginThread() .  Remember that we need to use reinterpret_cast to cast the ThreddFoxx object as an LPVOID pointer just like we did in our previous example with the for loop integer.  We are almost done.  Inside the static method ThreddFoxx::RunThread() definition, we use reinterpret_cast to recast the LPVOID pointer back to the ThreddFoxx object.  Now, with the ThreddFoxx object at our disposal, we can call any of its public methods.  The one of interest for us is the tellJoke() method.  If you are like me, it took me a while to figure this out, but take your time and study the code—you will get it.

Let’s make this example more realistic.  We create a simple struct called THREADTRACKER that allows us to bind an instance of a ThreddFoxx along with its corresponding CWinThread handle—which is returned by the AfxBeginThread() function.  We then create 10 instances of these structs and stored them in a STL vector.  This allows us to keep track of each thread once they have all been spawned.  Unlike our previous example of spawning a thread then waiting for it to complete before spawning the next thread, here we spawn all ten at the same time–we then go back and wait for the threads to complete—we then go back again to show you that the values are indeed encapsulated in each unique ThreddFoxx instance.  Here’s is the code:

#include <iostream>
#include <iafxwin.h>
#include <ivector>
#include <icstdlib>
#include <ictime>

using namespace std;

class ThreddFoxx
{
public:
  ThreddFoxx();
  ThreddFoxx( int iSeqNum );
  ~ThreddFoxx();
  static UINT RunThread( LPVOID params );
  UINT tellJoke();
  void showJokeNumber();

private:
  int  m_iSeqNum;
};

ThreddFoxx::ThreddFoxx() { m_iSeqNum = -1; }

ThreddFoxx::ThreddFoxx(int iSeqNum) { 

  m_iSeqNum = iSeqNum; 

  srand( (unsigned int)time(NULL) + m_iSeqNum );

  m_iSeqNum = rand() % 10 + 1;
}

ThreddFoxx::~ThreddFoxx() {}

UINT ThreddFoxx::RunThread( LPVOID params )
{
  ThreddFoxx *tf = reinterpret_cast
(params);

  tf->tellJoke();

  return 0;
}

UINT ThreddFoxx::tellJoke()
{
  // Do random sleep times to make
  // this example a bit more realistic
  Sleep(m_iSeqNum * 1000);

  cout << "How many lightbulbs does it take to screw a tester? "
       << m_iSeqNum << endl;;

  return 0;
}

void ThreddFoxx::showJokeNumber()
{
  cout << "Joke number is " << m_iSeqNum << endl;
}

// This struct does nothing more than
// map the ThreddFoxx instance to
// its thread handle.
struct THREADTRACKER
{
  ThreddFoxx threddFoxx;
  CWinThread *pThread;
};

int main( int argc, char **argv )
{
  // Create a vector to hold our array
  // of THREADTRACKERs
  vector
 vThreads;

  // Create and initialize 10 ThreddFoxxes
  for ( int i = 0; i < 10; i++ )
  {
    ThreddFoxx x(i);

    THREADTRACKER tt = {x, NULL};

    vThreads.push_back(tt);

    tt.threddFoxx.showJokeNumber();
  }

  // Now kick off all of the threads at once
  for ( unsigned int i = 0; i < vThreads.size(); i++ )
  {
    vThreads[i].pThread =
      AfxBeginThread(
        ThreddFoxx::RunThread,
        reinterpret_cast(&vThreads[i].threddFoxx));
  }

  // Now wait for them to complete...remember that each
  // has a random Sleep time...although we are just doing
  // this in order.
  for ( unsigned int i = 0; i < vThreads.size(); i++ )
  {
    WaitForSingleObject(vThreads[i].pThread->m_hThread, INFINITE);
  }

  // Just to prove here that the class holds it own state
  for ( unsigned int i = 0; i < vThreads.size(); i++ )
  {
    vThreads[i].threddFoxx.showJokeNumber();
  }

  return 0;
}
% ThreddFoxx.exe
How many lightbulbs does it take to screw a tester? 1
How many lightbulbs does it take to screw a tester? 1
How many lightbulbs does it take to screw a tester? 4
How many lightbulbs does it take to screw a tester? 4
How many lightbulbs does it take to screw a tester? 4
How many lightbulbs does it take to screw a tester? 4
How many lightbulbs does it take to screw a tester? 7
How many lightbulbs does it take to screw a tester? 7
How many lightbulbs does it take to screw a tester? 8
How many lightbulbs does it take to screw a tester? 10
Joke number is 4
Joke number is 8
Joke number is 1
Joke number is 4
Joke number is 7
Joke number is 1
Joke number is 4
Joke number is 7
Joke number is 10
Joke number is 4

A few caveats you should be aware of before trying this code.  This is an MFC console application.  I used Visual Studio 2008 on a Win 7 platform.  You can use the wizard to create an MFC application, but in my case, I created an empty project at first. I then had to make one change in my Visual Studio Project->Properties->Configuration Properties->Code Generation->Runtime Library setting.  Set it to Multi-threaded (/MT). The rest should be cut-and-paste, compile, and the run.  Good luck.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
Tagged with:  

Gear Shifting, Beer Drinking ENUM Testing in C++

C/C++ API testing usually involves testing parameters that are defined as enumerated types or enums.  Developers like to use enums because they make APIs more readable since related data can be easily grouped together and referenced in external documentation.

As test developers, we can take quick advantage of enums as long as they are ordered in logical and predicable ways.  The example I provide below shows the gears of a vehicle as an enum type.  I intentionally space them numerically from low to high.  It seems like the natural thing to do.  We can take advantage of this order when we do parameter testing against the shiftGear() function.  The function takes a GEARS type as a single argument.  We don’t know what is inside the function so we must test all positive cases, REVERSE to FIFTH and all negative cases outside of the valid enum range.

So to take advantage of the order, I created a simple for loop to traverse from REVERSE to FIFTH gear.  You may have noticed that I am using GEARS(int) instead of just using the int in the for loop.  It has to be done this way because although we can assign a GEARS to an int, we can’t assign an int to a GEARS. GEARS(int) allows me to cast the int to an enum.  It’s a little confusing for beginners because the types of GEARS are really just integers, but here is how it goes:

int x = FIRST;  // OK

GEARS y = 1;  // NOT OK

One other interesting aspect of the GEARS(int) syntax is that it allows us to cast values that are not defined in the original GEARS enum structure.  This is really useful for negative, out-of-bounds testing as seen later in this example.  It allows me to break the API rules without breaking compilation rules.

#include <iostream>

using namespace std;

// Valid gears to work with
enum GEARS {
  REVERSE = -1,
  NEUTRAL = 0,
  FIRST = 1,
  SECOND = 2,
  THIRD = 3,
  FOURTH = 4,
  FIFTH = 5 };

// Function API to test
void shiftGear( GEARS gear );

int main(int argc, char **argv)
{
  // It's always safe to start in neutral
  GEARS gear = NEUTRAL;

  // Check within boundary...everything should work
  for ( int i = REVERSE; i <= FIFTH; i++ )
  {
    shiftGear( GEARS(i) );
  }

  // Below expected boundary
  shiftGear( GEARS(-255) );

  // Above expected boundary
  shiftGear ( GEARS(255) );

  return 0;
}
% demo.exe
Shifting gear to -1
Shifting gear to 0
Shifting gear to 1
Shifting gear to 2
Shifting gear to 3
Shifting gear to 4
Shifting gear to 5
Not Shifting gear to -255 because not allowed
Shifting gear to 255 ahhhhh, transmission blown, die!

The pretend bug here is that the 255 case is not caught by the function, so the transmission blows up.  As I mentioned before, the logic has to make sense to test it this way.  What happens if we change the order of the positive tests?  What if we decide to shift straight from FIFTH to REVERSE?  It’s allowed in real life and probably here, but is this a smart thing to do?  This is where you get into an argument with the developer who says that although it will destroy the transmission, the specification allows for it; therefore, this is not a real bug.  Maybe so, I don’t know.  Factory recalls can be very expensive though.

There one other danger regarding the enum-based parameter testing.  There is nothing stopping developers from removing, adding, or reordering elements in enum structures.  Not a good idea, but it does happen.  If it does happen, regression tests are likely to break.  The effect is like grinding the gears of a transmission that is tongue-frozen to a metal chalkboard covered with someone’s dirty fingernails.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
Tagged with:  
Page 1 of 212

Random Site Quotes

“Always be testing, never be resting.”
© 2009-2011 TestDeveloper.com
Powered by WordPress
Content provided by John L. Whiteman and his Slam Carrot Long Ears Gang