{C++ etc.}

Latest Posts
 
Home | C++ Posts | Linux Posts | Programming Posts | Issue Tracking Posts

Monday, November 16, 2009

Design Patterns List

http://dirkriehle.com/computer-science/research/dissertation/appendix-d.html

Contains a list of GOF patterns and several additional ones.

Tuesday, October 27, 2009

How Software Companies Die by Orson Scott Card

A friend of mine sent this to me and it immediately captured my attention because of its synonymous nature with some of the present day software organizations.

Software: How Software Companies Die  ====================================  by Orson Scott Card  -------------------  The environment that nurtures creative programmers kills management and marketing types - and vice versa.  Programming is the Great Game.  It consumes you, body and soul.  When you're caught up in it, nothing else matters.  When you emerge into daylight, you might well discover that you're a hundred pounds overweight, your underwear is older than the average first grader, and judging from the number of pizza boxes lying around, it must be spring already.  But you don't care, because your program runs, and the code is fast and clever and tight.  You won. You're aware that some people think you're a nerd.  So what? They're not players.  They've never jousted with Windows or gone hand to hand with DOS.  To them C++ is a decent grade, almost a B- not a language. They barely exist.  Like soldiers or artists, you don't care about the opinions of civilians.  You're building something intricate and fine. They'll never understand it.  Beekeeping  ----------  Here's the secret that every successful software company is based on: You can domesticate programmers the way beekeepers tame bees.  You can't exactly communicate with them, but you can get them to swarm in one place and when they're not looking, you can carry off the honey.  You keep these bees from stinging by paying them money.  More money than they know what to do with.  But that's less than you might think.  You see, all these programmers keep hearing their parents' voices in their heads saying "when are you going to join the real world?"  All you have to pay them is enough money that they can answer (also in their heads)  "Geez, Dad, I'm making more than you."  On average, this is cheap.  And you get them to stay in the hive by giving them other coders to swarm with.  The only person whose praise matters is another programmer. Less-talented programmers will idolize them; evenly matched one will challenge and goad one another; and if you want to get a good swarm, you make sure that you have at least one certified genius coder that they can all look up to, even if he glances at other people's code only long enough to sneer at it.  He's a Player, thinks the junior programmer.  He looked at my code.  That is enough. If a software company provides such a hive, the coders will give up sleep, love, health, and clean laundry, while the company keeps the bulk of the money.  Out of Control  --------------  Here's the program that ends up killing company after company.  All successful software companies had, as their dominant personality, a leader who nurtured programmers.  But no company can keep such a leader forever.  Either he cashes out, or he brings in management types who end up driving him out, or he changes and becomes a management type himself.   One way or another, marketers get control.  But...control of what?  Instead of finding assembly lines of productive workers, they quickly discover that their product is produced by utterly unpredictable, uncooperative, disobedient, and worst of all, unattractive people who resist all attempts at management.  Put them on a time clock, dress them in suits, and they become sullen and start sabotaging the product.  Worst of all, you can sense that they are making fun of you with every word they say.  Smoked Out  ----------  The shock is greater for the coder, though.  He suddenly finds that alien creatures control his life.  Meetings, Schedules, Reports.  And now someone demands that he PLAN all his programming and then stick to the plan, never improving, never tweaking, and never, never touching some other team's code. The lousy young programmer who once worshipped him is now his tyrannical boss, a position he got because he played golf with some sphincter in a suit.  The hive has been ruined.  The best coders leave.  And the marketers, comfortable now because they`re surrounded by power neckties and they have things under control, are baffled that each new iteration of their software loses market share as the code bloats and the bugs proliferate.  Got to get some better packaging.  Yeah, that's it...working toward a better product line...  

Sunday, October 11, 2009

Functions that take length of strings as parameters

Lately, I've been working on a component which had HUGE issue with string lengths. The problem was that all the strings were initialized with an integer instead of defined lengths. When these were used in various places in the source, the programmer has used various lengths to alter the same string. And now I find myself faced with the nightmare of cleaning up the mess.

The code used to look like this:
z_User[31];
pCursor->Define(3, z_User, 30); // wrong. would only copy 29 chars off a database column
pMsg->Get(5, z_User, 30); // wrong. would only copy 29 chars off a message
ToUpperCase(z_User, 30); // correct. expects user to pass the length to convert and then appends '\0'

The problem is, functions which take string length as an argument would treat this length differently. For example, strcpy requires you to give one less than the actual length of the string in order to have space to print the NULL termination character. Another problem is the situation one would find ones self in if the size of the string were to be changed (e.g. change the size of User to 50).
When writing a function which uses char buffs, it would always be prudent to implement it in a safe way so that users would not have to worry about the actual implementation and wonder how it would behave if you pass the full length of the string to it. The above code would ideally be written as (keeping the same structure):

const int LEN_USER = 51;
z_User[LEN_USER];
pCursor->Define(3, z_User, LEN_USER);
pMsg->Get(5, z_User, LEN_USER);
ToUpperCase(z_User, LEN_USER); // Function changed to accept the full length of the string

The real fun begins when you have to do these changes in multiple code paths. :)

Wednesday, September 09, 2009

Installing Shrew vpn client on Fedora 10



There are some dependencies which have to be addressed when trying to install Shrew vpn client on Fedora 10.

IMPORTANT: Try to obtain the latest beta version of shrew. The stable package requires an outdated version of QT (3.2) and it's hard to set up since it uses the config.h file which is not included in modern versions of the linux kernel.
  • yum -y install cmake
  • yum -y install openssl-devel
  • yum -y install flex
  • yum -y install bison
  • install QT dev package using package manager
Run:
cmake -DCMAKE_INSTALL_PREFIX=/usr -DQTGUI=YES -DETCDIR=/etc -DNATT=YES

After installing the shrew client, you could set up the connection to a Cisco VPN network by importing a valid .pcf file. This is preferred over manual set up since the user might not be aware of some of the connection details. If you connect to the VPN using windows, this file is automatically created and you could find it by doing a simple search.

You could use rdesktop as a Remote Desktop client along with shrew to access windows machines in the VPN.


Sunday, September 06, 2009

Remove Stray Code Lines Before a Code Review




One of the modules that I'm in charge of, had an object which set a bool called b_Delete inside the destructor. While working on a new class which would handle a collection of these objects, I used:
list_A.erase(pX); if (! pX->b_Delete) // Already deleted { delete pX; } This was meant to crash if some other class removed the object in an asynchronous callback. After I have removed all the unwanted deletes else where I could remove the check. Unfortunately, the code remained as is. Right now I'm suffering the consequences. Some of my colleagues who saw this think that I'm not aware that you can't refer to objects inside a deleted object. The code works because I've already removed all of the unwanted delete calls on pX. Note to self: Go through each new code line before a code review

Fedora 10 doesn't have gcc pre-installed

Imagine my surprise when I tried to compile a test c++ program after installing Fedora 10 and it failed with the error "Command not found".
I had to install it manually with yum -y install gcc sudo (as root)

Thursday, May 21, 2009

Altering the primary key of an Oracle Table

Eg: Table T_1 has the following columns:
T_1
--------------
NAME VARCHAR2(100) not null (primary key)
AGE INT
ID VARCHAR2(100)
PASS VARCHAR

NAME is the primary key.
If we want to add INT to the primary key and make it a composite key:
1. We must first make the ID column "not null" which means it could not have any NULL entries.
2. We should drop the existing primary key.
3. Create the new primary key.


PL/SQL script to achive this:

alter table T_1 modify NAME VARCHAR2(100) NOT NULL;
alter table T_1 drop primary key;
alter table T_1 add primary key (NAME, ID);
commit;

:)

Sunday, May 03, 2009

STL containers for message buffers in socket(-like) communications

I always wondered why custom buffer classes were used in most of our (high performance) libraries. This post made me realize that STL, as extensively used as it is, is not a golden hammer.

Tuesday, April 28, 2009

C++ Comma Confusion via LightSleeper

Many C++ programmers are surprised by the effects of that little comma. In some cases (e.g. comma operator), the comma very clearly describes the order of operations. In other cases (e.g. function parameter separators), the comma does not describe the order. h() could execute before g() in the last example, and it often does in real compilers. Understanding the difference is well worth your time.


Original Post

Thursday, April 23, 2009

awk Search script with prior and following line capability

#!/bin/sh
# *********************************************************
# This uses nawk to list lines coming prior to and after
# the given search string.
# Format: xgrep
# ********************************************************
if [ $# != 4 ]
then
echo "Usage: $0 "
exit
fi
STR=$1
BEF=$2
AFT=$3
while [ ! -z "$4" ] ; do
echo ========== $4
nawk 'c-->0{print NR ":\t" $0;};$0~s{if(b)for(c=b+1;c>1;c--) print (NR-c + 1) ":\t" r[(NR-c+1)%b];print NR ":\t" $0;c=a}b{r[NR%b]=$0;}' b=$BEF a=$AFT s=$STR $4 | sed "s/^/$4\
/"
shift
done
echo ==========

Took me a while to understand how awk worked and customized the command I found on the net for my own needs.

Wednesday, April 22, 2009

sed and Nix Quotation Confusion

I wanted to use "sed" inside a script to make changes to a text file. The file looked like this:

/*
** Project "OrderCache.7.7.29"
** Hint: deleting everything below the "cause" field will set
** the defaults appropriately for the cause you have chosen.
*/
brief_description = "none";
description = "none";
cause = internal_bug;
test_exempt = true;
test_baseline_exempt = true;
regression_test_exempt = true;
architecture =
[
"unspecified",
];

I wanted to replace the "brief_description" with a value given by the user. So:

#!/bin/csh
set DESC = "$<"

But when I tried to use sed with $DESC:

sed -i 's%brief_description\ \=\ \"none\"\;%brief_description\ \=\ \"$DESC\"\;%g' temp_next.txt

the command would only change "brief_description" as follows:

brief_description = "$DESC";

The reason for this is that the variable has to be inside double quotes in order to get it dereferenced back to the actual value. So the solution is:

sed -i 's%brief_description\ \=\ \"none\"\;%brief_description\ \=\ \"'"$DESC"'\"\;%g' temp_next.txt


Monday, April 20, 2009

posix_spawnp Failure with WEXITSTATUS 127

One problem with posix_spawnp is that if it fails after successfully spawning a new process, the exit status of the spawned process is always 127. This gives us no clue what so ever as to what caused the problem.
I came across this a few days ago and struggled with it for a while before re-writing the code using "fork()" and "execvpe" to achieve the same effect. The "exec" calls also failed but they gave a proper error value (via errno) from which the cause of the error could be found (perror(errno)).
In my case, errno was 14 and the error message said "Bad address" which turned out to be caused by an invalid argument list passed to execvpe. I wasn't terminating the argument list with NULL set as the last element.
Having a better error reporting system in posix_spawnp would have saved me alot of trouble

Wednesday, April 15, 2009

High precision floating point arithmatic in C++

One of my friens had a need for a floating point type that would allow a precision level upto 9 decimal points. "long double" would have been our choice if not for the differences in implementation and VC++ not supporting it (in VC++, long double = double).
We opted for doubledouble which has a precision level upto 30 decimal points.
Some other options are available here.

Monday, April 06, 2009

Posix Threads and FT Handling

We have a set of stringent FT mechanisms at our company since failure of a single process might spell disaster for the whole system. Threre are multiple instances of the same process running as primary and mirror. And there are multiple "Sets" which hold copies of the whole system so if one set goes down, another could take over.
If a primary process goes down, an "FT_CHANGE" happens and the mirror becomes the primary.
I came across an instance where the mirror process was made to "Fail over" just as it became "Ready" (A process is "Ready" once it finishes the initialization process and sends a message to the controlling system). This has resulted some bizarre behaviour.
After having a look at the logs, we came to the conclusion that this was due to the fact that the process gave the "Ready" signal before some "pthread_create" calls have finished executing. I check the return types of the code but this does not guarantee that the threads are up and running at that moment.
The lesson: Wait till the child thread comes up and sends the main thread an acknowledgement before making any calls to that thread (like we do in most of the other processes)