The Minimum You Need to

Know
About Mono and Qt

Roland Hughes

Logikal Solutions

Copyright © 2011 by Roland Hughes 
All rights reserved
Printed and bound in the United States of America
ISBN­13 978­0­9823580­8­5
This book was published by Logikal Solutions for the author.  Neither Logikal Solutions nor the author shall be
held responsible for any damage, claim, or expense incurred by a user of this book and the contents presented 
within or provided for download at http://www.theminimumyouneedtoknow.com.

These trademarks belong to the following companies:
Trademark

Owner

Borland

Borland Software Corporation

C#

Microsoft Corporation 

DEC

Digital Equipment Corporation
Hewlett Packard Corporation

DEC BASIC

Hewlett Packard Corporation

Eclipse

Eclipse Foundation

Firefox

Mozilla Foundation

HP

Hewlett Packard Corporation

IBM

International Business Machines, Inc.

Java

Sun Microsystems, Inc.
Oracle Corporation

KUbuntu

Canonical Ltd.

Linux

Linus Torvals

Lotus Symphony

International Business Machines, Inc.

Mac

Apple Inc.

MySQL

Oracle

Netware

Novell, Inc.

OpenVMS

Hewlett Packard Corporation

OpenOffice

Sun Microsystems, Inc.

OpenSuSE

Novell, Inc.

Oracle

Oracle Corporation

OS/2

International Business Machines, Inc.

RMS

Hewlett Packard Corporation

RDB

Hewlett Packard Corporation

SourceForge

SourceForge, Inc.

Ubuntu

Canonical Ltd.

Unix

Open Group 

VAX

Hewlett Packard Corporation

Windows

Microsoft Corporation

Trademark
Zinc Application 
Framework

Owner
Professional Software Associates, Inc.

All other trademarks inadvertently missing from this list are trademarks of their respective owners.  A best effort
was made to appropriately capitalize all trademarks which were known at the time of this writing.   Neither the
publisher nor the author can attest to the accuracy of any such information contained herein.  Use of a term in this
book should not be regarded as affecting the validity of any trademark or service mark.

Additional Books by Roland Hughes
You can always find the latest information about this book series by visiting 
http://www.theminimumyouneedtoknow.com.  Information regarding upcoming and 
out­of­print books may be found by visiting http://www.logikalsolutions.com and clicking 
the “upcoming and out of print books” link.  At the time of this writing, Logikal Solutions 
and Roland Hughes offer the following books either in print or as eBooks.

The Minimum You Need to Know About Logic to Work in IT
ISBN­13 978­0­9770866­2­7
Pages:  154
Covers   logic,   flowcharting,   and   pseudocode.     If   you   only   learned   OOP,   you
really need to read this book first.
The Minimum You Need to Know To Be an OpenVMS Application Developer
ISBN­13 978­0­9770866­0­3
Pages: 795
Includes CD­ROM
Covers   DCL,   logicals,   symbols,   command   procedures,   BASIC,   COBOL,
FORTRAN,   C/C++,   Mysql,   RDB,   MMS,   FMS,   RMS   indexed   files,   CMS,
VMSPhone, VMSMAIL, LSE, TPU, EDT, SORT, and many other topics.  This
book was  handed  out by HP at a technical  boot camp because  the OpenVMS
engineering team thought so highly of it.
The Minimum You Need to Know About Java on OpenVMS, Volume 1
ISBN­13 978­0­9770866­1­0
Pages: 352
Includes CD­ROM
Covers  using  Java  with  FMS and RMS  indexed  files.    There  is a lot of JNI
coding.  We also cover calling OpenVMS library routines, building with MMS
and storing source in CMS.

The Minimum You Need to Know About Service Oriented Architecture
ISBN­13 978­0­9770866­6­5
Pages: 370
The National Best Books 2008 Award Winner – Business: Technology/Computer
Covers accessing your MySQL, RDB, and RMS indexed file data silos via Java
and port services from a Linux or other PC front end.  Also covers design and
development of ACMS back end systems for guaranteed execution applications.
The Minimum You Need to Know About Java and xBaseJ
ISBN­13 978­0­9823580­3­0
Pages: 186
This  book is available  only  as a free PDF.   It's source  files  are available  on
SourceForge  and on the book's  Web  page.   This book is meant  to provide  a
much needed tutorial for the Open Source xBaseJ library.   If you have some
fundamental  Java skills this book can have you developing your own xBaseJ
applications in a matter of hours.  The xBaseJ library was used by the author to
create the FuelSurcharge project on SourceForge. 
The Minimum You Need to Know About Qt and Databases
ISBN­13 978­0­9823580­5­4
Pages: 474
This book is meant to provide a much needed tutorial on using Qt with various
IDEs   and   database   tools.     Most   of   the   books   on   the   market   do   a   great   job
showing you most of the GUI features of Qt, but are sadly lacking when it comes
to explaining how to use Qt with databases.  It is not uncommon to find at most
one chapter in your favorite Qt book and to learn it is woefully inadequate for
the task at hand.  This book is meant to solve those problems.  While Qt attempts
to shield you from many underlying database differences, this book will prove
that it is only partially successful and you still have to design your application
around the limitations of your chosen database.

Infinite Exposure
ISBN­13 978­0­9770866­9­6
Pages: 471
A novel about how the offshoring of IT jobs and data centers will lead to the
largest  terrorist  attack  the free world has ever seen and ultimately to nuclear
war.
There   are   a   number   of   reviews   of  this   book   available   on­line.     The   first   18
chapters are also being given away for free at BookHabit, ShortCovers, Sony's
eBook store, and many other places.  If you can't decide you like it after the first
18 chapters, Roland really doesn't want to do business with you.
John Smith:  Last Known Survivor of the Microsoft Wars
ISBN­13 978­0­9823580­6­1
A post apocalypse novel which some might consider the sequel to Infinite Exposure.  If I
do my job correctly, it should piss just about everyone off.

Source Code License
This book is being offered to the public freely, as is the source code.  Please leave  
comments about the source of origin in place when incorporating any portion of the code 
into your own projects or products.
Users of the source code contained within this book agree to hold harmless both the author 
and the publisher for any errors, omissions, losses, or other financial consequences which 
result from the use of said code.  This software is provided “as is” with no warranty of 
any kind expressed or implied.
Visit http://www.theminimumyouneedtoknow.com to find a download link if you don't 
want to retype or cut and paste code from this book into your own text editor.

Table of contents

Introduction
Why This Book?
I had to ask myself this very question when starting to write this book.  Actually, an
author should really ask that question about every book they write but it was particularly
important for this book.  There are oceans of books on C#.  There are ponds of books
covering Mono.  There are various Web sites devoted to the promotion and support of
Mono and its various Open Source off­shoots.  Why should I write a book on it?
Believe it or not, I came up with a pretty good answer.  Most of the books out there
fall into one of the following categories:

Rah­Rah Microsoft, don't bother teaching anything

Language syntax bible which might be great for reference, but not for teaching.

Me­Too   regurgitation   of   the   stuff   available   for   free   on­line   by   professional
authors who have to crank out at least six books per year to earn a living.

Those of you who have followed this series know that my books never fall into those
three categories.  I've spent over 20 years in the world of IT with most of my years as a
real consultant.  The difference between someone who calls themselves a consultant and
a real consultant can easily be seen on their resumes.  Scan back over the past 20+ years
and you will see the people who call themselves consultants have worked at no more
than three companies.  Once in the door they latch on like a parasite and try to become
indispensable so they can milk the site for all it's worth.   A real consultant will rarely
spend more than 18 months at any single client site, but they will be called back to sites
multiple times over the years.  In short, a real consultant travels from client site to client
site   picking   up   information   about  additional   ways  of  doing   things   rather   than  doing
things the same way for 20+ years.

12

Introduction

Why is the definition of a consultant important?  That's simple.  Most of the books
out there on Mono/C# weren't written by real consultants.  They were written by people
who   call   themselves   consultants.     While   many   will   claim   to   have   over   20   years   of
experience in the field, most of them will have one year of experience repeated 20 times
rather than have traveled all over and done many things.  You don't have to dig deep in
their backgrounds to find out if the book you are about to buy is a waste of cash or not,
simply flip to the section on connecting to a database.  (That's right, there will be only
one and it might not even consume an entire chapter.)  Flip through the beginning and
very   end   of   that   section.    At   any   point   do   they   point   out   directly   connecting   an
application across the Internet or from outside of a secured internal network is a really
bad idea?   If the answer  to that  question  is “yes”, the book  you are looking  at was
written  by a veteran;  “no” means your book was written  by a commercial  author  or
someone with less than one year of real experience no matter how many years it was
repeated.
Yes, we will cover that topic yet again because I seem to be the only one writing
about it and the rest of the IT world seems to be appearing on “60 Minutes” trying to
explain why you shouldn't go to prison for writing the system which lead to this month's
largest identity theft.
Why this book?   Because I lived when this happened and Microsoft sure as hell
didn't  invent  C#.   I'm tired of seeing books anoint Microsoft for  inventing  something
they just renamed, bought, or in this case, mostly stole.
Why this book?  Because Microsoft is quickly disappearing from desktop and back
office   environments.     Companies   which   made   the   mistake   of   betting   on   them   need
someone to show them alternatives now, before it is too late.
Why this book?  Because most developers cannot learn an OOP tool from either a
syntax reference manual or a marketing brochure.  I'm going to continue doing what this
series does and has been acclaimed for, redeveloping applications with different tools so
developers can straddle technologies.

Introduction

13

Why OpenSuSE?
It is true that I've used Ubuntu and KUbuntu for other books in this series.  While
that set of Linux distros may be the most famous, they've taken some shortcuts to target
the now disappearing NetBook market which has established a sunset date for Ubuntu as
well.  There is a real problem with their distribution methodology which is forcing some
incredibly bad design decisions into that distro.  If you mandate that your initial “live”
version fit on a single CD instead of a DVD, you are going to make an awful lot of bad
decisions due to that initial bad decision.
OpenSuSe comes on a DVD, or a thumb drive, and in other methods which allow for
much more than just a single CD's worth of storage.   Because of this you don't see a
different release  of OpenSuSE for each potential  Linux desktop.   Not only are these
desktops all available on your initial installation media, they are actually tested together.
I cannot  tell you the number  of times  I was using  one flavor  of Ubuntu  but needed
something written for one of the other flavors to make my life easier, then had lots of
things stop working correctly once the other 700MEG was downloaded to support the
other desktop.  When you posted a support issue, you were quite honestly told “don't do
that” and the issue was closed.
Another reason we are using OpenSuSE instead of Ubuntu is that the support people
actually care.   I have wasted hundreds of hours in email arguments with the supposed
powers that be in Ubuntu land pointing out massive technical flaws due primarily to
their genetic inability  to grasp  technical topics.   Quite recently one of these cerebral
giants told me they were going to simply close without comment bug reports I was filing
about   their   forcing   all   things   Qt   to   use   database   plug­ins   instead   of   compiled   in
connections “because plug­ins were more secure.”   The English language simply does
not have the ability to accurately describe the depth of that stupidity, and this was the
person in charge!  Definitely promoted to their level of inability!  I didn't ask them, but
they sure sounded like an MBA from Keller!  That level of incompetence is the norm for
graduates of that school in my experience.

14

Introduction

For those of you who do not comprehend the security hole Open Source plug­ins
create, imagine if some Russian mafia family, or Chinese Triad, or some other organized
crime entity takes it upon themselves to write a custom version of each plug­in for each
release.  The custom version adds the “feature” of logging all table layouts and I/O to the
“temp” directory, then queuing a task at program exit to transmit this information to a
server of theirs somewhere on the Web.  
The   crime   family   then   “donate”   a   lot   of   time   to   various   Open   Source   projects
loading  these  plug­ins into the  distributions.    Nobody  notices  any difference  because
they have only added a logging and delayed transmit feature.  The crime family ends up
with   every   record   written   to   every   database   using   those   plug­ins   on   every   system
containing them.  Yes, they end up with a lot of chicken recipies and music catalogs, but,
eventually   they   start   getting   the   records   for   various   Open   Source   competitors   to
Quicken,   QuickBooks,   Seible,   etc.     Now   they   have   current   balance   and   account
information and possibly even identies.  All that is necessary to stop this from happening
is   to   statically   compile   in   the   database   connectivity.     Organized   crime   must   then
infiltrate each Open Source package they want data from instead of any package that
could be installed on your computer.  Points of failure now reduced from billions to one.
In short, we are  using OpenSuSE  because  it has matured  and, regrettably,  it has
close ties to Microsoft.  You might remember that Novell cut a deal which let Microsoft
sell SuSE servers and gave Novell a big chunk of cash.  Part of that cash went to Novell
producing  a  bunch  of  classes  providing  Linux  services  to  Mono  Core  libraries.    I'm
currently using a 64­bit version of OpenSuSE 11.4 both to do this development and to
write this book.  It is by far the stablest and best thought out version of Linux I have ever
used.   It doesn't currently have the “fan base” of Ubuntu, but the “shine” of Ubuntu's
initial “just works” marketing campaign is starting to wear off now that many people are
encountering things which don't work.
Speaking of things which don't work, I tried to make it an entire month with Fedora
14 before moving to the latest OpenSuSE.   I realize Fedora has its fans, but, nothing
worked   that   I   really   needed   and   Fedora's   desire   to   force   my   disks   into   some   LVM

Introduction

15

configuration really irked me.
If   you  want   a  more  believable   explanation,  how  about   this?    Ubuntu   has  begun
ignoring its user base in order to cling to some early marketing decisions.  Fedora 14 is a
train   wreck.     OpenSuSE   was   the   last   end   user   desktop   on   this   list:
http://www.ultraedit.com/products/uex.html   I have seen that exact same list for other
commercial products as well.  Yes, there will always be hundreds of Linux distros, but
there will only be a handful companies spending actual dollars for commercial products.
At this point in time it looks like OpenSuSE will be the survivor three years down the
road.
How C# Really Came About
A long time ago there was a company named Sun Microsystems (now owned by
Oracle   Corporation.)     Like   many   computer   companies   of   the   day   it   had   proprietary
computer hardware and operating systems.  Unlike most computer companies of its day,
it had direct involvement with embedded systems and to some extent video games.  The
embedded systems  market was becoming an expensive pauper's  child and some high
minded individuals at Sun looked to solve this problem.  Indeed, they could not achieve
their vision of Internet connected appliances unless they could create a prepackaged and
ready to program embedded computer for only a couple of dollars.
Embedded   systems   are   so   prevalent   in   today's   world   that   most   of   you   cannot
imagine life without them.   That coffee maker which you program to start brewing at
some point in the morning has an embedded system in it.   That DVD player and the
remote  control  for it?   Yep, both of them.   If you happen  to drive a car  which was
built­in   the   past   ten   years   it   has   somewhere   between   dozens   and   hundreds   of   self
contained embedded systems on board.
Let's consider for a moment the DVD player that retails for $40 in the U.S.   That
thing most likely has a production cost of less than $8, including all packaging.  How do
I figure that?   Most retailers purchase inventory via a distributor, not direct from the
manufacturer and both of them will expect at least a $10 cut of that $40 list which leaves

16

Introduction

about $12 per unit profit for the manufacturer, less shipping costs, warranty claims, and
returns.
Just how much do you think they actually spent on the embedded systems in both
the player and the remote control?  It was pennies.  Some little geek had to spend months
of   their   lives   burning   ROMs,   continually   shrinking   the   footprint   of   an   “application”
which continually was getting new features added.   He/she wasn't coding with a high
level language,  but working  in the assembler language for the chosen CPU trying to
squeeze   everything   to   the   cheapest   CPU   and   smallest   chip   count.     If   someone   in
purchasing got a “better deal” on a different CPU, the little geek had to start over.
The original  concept  was an embedded  Java  processor.    Almost  everything  on a
single chip on a little card with connector pins for serial, parallel, network, and possibly
even some display type device (normally LED connections.)   The unit would come in
several different flavors and sizes.  It would contain both flash ROM and actual memory
so that it could be updated on the fly.   The production cost would be driven down by
selling billions of units.
Yes,  the current  embedded  system   model  would  still  be  cheaper,  but  this model
would be both cheap and fast.  Code would be transportable between devices so instead
of taking 6­10 months to develop the next version programmers could have it to the
testing group in 6­10 days.  The presence of Internet capabilities, not to mention all of
that RAM meant features which were once science fiction could easily be implemented.
Rather than simply displaying some cryptic flashing lights or a fault code, your washing
machine  could signal the manufacturer it needed repair and what parts it needed.   It
would send along its serial number and the message would actually get to the service
department   of  the   vendor  who  sold   it   and  the   service   department  would  call   you  to
schedule an appointment.

Introduction

17

Laugh all you want about my washing machine description.  Some high end luxury
cars already have this feature.  There have even been television commercial pitching this
feature to consumers.  Just how do you think OnStar works?  You've all seen those TV
commercials where emergency personnel are dispatched automatically when the vehicle
determines it was involved in a collision with airbags deployed.   There is a series of
embedded systems all communicating together making that happen.
While it is true we have yet to get such a washing machine, we have gotten other
science fiction products.  With the embedded system in a DVR you can now pause live
TV and start  it back  up again.   Your  DVR can even connect  to a video  on demand
service and download movies for you to watch.   Do I even need to mention all of the
things your cell phone can do now, besides make a phone call?
Of  course,  the first  cut of Java, which  was to be the language  processed  by the
virtual machine in the embedded device, got written on Unix, then Linux, then a lot of
other   platforms.     Sun  wanted   to   test  it  and   get   it   adopted,  so  they   made  it  free   for
downloading.  Specifications were published for JVMs so anyone could develop a JVM
for their favorite platform, but Sun also developed the JVM for many platforms.   Of
course, it was the built­in Internet classes and the ability to work within Web browsers
that caused Java development to go off on a major tangent adding feature after feature.
Eventually, bloat became so bad that multiple editions of Java had to be released:

18

Introduction
Edition

Description

Java Card

For use with tiny footprint smart cards

Java ME (Micro Edition)

Various   packages   built   by   selectively
loading support only for the devices which
are present because loading support for all
would exceed available storage.

Java SE (Standard Edition)

Regular PC use

Java EE (Enterprise Edition) 

Lots   of   extra   APIs   for   multi­tier
client­server Enterprise development

Java oversold its “write once run anywhere” slogan, but it still became the mainstay
of most Web development.  One has to remember that this was during the DOT COM
stock bubble when “everybody was getting rich on the Internet.”   Microsoft was (and
still is) being left in the dust.  Industry analysts were starting to calculate the number of
days Microsoft would still be around as a company.
Naturally Microsoft took it upon itself to write its own Java Virtual Machine based
loosely on the Sun specifications and more tightly coupled to the Windows platform.
They started adding Internet Explorer and Windows specific extensions to the core VM
and even began producing executable files by fully compiling and binding Java source
code   to   an   executable   just   like   any   other   language.     (Eventually,   many   different
companies came up with many different ways to create self contained executables and
finally executable JAR files became part of the standard.)
There   were  many  heated  words  exchanged  in  the trade  press  between   these  two
corporations.  There were many hilarious Bill Gates parodies in the trade press as well.
Ultimately   there  was  a lot  of time  and  cash  spent  on lawsuits  and  Microsoft  had  to
“drop” its Microsoft Java Virtual Machine.
http://www.enotes.com/topic/Microsoft_Java_Virtual_Machine

Introduction

19

When it comes to bug ridden code that has already been paid for, Microsoft rarely
throws anything away.   Some notable exceptions would be Windows Vista, Microsoft
Bob, and Microsoft Money.   (Don't worry if you have never heard of these products,
they were and still are spectacular failures along with Zune and the soon to be forgotten
XBox360.)  Microsoft Bob uttered a few dying gasps as “Clippy” the Microsoft Office
Assistant and pretty much proved to the world why Bob was never allowed to procreate.
http://www.ask.com/wiki/Office_Assistant
Not long after the settlement with Sun, we saw the introduction of C#.  Actually, we
saw the first introduction of a product from Microsoft named C#.   You see, for some
time before that there had been regular monthly installments from  Al Stevens in Dr.
Dobb's Journal had a C/C++ library he was coding called C­Sharp which suddenly had to
be renamed D­Flat so C# could be launched.  Microsoft must have had their developers
spend all of 15 minutes tweaking their Java Virtual Machine to be C#.
HelloWorld.java
1
2
3
4
5
6
7

public class HelloWorld
{
public static void main(String[] args)
{
System.out.println( "Hello World!");
}
}

roland@linux-c345:~/mega_Mono> javac HelloWorld.java
roland@linux-c345:~/mega_Mono> java HelloWorld
Hello World!
roland@linux-c345:~/mega_Mono>

Just take a look at how different the world is with C#!

20

Introduction

helloworld.cs
1
2
3
4
5
6
7
8
9
10
11
12

using System;
namespace HelloWorld
{
class Hello
{
static void Main(string[] args)
{
Console.Out.WriteLine("Hello World!");
}
}
}

roland@linux-c345:~/mega_Mono> mcs helloworld.cs
roland@linux-c345:~/mega_Mono> Mono helloworld.exe
Hello World!
roland@linux-c345:~/mega_Mono>

Obviously there were oceans of effort put into making these two things different.
One thing which really corks me off, and should cork off every IT professional is the
fact   that,   even   on   a   Windows   platform,   the   p­compiled   code   file   is   given   an   EXE
extension.  On the DOS/Windows platform the EXE extension had been used for years
to indicate a stand­alone program.
Now Microsoft has a host of languages which exist only as front ends and p­compile
to   the   same   virtual   machine.     Of   course   Microsoft   calls   this   p­compiled   version   IL
(Intermediate Language) and their Virtual Machine is called CLR (Common Language
run­time.)  This set of languages and virtual machines is called their common language
infrastructure.    Since  they didn't  want to completely  piss off the Assembly  language
freaks out there, hard core bit twiddlers are allowed to code their programs directly in IL
if they wish.
Before you go giving Microsoft credit for choosing to compile to an Intermediate
Language, you should read up on just how many years the GNU project had been doing
that with their compiler set  before Microsoft even inched in that direction.  As long as
the   intermediate   language   chosen   is   robust   enough   to   support   all   facets   of   a   source
language,   you  can  create  a  front   end  for   any   language   you  want   except  COBOL,   it

Introduction

21

appears.     Two   attempts   were   made   at   a   GNU   COBOL   compiler   then   OpenCobol
emerged.  http://www.opencobol.org
There are many stories circulating out there about the history of Mono.  “Practical
Mono” Apress ISBN 1­59059­548­3 gives a short “true as far as it goes” history on page
seven.  Then you find other articles which lend a lot of credence to the rumors out there:
http://www.tikalk.com/net/microsoft­contribute­Mono
While Mono may very well have started as one man's mission in life, or one small
company's mission, it has evolved.   The rumors one hears now is that even Bill Gates
has come to the conclusion Microsoft will soon be nothing but a footnote in computing
history like Wang, Commodore, and Singer, so he is desperately donating cash and code
to the Mono project hoping some portion of his company will still survive him. Yes,
Singer (the sewing machine company) made computers at one point.  
http://www.time.com/time/magazine/article/0,9171,913860,00.html
Novell   (now   owned   by   Attachmate)   has   been   actively   developing   Mono   while
actively developing with it for some time now.  Novell Linux Desktop 9 was based on
Mono development.  That said, there is a lot of up­stream Linux development occurring
with other tools and limiting the growth of Mono.  In order to bridge some of that divide
we are now seeing Mono wrappers and hooks for other packages such as Qt.  Instead of
using   Gtk#   which   only   works   on   Gnome,   you   can   now   specify   Qt   which   runs
everywhere with a native look and feel, so you only need a user to have Core Mono
installed along with Qt.
Prerequisites
You need to have read at least one of the following:
The Minimum You Need to Know About Java and xBaseJ  ISBN­13 9780977086603
The Minimum You Need to Know to Be an OpenVMS Application Developer   ISBN­13
9780982358054

22

Introduction
and preferably 

The Minimum You Need to Know About Qt and Databases ISBN­13 9780982358054
Most  of the programming  presented  in this series  is based  on the concept  that  a
skilled   programmer   knowing   one   of   the   covered   languages   can   quickly   become
functional in another language if we keep implementing the same applications over and
over   again.     You   might   be   tired   of   my   “Mega   Zillionare”   or   “Xpns   Tracking”
applications, but you know when you grab one of these books you are going see one of
those applications and be up to speed in no time.
What no Web?
I'm not going to cover Web here.   I know that most of the trade press is all gaga
about products which can connect databases directly to the Web, but from a business
perspective that is just about the worst idea imaginable.  If, and only if, the database you
wish to expose on the Web contains  only  what you consider 100% public information
then by all means, make a copy and place that copy outside of your firewall so all can
get to it.
Most databases  do not  meet the 100% public information requirement.   I will win
this argument every time, and not just because I'm the one writing the book. You tell me
that you want to expose a MySQL version of the inventory database to the Web for a
catalog ordering system.   You swear on your grandmother's grave that you will only
create   inventory   tables   and   only   copy   inventory   information   including   product
descriptions and quantities.  I submit to you that in 99% of all cases you still don't meet
the requirement.  Do you understand why?
Who maintains this database?  Who actually creates it?  If you are in a Fortune 500
or  above  firm,  it  will  be a DBA.   Most  systems  managers  and  DBAs  use a naming
schema  or  formula  for  creating  passwords.    Oh, it will  meet  all  of  the  requirements
having mixed case letters with numbers and some punctuation characters in it, but at
some point, there will be a three or four digit number which increments by one each time
the password expires.  Each DBA knows what the base password is so they only have to

Introduction

23

try a few times to get in.   The problem is MySQL provides its own user security.   A
successful attack on your exposed database would reveal a password and, possibly, the
generation pattern, putting all of your databases at risk.
Scope of this book
We are going to re­invent the Mega Zillionare application using Mono and Qt.  In
fact, this book is going to focus completely on using Qt with Mono once we get all of the
nasty syntax details covered in Chapter 1.  Unlike other books in this series I'm not going
to connect to multiple databases just to show you the differing syntax.   We have done
that often enough in this series.   Instead, Chapter 3 will take one small piece of our
application, the reports, and generate them over and over again.  Why?  Because most of
you want to read reports which look like this:

24

Introduction

Illustration 1: Report Example 1

25

Introduction

You want fancy headings, multiple fonts, and nice graphical lines segregating the
data.  If your reports will be read by today's MBAs, they can't read anything over half a
page without a picture, preferably one sentence for every picture just like a children's
book.
While most IT professionals and business users who just need the data are more than
willing to accept a report which looks like this:
8/27/2011 3:18:40 PM
Elm
46
51
53
48
52
05
27
39
12
36
17
25

Hits
49
48
47
47
47
45
45
45
45
44
43
43

Most Regular Hits
Since
21
11
5
6
12
2
3
7
4
13
1
11

AveBtwn
8.170
8.370
8.578
8.578
8.578
9.023
9.023
9.023
9.023
9.262
9.512
9.512

MaxBtwn
30
24
30
42
27
45
67
36
40
31
30
27

Page 0001
LongestSeq
2
5
3
2
3
2
2
2
3
2
2
2

Today's MBAs simply cannot function with 1970s state of the art output.
No, I'm not going to throw both the application and writing fancy reports at you in
one chapter.  Existing code to generate fancy­schmancy reports is cumbersome and not
well documented.  Many people purchase commercial third­party libraries or use some
of the Open Source­based Qt report writing tools to pick and point various reports from
databases.  Chapter 2 will give you start of the art 1970s text files that need a fixed width
font (or old fashioned line printer) to line up correctly.
Chapter 3 will cover the fancy­schmancy reports.  Don't worry, this won't be a short
chapter.  Reports is the one area where it seems Qt developers took the spaghetti cooking
approach, they through a big handful of noodles up against the wall and kept all that
stuck.   There is not just one method or one file format supported by the text browser
class.  You can feed it HTML, PDF, Postcript, and even OpenDocument Format.  Qt also
provides some document transformation functionality in that you can create a PDF from

26

Introduction

whatever id displayed in your text browser class.  We will look at all of this in what will
be a very involved Chapter 3.
Finally, this book, like most in the series, will include the chapter it is famous for,
Ruminations.  Need I say more?

Chapter 1 

Fundamentals

1.1 The Confusion You Feel is Deliberate
When OOP (Object Oriented Programming) was just a gleam in the eye of software
researchers they needed to find a way to force it down the throats of assembly hacking
programmers everywhere.  C had come onto the market as a widely accepted language,
mainly because it allowed assembly level hackers to exercise nearly complete control
over a computer while using a high level language.  Most C compilers even supported
the   __asm{}   directive   which   allowed   highly   skilled   assembly   programmers   to   drop
assembly code into the middle of their C program.   (Once optimization was turned on
this was an incredibly bad idea, but, it didn't stop some from trying.)  So, if you wanted
to force OOP down the throats of programmers, the best way to do it was to create an
OOP language named after, and mostly compatible with C.
In truth, the creator of the language didn't create a compiler for it initially.  Instead
he created Cfront which translated C++ source into C source before compiling the C
source.  http://weseetips.com/tag/cfront/  Once C++ moved sufficiently away from C, in
particular with exception handling, there was no reason to continue working on it.  By
that time, actual compilers were out on the market.
Because   of   the   low   level   aspect   of   C,   and   by   extension   C++,   we   had   a   lot   of
portability   and   hardware   issues.     LITTLE_ENDIAN   and   BIG_ENDIAN   issues
constantly reared their heads along with “standard data type sizes” on each machine.
(LITTLE_ENDIAN refers to architectures that address the least significant byte while
BIG_ENDIAN refers to architectures that address the most significant byte.)  Size issues
were introduced by machines themselves.  Most desktop computers at the time of C++
were 16­bit DOS machines.  32­bit desktop computers were being introduced, but most
midrange and mainframe machines were 64­bits or more.  

28

Chapter 1 ­ Fundamentals

Let us not forget the final insult:  ASCII vs. EBCDIC.  Even if we could solve all of
the other low level problems, we still had different character encoding schemas being
used.
There are many different stories about the creation of Java circulating in the world.
Yes, we've already covered the story about the embedded device market, but how did
they come up with the Java syntax?   My personal belief that I will take to the grave
despite all evidence to the contrary is that Sun had a bunch of people working for them
who  couldn't  learn  C++.   In  an  effort  to  get  some  kind  of  benefit  from  hiring  these
people, higher minds at Sun created Java.  It contained a bunch of C++ syntax, a bunch
of wrapper classes to do those things which confused people, and, most importantly, it
left out things like multiple inheritance which really baffled most of Sun's employees.
Of   course   Sun   touted   that   Java   was   truly   a   GOTO­less   programming   language.
Well, they may have nuked the word from the language, but they still implemented its
functionality.
Java backers also touted how the language removed multiple inheritance, a massive
source of confusion and bugs for many C++ developers.  Well, initially it didn't provide
any machinery to do this and people started dropping Java as a development language.
Once that happened, Java suddenly got Interfaces.  A class could only inherit from one
other class, but it could implement multiple interfaces.
When Microsoft had to quickly repackage their Java compiler product, they made
C# straddle  many of the issues between  Java and C++ while retaining  a confusingly
similar syntax.  As with most things, the devil is in the details.

29

Chapter 1 – Fundamentals
1.2 Data Types and Comments
Size or Content

C#/Mono

Java

C++ 

8­bit signed
­128 to 127

sbyte

byte

Usually   char,   size   of   char   determined
by CHAR_BIT in limits.h.  Could be as
small   as   4   bits   or   as   large   as   16.
Smallest   directly   addressable   memory
unit.
SCHAR_MIN   and   SCHAR_MAX
determine value range.
Also stores 8­bit ASCII.

8­bit unsigned
0 to 255

byte

N/A

unsigned char
UCHAR_MAX determines value range
from zero.  Also stores 8­bit ASCII

16­bit signed
­32768 to 32767

short
short
int   on   many   platforms.   Short   int   on
char   16­bit char   16­bit many   other   platforms.     SHRT_MIN
unicode 
unicode
and   SHRT_MAX   determine   short
range while INT_MIN and INT_MAX
determine int range.

16­bit unsigned
0 to 65535

ushort

N/A

Could   be   short   int   or   simply   int.
USHRT_MAX   determines   range   from
zero   for   short   and   UINT_MAX
determines range from zero for int.

32­bit signed
­2147483648
2147483647

int

int

Could   be   long   or   int   depending   upon
architecture.     LONG_MIN   and
LONG_MAX define range for long.

 

to

30
Size or Content
32­bit unsigned
0 to 4294967295

Chapter 1 ­ Fundamentals
C#/Mono

Java

C++ 

uint

N/A

Could be unsigned long or unsigned int
depending   upon   platform.
ULONG_MAX determines range from
zero.

64­bit signed
long
­9,223,372,036,854,
775,808
 
to
9,223,372,036,854,7
75,807

long

long long, int, or quadword depending
upon architecture.  Quadword might be
a struct containing 2 longs or a macro
translating to “long long”.

64­bit unsigned

ulong

N/A

Unsigned   long   long,   unsigned   int,   or
unsigned   quadword   depending   upon
platform.

float

32­bit
32­bit
signed
IEEE­754
floating
point value

Not   required   by   standard   to   use   any
IEEE   representation.     Controlled   by
compiler switches in many cases.

double

64­bit
64­bit
signed
IEEE­754
floating
point value

Not   required   by   standard   to   use   any
IEEE   representation.     Controlled   by
compiler switches in most cases.

boolean

bool
boolean
bool
8­bit   true Undefined 1 byte as determined by the char data
or false
size
type.  Can hold either true or false.

31

Chapter 1 – Fundamentals
Size or Content
long double

C#/Mono

Java

128­bit
N/A
scaled
integer
data   type
1.0x10^­28
to
7.9x10^28
provides
28­29
significant
digits

C++ 
Twice the size of standard double, not
required to use IEEE representation.  

Mono
provides   a
slightly
different
definition 
Packed Decimal

Supported Supported Could   be   native   type   depending   upon
by   classes by   classes compiler.
if at all
if at all.

Most junior developers will argue with every answer I put in the C++ column of this
spreadsheet.   They have only worked on a WinTel PC platform, despite its operating
system,   so   have   never   encountered   the   size   issues.     Dig   back   on­line   through   your
history and you will read about the death march Microsoft put its programmers through
migrating from Windows 3.1 under 16­bit DOS to a 32­bit version of that application
(which they now call an operating system.)

32

Chapter 1 ­ Fundamentals

Packed Decimal and C# Decimal are night and day different.  In the early days of
computing  IBM created  a nibble  based character­numeric  data type  and added  direct
CPU support for it.   This data type provided for fixed decimal math without rounding
errors.   It saved an immense amount disk space back when disk storage was costing
about  $10,000/MEG.    You can  find  a pretty  decent  write  up  on this  data  type  here:
http://www.simotime.com/datapk01.htm   The data type was widely used with COBOL
and DIBOL programming languages.  It is still used today in many banking systems so
you may have cause to understand it in your future.
Packed Decimal had some issues with the value used in the last nibble for the sign
value.  Originally hex C was used for positive and D for negative to mimic Credit and
Debit.  Some platforms used hex A or hex E for positive and hex B for negative.  The
hex F value was used to indicate unsigned by many platforms.  Each digit of the value
was stored in a 4­bit nibble with the last 4­bit nibble being reserved for the sign.
+1,234.56 would be stored as 01 23 45 6C because there are two nibbles in each byte
and you had to use a full byte for storage.   Notice that this format does not store any
information about the decimal point.  This data type made COBOL copylibs a mandatory
part   of   development   until   Common   Data   Dictionaries   came   onto   the   scene   allowing
multiple   languages   to   share   the   same   variable   names   with   the   same   definitions.     A
decimal point was always “assumed” with this data type and its position controlled by
the picture clause.   While this data type doesn't work well with OOP languages unless
classes   are   specifically   created   to   deal   with   it,   on   hardware   which   provides   native
support it is both the fastest and most accurate numeric data type to use.   With a PIC
9(7)V99   clause   you   will  always  get   two   decimal   digits   and   truncated   intermediate
results.     With   a   PIC   9(7)V99   WITH   ROUNDING   clause   you   will  always  get   two
decimal digits but all intermediate results will be rounded based upon the third decimal
digit.

33

Chapter 1 – Fundamentals

Decimal, as implemented by C# and Mono is a dynamically scaled integer data type
for   use   with   floating   point   values.     Unlike   IEEE   floating   point   values,   it   preserves
precision.  If you add two numbers which each have two decimal places your result will
have two decimal places even if the result is an even integer value.   Version 1 of the
Mono specification actually mapped out how all 128­bits  of this data type were to be
used.  The specification has since been changed to “unspecified” storage to allow for use
of alternate IEC specifications.  The only way to reliably exchange this data type with
another system is to export it to a string and convert the string on the receiving side.
Let's take a look at Constants:
C#/Mono
Must   be   declared   inside   of   a
class as:
const type name = value;
can   be   preceded   by   access
qualifier like public

Java

Must   be   declared   inside const type name = value; 
of a class as:
declared anywhere.
final type name = value;
can be preceded by access
qualifier like public

helloworld.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

C++

using System;
namespace HelloWorld
{
class Hello
{
const int my_constant = 32;
static void Main(string[] args)
{
Console.Out.WriteLine("Hello World!");
Console.Out.WriteLine( my_constant);
}
}
}

roland@linux-c345:~/mega_Mono> mcs helloworld.cs
roland@linux-c345:~/mega_Mono> Mono helloworld.exe
Hello World!
32

34

Chapter 1 ­ Fundamentals

HelloWorld.java
1 public class HelloWorld
2 {
3
public final int my_constant = 32;
4
5
public static void main(String[] args)
6
{
7
System.out.println( "Hello World!");
8
System.out.println( my_constant);
9
}
10 }
roland@linux-c345:~/mega_Mono> javac HelloWorld.java
HelloWorld.java:8: non-static variable my_constant cannot be referenced from a
static context
System.out.println( my_constant);
^
1 error

As the compilation attempt above shows, Java has a protection crisis when it comes
to constants.   Why constants cannot be placed in a managed area of the VM which is
addressable by static methods is beyond me.  To make the above work we have to insert
“static” into the constant definition.   In the world of Java, static implies that only one
instance of this item will exist and that it will exist even if there are zero instances of the
class containing it. To me that is a lot of needless burden on the computer and one of the
reasons Java applications seem to be resource hogs.
hello.cxx
1
2
3
4
5
6
7
8
9
10

#include <iostream>
using namespace std;
const int my_constant = 32;
int main( int argc, char **argv)
{
cout << "value of my_constant " << my_constant << endl;
}

roland@linux-c345:~/mega_Mono> g++ -I/usr/include/c++/4.5 hello.cxx -o hello
roland@linux-c345:~/mega_Mono> ./hello
value of my_constant 32

Chapter 1 – Fundamentals

35

Because C# started out as rebadged Java, you notice it has the same restriction for a
constant value declaration even if it uses different syntax.  C++ on the other hand, lets
const be used all over the place, including and especially in header files.  This freedom
with constants has caused quite a bit of complexity to be added to both compilers and
linkers.  You see, this freedom allowed two different problems to surface:
1. Same constant name having different values in different compilation units.
2. Same constant name with same constant value existing multiple times across and
within a compilation unit.
The “solution” provided by compiler and linker developers was something called
“constant folding.”  Some were very good and some were trash.  Some would only allow
a constant to be “folded” (have all definitions merged into one) if both the name and the
value were the same.   Others folded to the very first definition encountered no matter
what.  The “First One in Wins” solution provided some interesting debugging whenever
our constants fell into situation one.
Many developers, myself included  over the years, will refer to defined values as
constants or “compiler constants.”  Java does not have a preprocessor, so it doesn't have
this   situation.     Both   C++   and   C#/Mono   utilize   a   preprocessor   which   allows   for
statements such as the following to be scattered about the code:
#define yellow

12

While it is true that 12 is constant, it is a textual constant.  The preprocessor scans
through   the   source   code   replacing   all   textual   instances   of   yellow   with   “12”   before
feeding   the   result   into   the   compiler.     You   have   to   be   very   careful   with   #define
statements.     Normally   the   preprocessor   will   only   substitute   when   it   finds   a   perfect
match, but perfect is in the eye of the beholder.  The rule in C/C++ is to make all #define
names uppercase.  This helps stop collisions like the following:
enum my_colors = {red, blue, green, yellow, black, brown, white};

36

Chapter 1 ­ Fundamentals

After passing through the preprocessor with the above definition it would look like
this:
enum my_colors = {red, blue, green, 12, black, brown, white};

You   might   have   guessed   that   the   compiler   isn't   too   fond   of   that.     How   about
pointers?
C#/Mono

Java

C++

Most   value   types   and
structures   can   be   pointers,
but declaration does not put
syntax   on   variable   name,
rather on type name.
The   following   declares   3
integer pointers
int*  x1, x2, x3;

Only   allowed   in   JNI   code,
the Java  language  does not
support pointers, but if they
can be converted to a native
integer   type   it   can   “store
their   value   between   JNI
calls.”

Most   value   types   and
structures   can   be   pointers.
Syntax   is   on   variable   at
time   of   declaration.     The
following   declares   2
integers and 3 pointers:
int x1, x2, *x3, *x4, *x5;

Most books covering C#/Mono won't even cover pointers.  If you thought pointers
were difficult in C or impossible under C++ after classes were introduced, you ain't seen
nothin' yet!  Sorry, couldn't resist the song quote.  It really does fit.  Besides the unusual
declaration   syntax,   you   have   to   remember   that   C#/Mono   runs   in   a   p­compiled   state
under   a   VM.     Your   data   moves   around.     Unlike   C++   where   the   programmer   had
complete   control   over   where   variables   were   allocated,   C#/Mono   offers   only   fleeting
control and classifies all use of pointers as “unsafe.”
char* str = stackalloc char[1024];
MyClass m1 = new MyClass();
…. some code to set values here...
fixed ( int* p = &m1.count)
{
more code here
}

Chapter 1 – Fundamentals

37

Above  I show  you  the  two methods  of  “pinning”   a memory  allocation  to actual
physical memory so a pointer can be taken.  The first example actually allocates memory
on the stack, so it isn't pinned  per­se.   The lifetime of the memory  is limited  to the
lifetime   of   the   method   in   which   it   is   defined.    There   is   no   way   to   delete   or   free
stackalloc memory.
Fixed temporarily “pins” managed memory to a single location for the execution of
a “statement”.   As we all know a “statement” can be a single statement or a bunch of
statements enclosed by {}.  
I could explain this a bit further, but, I'm going to direct you to purchase a copy of
The   Minimum   You   Need   to   Know   About   Java   on   OpenVMS       Volume   1    ISBN
0­9770866­1­5.     You   can   find   more   information   including   places   to   purchase   here:
http://www.theminimumyouneedtoknow.com/java_book.html  
No, I'm not trying to force the sale of another Java book down your throat when you
want to learn about Mono, I'm trying to keep this book focused.  That book is almost all
JNI code and it deals with all of the ugly details about moving, pinning, and transferring
memory between Java code and C/C++ code.  Once you understand that, you can delve
into Microsoft's new CLI strategy (Common Language Interface.)
If   you   come   from   a   DOS/PC   hacker   only   background,   CLI   is   a   big   chunk   of
information   for   you   to   chew.     If   you   come   from   a   real   computing   platform   like
OpenVMS,   then   you   wonder   why   passing   by   descriptor   was   only   half­assedly
implemented.  Microsoft's actual big thinkers have even acknowledged the platform they
are now trying to emulate after decades of dissing:
http://visualstudiomagazine.com/articles/2008/02/01/the­end­of­the­language­wars.a
spx
http://www.openvms.org/stories.php?story=08/02/17/5922249

38

Chapter 1 ­ Fundamentals
Note: Unlike C, you cannot mix pointer  and entity declarations  on the same

declaration line.  Under C#/Mono, when you declare int* x1, x2, x3, all three of these
variables are pointers.  Under C/C++ when you declare int x1, x2, *x3, *x4, *x5, only
x3­5 are pointers.  Conversely, if you screw up and use the Mono syntax in C++, only
the first variable will be a point.
hello.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

//

The most familiar test program in the world.

#include <stdio.h>
int main()
{
int* x1, x2, x3;
printf( "Hello Word!!\n");
x1
x2
x3
x2

= &x2;
= 6;
= 4;
+= x3;

printf( "%d

%d

%d\n", *x1, x2, x3);

return 0;
}

roland@linux-c345:~> gcc -o hello hello.c
roland@linux-c345:~> ./hello
Hello Word!!
10 10 4
roland@linux-c345:~>

Chapter 1 – Fundamentals

39

Many   of   you   are   probably   unfamiliar   with   what   is   really   meant   by   “stack”
allocation, especially if you are recent graduates.  Back in the DOS days, and even on
most   midrange   computers   of   the   day,   we   had   various  ­stacksize=nnnn  switches   we
could use on either the compiler or the linker.   These magical incantations created a
“stack” in memory on non­stack based computers.  Let's not go too deep down the bunny
hole  defining  stack­based  and non­stack­based.   Suffice  it to say there  weren't  many
virtual   memory   operating   systems   which   allowed   for   dynamic   process   memory
allocation.  The big boxes where mostly fixed­size batch region machines.  They had a
fixed number of fixed­sized “regions” where your application could run.   They would
swap out entire regions at a time as part of their process change over.  The concept of a
program being able to use only what it needed didn't exist.
All Assembler languages for all machines of the day made use of a program call
stack.  Every time a method/function was called, a return address, return value area, and
various parameters were  pushed  onto the stack.  The first thing the called method did
was popped off its parameters and identified where it would write its result.  Yes, there
were different rules about what got pushed in what order on different platforms and even
which direction a push went, but, for this discussion, we don't care.
Some platforms required that all declared/automatic variables be allocated on the
stack   immediately   upon   method/function   entry.     Other   platforms   required   that   you
allocated all variables from available memory known as the heap.  To some people, the
ones allocating variables on the stack became known as “stack based.”   Regardless of
how variables were allocated, it was the responsibility of the called function/method to
clean up the stack upon return.
Yes, I know Assembler isn't taught in today's colleges.  It's a pity because everybody
needs   to   understand   stacks   when   they   start   to   toy   with   CLI   (Common   Language
Interface) or JNI (Java Native Interface.)  Most of today's authors don't even cover these
topics because they've never had to write an Assembler program in their life.

40

Chapter 1 ­ Fundamentals

If your program either pushed past the end or popped past the beginning of your
allocated stack area, most operating systems would kill it and issue an ABEND report
known as a STACK DUMP.  If you knew Assembler, you could identify exactly what
caused your problem in a matter of minutes by looking at the CALL STACK and data
left on the stack.
We are taking time speaking of this because “stack” is generally fixed at program
startup.  OpenVMS and most Linux distributions have stack size values set at either the
system or the user level.  On Linux a program can make a call to setrlimit() to change
the current stack size of this program instance (assuming the user running the application
has sufficient privilege.)   Under DOS, that GUI version of DOS called Windows, and
even OS/2 if I remember correctly, each program set its own stacksize at launch.
You need to understand that stack is a very precious resource.  You may have 8Gig
of  RAM  in  your   Linux   or   Windows   box,   but   it   will  not   be   uncommon  to  see  your
executable limited to either 16K or 32K of stack.  On many platforms stack is allocated
in a psect which occurs prior to the beginning or directly after the end of where your
program loaded into memory.
Having said all of that, stack is both similar and different when spoken of in terms of
the   C#   or   Java   virtual   machines.     It's   still   a   very   precious   commodity   not   to   be
squandered carelessly.

41

Chapter 1 – Fundamentals
Arithmetic

C#/Mono

Java

C++

Basic Assignment

=

=

=

Addition

+

+

+

Subtraction

­

­

­

Unary Plus

+a

+a

+a

Unary Minus

­a

­a

­a

Multiplication

*

*

*

Division

/

/

/

Modulo

%

%

%

Pre­increment

++a

++a

++a

Post­increment

a++

a++

a++

Pre­decrement

­­a

­­a

­­a

Post­decrement

a­­

a­­

a­­

Math.Pow()

Math.Pow()

pow()

C#/Mono

Java

C++

NOT

!

!

!

AND

&&

&&

&&

OR

||

||

||

Exclusive OR

^

^

^

Inclusive OR

|

|

|

Operator

Power

Logical Operators

42
Bitwise Operators

Chapter 1 ­ Fundamentals
C#/Mono

Java

C++

NOT

~

~

~

AND

&

&

&

OR

|

|

|

XOR

^

^

^

Left SHIFT

<<

<<

<<

Right SHIFT

>>

>>

>>

Unsigned Right Shift

>>>

>>>

Please note that C++ does not have an Unsigned Right Shift Operator.  Many articles
and books you read will classify unsigned right shift as a “logical” operator because it
forces unsigned treatment of signed values.   C/C++ programmers achieve an unsigned
right shift by casting the signed variable to unsigned prior to performing the shift.
I really hated including Exclusive/Inclusive OR on the Logical table, then showing
you the same two operators in the bitwise table, but, it's all part of the language and I'm
certain you will find some poorly documented code which makes heavy use of them.
Let me show you some code and explain why  some  developers will choose to use
these things as logic operators.

Chapter 1 – Fundamentals
bitwizelogic.cs
1 using System;
2
3 namespace bitwizelogic
4 {
5
class BitwizeLogic
6
{
7
static void Main(string[] args)
8
{
9
int w, y, z;
10
bool x;
11
12
y = 20;
13
z = 30;
14
w = y | z; // bitwize inclusive or
15
Console.Out.WriteLine("Result of 20 | 30 = {0:n}", w);
16
17
y = 20;
18
z = 30;
19
w = y ^ z; // bitwize exclusive or
20
Console.Out.WriteLine("Result of 20 ^ 30 = {0:n}", w);
21
22
int
k, j, m, n;
23
24
k = 27;
25
j = 15;
26
m = 7;
27
n = 3;
28
29
Console.Out.Write( "\nBefore k {0:n} ", k);
30
Console.Out.WriteLine( " j {0:n}", j);
31
x = (k++ == 100) && (j++ == 100);
32
Console.Out.Write("First && test {0:g}", x);
33
Console.Out.Write(" k {0:n} ",k);
34
Console.Out.WriteLine(" j {0:n}", j);
35
36
Console.Out.Write( "\nBefore k {0:n} ", k);
37
Console.Out.WriteLine( " j {0:n}", j);
38
x = (k++ == 28) && (j++ == 16);
39
Console.Out.Write("Second && test {0:g}", x);
40
Console.Out.Write(" k {0:n} ",k);
41
Console.Out.WriteLine(" j {0:n}", j);
42
43
Console.Out.Write( "\nBefore m {0:n} ", m);
44
Console.Out.WriteLine( " n {0:n}", n);
45
x = (m++ == 7) || (n++ == 3);
46
Console.Out.WriteLine("First || test {0:g}", x);
47
48
Console.Out.Write( "\nBefore m {0:n} ", m);
49
Console.Out.WriteLine( " n {0:n}", n);
50
x = (m++ == 7) || (n++ == 4);

43

44
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 }

Chapter 1 ­ Fundamentals
Console.Out.WriteLine("Second || test {0:g}", x);
Console.Out.Write( "\nBefore m {0:n} ", m);
Console.Out.WriteLine( " n {0:n}", n);
x = (m++ == 9) | (n++ == 4);
Console.Out.WriteLine("First | test {0:g}", x);
Console.Out.Write( "\nBefore m {0:n} ", m);
Console.Out.WriteLine( " n {0:n}", n);
x = (m++ == 7) | (n++ == 4);
Console.Out.WriteLine("Second | test {0:g}", x);
Console.Out.Write( "\nBefore m {0:n} ", m);
Console.Out.WriteLine( " n {0:n}", n);
x = (m++ == 12) ^ (n++ == 4);
Console.Out.WriteLine("First ^ test {0:g}", x);
Console.Out.Write( "\nBefore m {0:n} ", m);
Console.Out.WriteLine( " n {0:n}", n);
x = (m++ == 7) ^ (n++ == 4);
Console.Out.WriteLine("Second ^ test {0:g}", x);
Console.Out.WriteLine( "after: ");
Console.Out.Write(" m {0:n} ", m);
Console.Out.WriteLine(" n {0:n}", n);
}
}

Please pay very special attention to the output created by listing lines 50 and 51.
This is one area where wanna­be Uber Geeks shoot themselves in the groin.  Ordinarily I
would say foot, but, this type of bug tends to turn up in medical devices and high speed
trading   engines   where   wanna­bes   are   trying   to   shave   a   few   clock   cycles   and   code
themselves some job security.  Performing mathematical calculations inside of boolean
expressions is quite simply an unforgivable coding foul.  You should be fired instantly.
 

45

Chapter 1 – Fundamentals
roland@linux-c345:~/mega_Mono> mcs bitwizelogic.cs
roland@linux-c345:~/mega_Mono> Mono bitwizelogic.exe
Result of 20 | 30 = 30.00
Result of 20 ^ 30 = 10.00
Before k 27.00 j 15.00
First && test False k 28.00
Before k 28.00 j 15.00
Second && test False k

29.00

j 15.00
j 16.00

Before m 7.00 n 3.00
First || test True
Before m 8.00 n 3.00
Second || test False
Before m 9.00 n 4.00
First | test True
Before m 10.00 n 5.00
Second | test False
Before m 11.00 n 6.00
First ^ test False
Before m 12.00 n 7.00
Second ^ test False
after:
m 13.00 n 8.00
roland@linux-c345:~/mega_Mono>

Take a good look at the highlighted lines above where “n” did not change value.
The C standard chose to optimize boolean expressions by only requiring the compiler to
execute enough code to prove the boolean true.   In the case of a logical OR condition
only  one side  needs  be executed.    While  we as humans  may  want  to believe  it will
always   be   the   first   test   provided,   compiler   optimization   could   eliminate   the   tests
altogether if one expression contains only constants.
See the second highlighted “True” above?  The bitwise operators force evaluation of
all tests not optimized away.  This is why you will see many geeks using them instead of
the logical operators.  It is extremely poor coding style to do it, but, some people's kids
never learn.

46

Chapter 1 ­ Fundamentals
Relational

C#/Mono

Java

C++

Equal to

==

==

==

Not Equal to

!=

!=

!=

Greater than

>

>

>

Less than

<

<

<

Greater than or 
Equal to

>=

>=

>=

Less than or Equal 
to

<=

<=

<=

Operators

Member and Pointer Operators

C#/Mono

Java

C++

Array Subscript

[]

[]

[]

Indirection  (value at)

*n

*n

Address of (see note below)

&n

&n

Member of object pointed to by n

n­>t

n­>t

Member of object
Value at member pointed to by n
Value at member of object

n.t

n.t

n.t

n­>*t

n­>*t

n.*t

n.*t

Java eliminated pointers from the language.  Arrays and enums in Java are actually
classes so none of the usual tricks with [] are allowed.  We will cover more on arrays
and emums later in this chapter.

Chapter 1 – Fundamentals

47

C# (and by extension Mono) really buggered things when it comes to pointers and
references.  You will always feel massively confused if you are mixing and matching C#
and C++.  We touched on this earlier, but I need to really beat it into your skull now.
Take the following declaration:
int* a1, b1, c1;

In C#, the above declaration declares three pointers.   In C++ this line declares a
pointer  and   two   integer   variables,  if  your   particular   compiler  allows  the  int*   syntax
which most do these days.
int x;
int& y = x;

In   C++,   the   above   two   lines   declare   an   integer   variable   and   a   reference   to   that
integer variable.  Notice how the syntax looks eerily close to pointer declarations in C#?
Well, it gets worse.  C# does not allow you to physically declare a reference.    The C#
language enforces the rules that all “native” values are type variables passed by value
and   all   object   variables   are   references   which   need   an   instance   created   for   them   to
refererence.   Knowing this rule does not make the life of your C++ programmer any
easier  when   coding  in  C#.     It  also   doesn't   help  when   you   must   hop   back  and  forth
between languages which share a massive amount of syntax.
Now let us discuss the abyss known as comments.

48

Chapter 1 ­ Fundamentals
C#/Mono

Java

C++

// single line comment

// singe line comment

// single line comment

/* multi­
 * line
 * comment 
 */

/* multi­
 * line
 * comment 
 */

/* multi­
 * line
 * comment 
 */

/** XML comments
  on multiple lines
 */

/** JavaDoc comments
 on multiple lines
*/

///   XML   comments   on   a
single line.

Of   course   there   have   been   many   third­party   and   layered   attempts   to   introduce
various comment tagging methods to C/C++ and Java over the years.  One which seems
to spring forth from the Apple camp is HeaderBrowser.  You can find more information
about it here: http://www.headerbrowser.org/ The Open Source effort with support of the
entire   Qt   community   behind   it   is   a   product   called   Doxygen   which   handles   multiple
languages, including both C++ and C#/Mono.  You can learn more about this effort here:
http://www.stack.nl/~dimitri/doxygen/index.html 
In any case, if you wish to generate useable documentation from your source code,
you will spend hours  inserting  tags  into  comments  and adding  comments  where  you
never   once   thought   about   adding   them.     Just   click   here   to   see   the   test   class   with
comments:  http://www.stack.nl/~dimitri/doxygen/docblocks.html  and   be   sure   to   click
the link they provide to view the HTML generated documentation.  This is exactly the
kind of class documentation one wants to see automatically generated from source code
… but … most of you won't enter that many comments for a single class even if they put
a gun to your head.  What programmers consider “sufficient doc” has to telegraph ahead
to find what the world considers “inadequate doc.”

Chapter 1 – Fundamentals

49

One of my favorite documentation stories actually came from an account rep for a
consulting   firm   specializing   in   providing   documentation   consultants.     Upper
management called the consulting firm into a meeting with the lead developer to discuss
awarding a documentation project.  The lead developer was all pissed off claiming that
the meeting was a waste of his coding time and “all you have to do is look at the code to
figure out what it does.”  The response was priceless:  “Yes, I can look at a spark plug
and tell you that it is used for combustion, but, without documentation, I cannot tell you
if this particular spark plug is used in a Briggs & Stratton lawn mower engine or a Ford
V8.”

JUnit was God's gift to programmers. 

JUnit will bring about the end of mankind.

Both of those statements are true.  JUnit allows a $400+/hr consultant who actually
understands   the   business   entity   the   system   is   being   developed   for  and  completely
understands   the   business   requirements   to   generate   a   flawless   system   with   less   than
one­third of the time devoted to testing.   JUnit allows the typical $10/day illegal alien
consultant to turn in a system which passes 100% of all unit and automated regression
testing yet doesn't work at all.  We will discuss more about testing later in this book.  I
bring it up now so you have a frame of reference to discuss automated documenation.
Hopefully you all went to the doxygen site and saw the amount of comments which have
to be added to  each and every  class to generate the kind of documentation everyone
expects.  
JUnit, JavaDoc, and Doxygen are all basically  the same.   A $400+/hr  consultant
creates miraculous things of beauty with them; the class of developer pursued by today's
MBAs produce nothing but train wrecks.

50

Chapter 1 ­ Fundamentals

It   is   my   professional   opinion   that   all   languages   will   move   to   the   Doxygen
commenting standard (with the possible exception of diehard JavaDoc shops.) The tool
is highly portable and already supports a wide array of languages.  Everybody and their
brother   wants   to   have   really   nice   HTML   documentation   ready   for   on­line   posting
complete   with   hyperlinks,   menus,   and   a   table   of   contents.     At   first   they   will   try   to
demand this level of documentation for free from their programmers.  Then, after they
see   what   gets   generated   from   their   programmer's   comments,   they   will   have   to   hire
$200/hr technical writers to go in and add Doxygen comments to the code.
By   now   you   should   be   understanding   that   Microsoft   well   and   truly   gave   the
programming   world   the   short   stiff   one   when   they   re­badged   their
Java­compiler­tightly­coupled­to­Windows as C#.  We are now at a point where I have
to split the rest of this confusing discussion out into its own sections.   It is  definitely
okay to take a breather before reading on.   What we are about to discuss next is quite
nasty.

1.3 Structure and Class Confusion
The original idea behind a “structure” was that it would provide a logical grouping
of data.  You see “struct” was the new hoity­toity word for RECORD.  BASIC provided
us with a RECORD which, ironically, was used to declare a structure we would read and
write to files.  COBOL provided us the “01” level underneath the FD (File Descriptor) to
contain  the  various  record  definitions  which  could  be  written  to  an  indexed  file.    C
desperately needed a word which could provide this logical grouping, but, there was a
problem.  C was a cheap language used to write an incredibly cheap operating system.
That OS took massive  shortcuts and adopted significant design flaws  because  it was
never supposed to see the light of day in the business world.

Chapter 1 – Fundamentals

51

Unix   was   supposed   to   be   a   single   purpose   platform   which   would   allow   task
switching and remote access by technicians, but, its original design purpose was to only
operate telephone switching stations.   Such a single purpose coupled with the promise
this would never be released commercially or require any support what­so­ever outside
of the company allowed horrific shortcuts to be taken with the OS design.  To start with,
it really doesn't have processes, it has threads, but, we discussed that in another book of
this series.  More importantly, the entire OS kernel was written without embedding the
concept of a record as the primary logical IO unit.  Yes, it supported blocks for physical
IO, but there was no logical IO concept.   The only built­in file storage concept was a
stream.   To this day  this issue  still  causes  massive  multiuser  headaches  and  disaster
recovery problems.  If someone hadn't finally written a relational database for first Unix,
then Linux, neither operating system would be the least bit usable in the business world.
The first wart to appear in the C language due to this massive design flaw was the
“struct” keyword.  The powers that be did not want to point out such a massive design
flaw at a time when 90% of all critical business data was still stored in either indexed
files or on magnetic tape, in record format.  Had they introduced the RECORD keyword
the first thing the IT community would have said is “Great, how do I declare keys and
connect this to a file for permanent storage?”
Colleges, who by now had copies of the operating system which wasn't supposed to
see  the  light  of  day  and  the  compiler  for  the  language  developed  to  only  write  that
operating system, started teaching “Data Structures” courses.  Students were required to
ooh and aah at how you could create linked lists and doubly linked lists by embedding
next and previous pointers inside of a data structure which was naturally implemented
via the struct keyword.  IT professionals once again said “Great, how do I declare keys
and connect this to a file for permanent storage?”
Let me veer off a moment to explain what I meant when I said C was a “cheap”
language.  Those who know me know I have worked for decades using C, but it was and
still is a cheap language.

52

Chapter 1 ­ Fundamentals

C was designed to be “one level above assembly language” when it was originally
implemented.    The core  language  itself  provides  almost  no functionality.    What  you
believe to be the “core” language is a set of extension libraries and header files which
have been added to the language and became part of the ANSI C standard at some point.
The world's most famous C program, hello.c, doesn't even work without the extensions.
hello.c
1
2
3
4
5
6
7
8
9
10

//

The most familiar test program in the world.

#include <stdio.h>
int main()
{
printf( "Hello Word!!\n");
return 0;
}

roland@linux-c345:~> gcc -o hello hello.c
roland@linux-c345:~> ./hello
Hello Word!!
roland@linux-c345:~>

In case you don't know this little bit of Linux lore, if you don't specify an output
name  when  calling  gcc,  your   executable  file,   if  created,  will  be   named  a.out.    This
naming  exists for “historical reasons” which fewer  and fewer  people remember each
year.  This is yet another example of how Unix and Linux were designed to be cheap,
rather than business class, platforms.
COBOL and BASIC are, by contrast, expensive languages.  Both of these languages
not only provide for computational complexity, but come bundled with the majority of
I/O originally needed for their day.
HELLO.BAS
1
2

10 PRINT “Hello World!”
32767 END

Depending upon the compiler you use, the END statement may be optional.

Chapter 1 – Fundamentals

53

HELLO.COB
1
2
3
4
5

IDENTIFICATION DIVISION.
PROGRAM-ID. hello.
PROCEDURE DIVISION.
DISPLAY "Hello World!".
STOP RUN.

Yes, COBOL maintains its position as the word's most wordy computer language,
even with this example, and only gets worse with future examples, but, you should begin
to see, one doesn't need to bring outside libraries in for core functionality.  If you have
not read The Minimum You Need to Know to Be an OpenVMS Application Developer at
this point, I suggested you find a copy and at least read up on the accessing of indexed
files.
C   was  crippled   right  out   of   the   gate.    Because  it  was   originally  conceived   as   a
“portable assembly language” which would be used to port a proprietary OS used to run
communications switches, it wasn't given the concept of a record.  Sadly, Microsoft and
other flavors of DOS also didn't have the concept of a record built­into the OS either.
This   meant   that   C,   which   didn't   require   support   for   indexed   file   systems   like   other
languages, ported easily to the platform.  Once people got bored with writing “hello” to
the   monitor,   very   expensive   indexed   file   and   “database”   libraries   surfaced.     Many
flavors of Xbase showed up and were mostly incompatible with each other, though they
had overlapping capabilities.  (You need to read The Minimum You Need to Know About
Java and xBaseJ to get more information on Xbase file formats and history.)
When the various standards committees met, Microsoft and the various Unix/Linux
vendors howled mercilessly at the mere suggestion the ANSI C standard require support
for indexed files like the Holy Trinity of COBOL­FORTRAN­BASIC.   Vendors who
were busy back stabbing, thieving from, and suing each other took time out from their
busy days of mayhem to provide a unified front against such support in the language
standard.  This unified front continued on into the ANSI C++ standard.  Since Java was
basically written to allow programmers who couldn't comprehend C++ to program, it
continued the tradition.  Needless to say, when the fresh coat of paint was applied to Java

54

Chapter 1 ­ Fundamentals

and Microsoft re­branded it C# that fresh coat of paint didn't include support for indexed
file systems which Microsoft's pathetic excuses for operating systems couldn't natively
provide.
Most end user and small business data storage needs can easily be met by a native
indexed file system.  Many of you have the opinion that an SQL interface means you are
using a relational database, and you would be wrong.   While things like MySQL and
SQLite   provide   SQL   interfaces   to   C/C++,   Java,   and   C#/Mono,   they   don't   normally
provide a relational database.   On most platforms MySQL defaults to its own indexed
file system.  SQLite has become a master at obfuscating just how it stores things:
S
QLi
t
ei
sa
ne
mb
e
d
d
e
dS
QLd
a
t
a
b
a
s
ee
ng
i
ne
.
Unl
i
k
emo
s
to
t
he
rS
QLd
a
t
a
b
a
s
e
s
,
S
QLi
t
e
d
o
e
sno
tha
v
eas
e
p
a
r
a
t
es
e
r
v
e
rp
r
o
c
e
s
s
.S
QLi
t
er
e
a
d
sa
ndwr
i
t
e
sd
i
r
e
c
t
l
yt
oo
r
d
i
na
r
yd
i
s
k
f
i
l
e
s
.A c
o
mp
l
e
t
eS
QL d
a
t
a
b
a
s
ewi
t
h mul
t
i
p
l
et
a
b
l
e
s
,i
nd
i
c
e
s
,t
r
i
g
g
e
r
s
,a
nd v
i
e
ws
,i
s
c
o
nt
a
i
ne
di
nas
i
ng
l
ed
i
s
kf
i
l
e
.Thed
a
t
a
b
a
s
ef
i
l
ef
o
r
ma
ti
sc
r
o
s
s
p
l
a
t
f
o
r
m -yo
uc
a
nf
r
e
e
l
y
c
o
p
yad
a
t
a
b
a
s
eb
e
t
we
e
n3
2
b
i
ta
nd6
4
b
i
ts
y
s
t
e
mso
rb
e
t
we
e
nb
i
g
e
nd
i
a
na
ndl
i
t
t
l
e
e
nd
i
a
n
a
r
c
hi
t
e
c
t
ur
e
s
.
You can find the above quote at:  http://sqlite.org/about.html.   I can tell you that I
haven't ever found a relational database or an indexed file system which would let you
copy   a   single   file   data   set   between   32­bit   and   64­bit   systems,   let   alone   between
big­endian   and   little­endian.     I   will   hazard   a   guess   that   there   is   some   text­only
XML­based storage going on inside of those files, but I haven't looked to be certain.  In
any event, it is not a binary relational database you are using.  As I said, most end user
through  small  business  data  storage  needs  can  easily  be  met  by  today's  indexed  file
capabilities.  For more on this topic you need to read The Minimum You Need to Know
About Qt and Databases.
Before the simple struct morphed out of just being a record definition, it gave us no
end of ulcers, at least in the C/C++ world.  Those ulcers were all due to problems caused
by memory  alignment  chosen by each compiler.    This  created  all kinds of problems
when trying to store data on disk for another program to read.   Even if the programs
were running on the same computer, but using different memory models.

Chapter 1 – Fundamentals

55

During   the   days   of   DOS/Windows,   C   compilers   could   compile   code   using   the
Compact, Small, Medium, and Large memory models.  (Compact was an oddity used for
creating  .COM binaries.)    This  architecture  also used a SEGMENT:OFFSET  type of
memory   addressing   rather   than   the   linear   memory   addressing   used   by   some   other
platforms.  The size of data types, in particular pointers, changed when compiling with
different memory models.  The default alignment also changed.
struct {
char
c1;
long
emp_id;
char
first_name[35];
char
last_name[45];
short int
age;
} emp_age, *emp_age_ptr;

The novice programmer would expect each of these items to be placed back to back
in   memory   without   any   intervening   gaps.     If   you   were   working   with   the   Compact
memory model, the compiler would even reinforce this belief because the default for
most compilers was pack(1) or align(1) with that memory model.  The one signified byte
alignment.     From   a   performance   standpoint,   this   was   inefficient.     Most   desktop
computers of the day worked well with longword (or long or 4 byte) alignment, but only
certain memory models allowed that to happen.  The default structure alignment changed
with each memory model.  Unless you added #pragma statements around your structure
definitions to control their creation, you got whatever the default was at the time the
compiler got to your structure definition.
As long as you were working with this only in memory and not doing pointer math,
the size and alignment of the structure did not matter.  When you did pointer math you
had to use the C compiler operator sizeof() to get the correct size of the structure before
moving your pointer.  The wheels came off the cart when you wrote this information to
disk and another program, compiled with different alignment, tried to read it.  The size
of the structure it wanted to use would be different and very bad things would happen.

56

Chapter 1 ­ Fundamentals

When C++ came along and the Cfront program translated C++ source into C adding
functions for methods and pointers for  this, things got really ugly in the world of the
struct.  Eventually, the C++ language moved far enough beyond the capabilities of the C
language that real compilers had to be used and the translator was abandoned.
http://en.wikipedia.org/wiki/Cfront
I'm taking you down this rabbit hole because you need to be aware of the problems
before you can understand why some things which seem like spectacular failures still
exist in all of these languages.   They were all attempts to work around this problem.
Yes, even the creation of MySQL and SQLite were attempts to work around this very
problem.    While  it  may  be  difficult  to  understand  with  SQLite,  it  should  be  readily
apparent   when   you  visit   the   MySQL   site   and  look   at   the   possible   responses   for   the
SHOW ENGINES command.  

Illustration 2: MySQL Show Engines

In   the   early   days   of   C/C++,   each   of   these   engines   would   have   had   their   own
proprietary   C/C++   header   files   and   library   interface   calls.     Each   would   have   used
function   names   which   were   completely   incompatible   with   the   other,   not   to   mention
completely different parameter order and return values.  By placing the MySQL server
engine between the data and the application, you not only gained file sharing (which
really   never   existed   on   DOS/Windows),   but   you   gained   a   unified   interface.     Your
application issues the SQL INSERT command and MySQL has to figure out how to get

Chapter 1 – Fundamentals

57

the data into the indexed file.
Please note that only one engine currently supports transactions.   Many people
draw the conclusion that if you read and write via SQL it must support transactions.
Nothing could be further from the truth!
Old hands should not be surprised by the popularity of either MySQL or SQLite.
Most of you should remember the heyday of Novell when it sold a file server known as
Netware.  What this server had over all others was the Btrieve indexed file system.  It
handled all of the sharing and provided a “requester” which could either create unshared
local   files   or   shared   remote   files.     Netware   sold   in   massive   quantities   despite   its
incredibly high price and even higher branded/certified component prices.  For the first
time desktop computers had a robust shareable indexed file system.
Today, we have TCP/IP standards and Open Source databases which will let any
desktop computer become a database server provided someone wants to enter all of the
user IDs and passwords.   It's a bit of a break from the file server­based database, but
eventually we shall find a happy middle ground.  Having to have a different username
and password for every database you access is a real PITA.  Old style, centrally served
databases allowed you to connect to any number of databases once you were logged into
the   server.     Many   of   those   “server”   platforms   are   the   highly   secure   midrange   and
mainframe platforms most of the PC world is calling legacy and heritage, yet the PC
world still cannot replace.
I had planned on putting another one of my nice little tables in here to show you the
differences, but, Java doesn't allow for or support the struct keyword.  The Java world
expects you to create simple classes instead.  I can see where they came up with this idea
and it is a fine­fine boot to the head.

58

Chapter 1 ­ Fundamentals

hello_struct.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

//

The most familiar test program in the world.

#include <stdio.h>
#include <string.h>
struct my_struct {
int a, b, c;
char *the_name_str;
} fred;
typedef struct {
long
emp_id;
char
first_name[35];
char
last_name[45];
short int
age;
} emp_age;
typedef struct {
public: long
emp_id;
private: char
first_name[35];
private: char
last_name[45];
protected: char
dept[10];
public: void fill_in( char *f, char *l, char *d)
{strcpy( first_name, f);
strcpy( last_name, l);
strcpy( dept, d);
}
void display_this() {
printf( " %ld %s %s %s\n",
emp_id, first_name, last_name, dept);
}
} emp_dept;
int main()
{
emp_age a1;
emp_dept d1;
printf( "Hello Word!!\n");
fred.a = 12; fred.b = 13; fred.c = 14;
fred.the_name_str = "test name";
printf( "fred: %d %d %d %s\n",
fred.a, fred.b, fred.c,
fred.the_name_str);
a1.emp_id = 1024L;
strcpy( a1.first_name, "Roland");
strcpy( a1.last_name, "Hughes");

Chapter 1 – Fundamentals
51
52
53
54
55
56
57
58
59
60
61
62
63 }

a1.age = 21;

59

// I wish!!

printf( "a1: %ld %s %s %d\n",
a1.emp_id, a1.first_name, a1.last_name,
a1.age);
d1.emp_id = a1.emp_id;
d1.fill_in( a1.first_name, a1.last_name, "IT");
printf( "d1: ");
d1.display_this();
return 0;

Notice that I put a CXX extension on this instead of C.  If you save this file with a C
extension and try to compile it you will have the following happen:
roland@linux-c345:~> gcc hello_struct.c -o hello_struct
hello_struct.c:20:5: error: expected specifier-qualifier-list before ‘public’
hello_struct.c: In function ‘main’:
hello_struct.c:57:7: error: ‘emp_dept’ has no member named ‘emp_id’
hello_struct.c:58:7: error: ‘emp_dept’ has no member named ‘fill_in’
hello_struct.c:60:7: error: ‘emp_dept’ has no member named ‘display_this’
roland@linux-c345:~>

A CXX extension allows for successful compile, link, and execution.
roland@linux-c345:~> g++ hello_struct.cxx -o hello_struct
hello_struct.cxx: In function ‘int main()’:
hello_struct.cxx:43:25: warning: deprecated conversion from string constant to
‘char*’
hello_struct.cxx:58:50: warning: deprecated conversion from string constant to
‘char*’
roland@linux-c345:~> ./hello_struct
Hello Word!!
fred: 12 13 14 test name
a1: 1024 Roland Hughes 21
d1: 1024 Roland Hughes IT

I'm   not   real   happy   with   the   change   in   the   C/C++   standard   which   deprecated
conversion from string constant to 'char *', but I have to live with it.   Basically OOP
pooched normal computer architecture and compiler writers have not been able to cope.
Remember   when  I   told  you  about  the   PC  “memory   models”  earlier  in   this   chapter?
Well,  other  architectures  had better  control,  they  used  PSECTs  which  were  Program
Sections  in memory.   Each PSECT could  be tagged with various  attributes  like RD,

60

Chapter 1 ­ Fundamentals

WRT, EXEC, RDNLY, etc.   The PC tried doing this initially with the segments, then
adopted the PSECT model (as best it could) for the multi­segmented memory models.
During the days of C and other early 3GLs, ALL constants were rolled into one or
more PSECTs which had the RDNLY (Read Only) attribute assigned.  Compiler writers
didn't have to care about what you did with a string pointer because the instant you tried
to write to a RDNLY PSECT, the OS would kill your process with an access violation.
Somewhere, in the middle of all this, came self modifying languages like LISP and
Forth.  Champions of them cheered the self modifying language as a “living language”
thus inherently secure and most suitable for AI (Artificial Intelligence) work.  The rest
of the IT world decried self modifying languages for being non­deterministic AND not
taking advantage of the hardware protection available in the computer.  While you can
still   find   LISP   and   Forth   out   there,   thankfully,   the   marketing   machine   for   AI
dramatically  over sold  what could  be delivered  in the short  term  and self  modifying
languages have very little in the way of real dollars or real development efforts being
thrown at them.  
Regrettably,   most  of  the   AI  developers  and  language   designers  which   were  cast
aside  by the industry, managed  to jump  into  jobs  at places like Bell Labs and other
research  facilities  that  were  coming  up with  OOP.   They perpetuated  this really  bad
practice   of   self   modifying   language   and   carefully   disguised   it   within   the   Object   of
Object Oriented Programming.
C programmers had thousands of lines in header files which contained text like this:
#define DEFAULT_ACCOUNT “01123445”
#define MAX_DRAW_NO 57

Borland C programmers had thousands of lines scattered about in there header files
which contained text like this:
const char *DEFAULT_ACCOUNT = “01123445”;
const int MAX_DRAW_NO = 57;

The first course of action was actually ANSI standard C.   The precompiler would

Chapter 1 – Fundamentals

61

textually replace every occurrence of the defined text with the substitute text.  If you had
a single pass compiler, that was as far as it went.  You would have however many copies
of these values as was found during the first pass.  If you had an N­pass compiler and
linker, each instance of the constants requiring more than four bytes of storage (refer to
type and size table earlier in this book) would be replaced with a pointer or reference to
a single instance of that constant placed in a read only constants PSECT.
Borland, never one to follow rules, decided to introduce “constant folding” early on
in the C language, long before it could even be considered for standardization.   Most
compilers flagged it as an error to have the same constant defined more than once, even
if all definitions had the same value.   Putting the “const” declarations in header files
would   cause   this   to   happen   with   every   module   that   included   them.     The   Borland
compiler would simply “fold” all of these constants into a single instance off in a read
only constant PSECT which was illegal according to the standard of the time and caused
seriously heated debate, especially when the constants were different values.
I'm bringing all of this up because OOP tossed a real monkey wrench into things
when they allowed constants to be declared in object methods instead of requiring them
to be declared as a static constant at the global level of the object.

62

Chapter 1 ­ Fundamentals

hello_class_const.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

//

The most familiar test program in the world.

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
class my_class {
private: int no_1, no_2, no_3;
char draw_dt[9];
public: void set_values( int a, int b, int c, char *d) {
const int MAX_DRAW_NO = 57;
if ( a <= MAX_DRAW_NO)
no_1 = a;
else
cout << "Invalid no_1 value" << endl;
if ( b <= MAX_DRAW_NO)
no_2 = b;
else
cout << "Invalid no_2 value" << endl;
if ( c <= MAX_DRAW_NO)
no_3 = c;
else
cout << "Invalid no_3 value" << endl;
strncpy( draw_dt, d, 8);
};
};
int main()
{
my_class m;
printf( "Hello Word!!\n");
m.set_values( 1, 59, 8, "20110425");
return 0;
}

When I was getting my degree in computer science, every student had to take a class
called   something   like   “compiler   theory”   or   “compiler   construction”   or   “theory   of
compiler   construction”   where   we   learned   about   Reverse   Polish   Notation,   studied   2's
compliment yet again, and learned that you put all constants in a write protected (read

Chapter 1 – Fundamentals

63

only) PSECT.   Nobody who actually passed a compiler construction class would have
allowed this into the language specification.
Take a good look at the two highlighted lines.  While it is true that I didn't add the
“inline” qualifier to the method, it is short enough that it will be inlined.  Now look at
listing line 34 and tell me where my object exists.  That's right, it's on the STACK, not
on   the   memory   heap.     While   it   is   true   that   the   “object   instance”   could   actually   be
constructed   with   a   pointer   to   the   member   method,   putting   the   member   method
somewhere in an executable PSECT, a single pass compilation would not do this.   In
theory, depending upon how the compiler danced around this debacle, we have compiled
executable code into the program call stack.  Most security professionals would call that
an earmark or trademark of a virus.   The program call stack is supposed to have only
return addresses, return values, parameters, and locally declared data.   Like everyone
else, I used to say “locally declared variables,” but now I say data because the word
variables is exactly how we got into this situation.
roland@linux-c345:~> g++ hello_class_const.cxx -o hello_class_const
hello_class_const.cxx: In function ‘int main()’:
hello_class_const.cxx:38:39: warning: deprecated conversion from string constant
to ‘char*’
roland@linux-c345:~> ./hello_class_const
Hello Word!!
Invalid no_2 value

Let's look at a slightly different version of this example.

64

Chapter 1 ­ Fundamentals

hello_class_struct2.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

//

The most familiar test program in the world.

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
class my_class {
private: int no_1, no_2, no_3;
char draw_dt[9];
static const char *DEFAULT_DATE;
public: void set_values( int a, int b, int c, char *d) {
const int MAX_DRAW_NO = 57;
if ( a <= MAX_DRAW_NO)
no_1 = a;
else
cout << "Invalid no_1 value" << endl;
if ( b <= MAX_DRAW_NO)
no_2 = b;
else
cout << "Invalid no_2 value" << endl;
if ( c <= MAX_DRAW_NO)
no_3 = c;
else
cout << "Invalid no_3 value" << endl;
strncpy( draw_dt, d, 8);
};
void display_values() {
cout << "no_1: " << no_1;
cout << " no_2: " << no_2;
cout << " no_3: " << no_3;
char *str = (char *)DEFAULT_DATE;
strcpy(str,"Fred");
cout << " draw_dt: " << draw_dt;
cout << " DEFAULT_DATE: " << DEFAULT_DATE;
cout << endl;
};
};
const char* my_class::DEFAULT_DATE

= "20110428";

int main()
{
my_class m;
printf( "Hello Word!!\n");
m.set_values( 1, 53, 8, "20110425");

Chapter 1 – Fundamentals
51
52
53
54
55 }

65

cout << "displaying values now " << endl;
m.display_values();
return 0;

roland@linux-c345:~> g++ hello_class_const2.cxx -o hello_class_const2
hello_class_const2.cxx: In function ‘int main()’:
hello_class_const2.cxx:50:39: warning: deprecated conversion from string constant
to ‘char*’
roland@linux-c345:~> ./hello_class_const2
Hello Word!!
displaying values now
Segmentation fault

I'm discussing this example because it was not all that long ago when this example
would work on seemingly any platform.   Many platforms will allow a user to elevate
their priv enough to make it work even today, if you don't believe me, just think about
how it is the PSECT gets loaded the first time.
Listing line 33 is where we cast away the  constness of DEFAULT_DATE.   This
eliminates the compilation warning and allows us to create an exectable.   OpenSuSE
apparently manages to set protection correctly on class level constants.  Now, let's tweak
this code just a bit more.

66

Chapter 1 ­ Fundamentals

hello_class_struct2.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

//

The most familiar test program in the world.

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
class my_class {
private: int no_1, no_2, no_3;
char draw_dt[9];
static const char *DEFAULT_DATE;
public: void set_values( int a, int b, int c, char *d) {
const int MAX_DRAW_NO = 57;
if ( a <= MAX_DRAW_NO)
no_1 = a;
else
cout << "Invalid no_1 value" << endl;
if ( b <= MAX_DRAW_NO)
no_2 = b;
else
cout << "Invalid no_2 value" << endl;
if ( c <= MAX_DRAW_NO)
no_3 = c;
else
cout << "Invalid no_3 value" << endl;
strncpy( draw_dt, d, 8);
};
void display_values() {
const int MAX_DRAW_NO = 42;
cout << "no_1: " << no_1;
cout << " no_2: " << no_2;
cout << " no_3: " << no_3;
char *str = (char *)DEFAULT_DATE;
//strcpy(str,"Fred");
cout << " draw_dt: " << draw_dt;
cout << " DEFAULT_DATE: " << DEFAULT_DATE;
int *my_int = (int *)&MAX_DRAW_NO;
*my_int = 12;
cout << " MAX_DRAW_NO: " << MAX_DRAW_NO;
cout << “ my_int: “ << *my_int;
cout << endl;
};
};
const char* my_class::DEFAULT_DATE
int main()
{

= "20110428";

Chapter 1 – Fundamentals
51
52
53
54
55
56
57
58
59
60 }

67

my_class m;
printf( "Hello Word!!\n");
m.set_values( 1, 53, 8, "20110425");
cout << "displaying values now " << endl;
m.display_values();
return 0;

roland@linux-c345:~> g++ hello_class_const2.cxx -o hello_class_const2
hello_class_const2.cxx: In function ‘int main()’:
hello_class_const2.cxx:55:39: warning: deprecated conversion from string constant
to ‘char*’
roland@linux-c345:~> ./hello_class_const2
Hello Word!!
displaying values now
no_1: 1 no_2: 53 no_3: 8 draw_dt: 20110425� DEFAULT_DATE: 20110428 MAX_DRAW_NO:
42 my_int: 12

This  is a fine kettle  of fish.   Most  of you will  either  be burned  by this  or have
already been burned by this.  What actually happens and what is allowed in the standard
seem to vary widely.  The standard says the behavior is undefined.  Many platforms will
let   you   modify   the   const,   and   many   will   not.     Worse   yet   is   what   we   see   the   GNU
compiler doing.  It appears to point the pointer to some other location, and allows you to
write there.  Thus, when we check my_int, we see the value we want, but when we check
MAX_DRAW_NO we see the original constant value.  I will leave it as an exercise for
the reader to find out if we get the same address returned for all integer constants, or a
different   address   returned   each   time   we   attempt   to   take   the   address   of   an   integer
constant.
C#/Mono and C++ share many of the same rules and characteristics of structures.  A
struct is a “sealed” entity, unlike a class.  A struct cannot be derived from another struct.
That said, all bets are off when it comes to what gets placed inside of a struct.  Not only
can a struct contain code and value types, but, in may cases you can put a class inside of
a struct.  That class can even contain member variables which happen to have the same
name as members of the struct.

68

Chapter 1 ­ Fundamentals

hello_struct_class.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

//

The most familiar test program in the world.

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
class my_class {
private: int no_1, no_2, no_3;
char draw_dt[9];
static const char *DEFAULT_DATE;
public: void set_values( int a, int b, int c, char *d) {
const int MAX_DRAW_NO = 57;
if ( a <= MAX_DRAW_NO)
no_1 = a;
else
cout << "Invalid no_1 value" << endl;
if ( b <= MAX_DRAW_NO)
no_2 = b;
else
cout << "Invalid no_2 value" << endl;
if ( c <= MAX_DRAW_NO)
no_3 = c;
else
cout << "Invalid no_3 value" << endl;
strncpy( draw_dt, d, 8);
};
void display_values() {
const int MAX_DRAW_NO = 42;
cout << "no_1: " << no_1;
cout << " no_2: " << no_2;
cout << " no_3: " << no_3;
char *str = (char *)DEFAULT_DATE;
//strcpy(str,"Fred");
cout << " draw_dt: " << draw_dt;
cout << " DEFAULT_DATE: " << DEFAULT_DATE;
int *my_int = (int *)&MAX_DRAW_NO;
*my_int = 12;
cout << " MAX_DRAW_NO: " << MAX_DRAW_NO;
cout << " my_int: " << *my_int;
cout << endl;
};
};
const char* my_class::DEFAULT_DATE
struct my_struct {

= "20110428";

Chapter 1 – Fundamentals
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

69

class my_class m1;
int my_int;
};
int main()
{
struct my_struct ms1;
printf( "Hello Word!!\n");
ms1.m1.set_values( 1, 53, 8, "20110425");
ms1.my_int = 255;
cout << "displaying values now " << " my_int: " << ms1.my_int << endl;
ms1.m1.display_values();
return 0;
}

roland@linux-c345:~> g++ hello_struct_class.cxx -o hello_struct_class
hello_struct_class.cxx: In function ‘int main()’:
hello_struct_class.cxx:61:44: warning: deprecated conversion from string constant
to ‘char*’
roland@linux-c345:~> ./hello_struct_class
Hello Word!!
displaying values now my_int: 255
no_1: 1 no_2: 53 no_3: 8 draw_dt: 20110425 DEFAULT_DATE: 20110428 MAX_DRAW_NO: 42
my_int: 12

To anyone who didn't have the source code to look at, this output would be a major
boot to the head.  Notice that the struct always defaults to public access because that's
what it was originally in C.  That said, unless you know with absolute certainty that your
struct contains only ordinary value types in it, I would refrain from doing a binary write
of it to any file.  Remember all of the earlier discussion about alignment?  That reality
hasn't gone away.  Actually, it is one of the many reasons C++ and OOP in general had
to come up with Serializable and Serialize.  
Objects may be nice inside of your program, but, you cannot ensure the exact same
object will have the exact same size and alignment on another platform or even the next
time it is run.  Most OOP languages provide a method for assigning a “unique version”
to the unique RTTI (Run Time Type Identifier) and including at least the version if not
the entire RTTI value when generating the serialized output of a class.

70

Chapter 1 ­ Fundamentals

If I'm confusing you, don't worry.  You really only have to know that this debacle
existed for classes.  There are many examples for both C# and C++ on­line.  One for C#
can be found here:
http://www.switchonthecode.com/tutorials/csharp­tutorial­serialize­objects­to­a­file
Never under any conditions get talked into doing this for a project!
There is absolutely no reason to undergo serialization of objects in this day and age.
We have dozens of Open Source databases systems which are all free and offer various
levels of functionality.  There are even Java, C++, and Mono class libraries which will
allow you to read and write XBASE type DBF files.  For most developers today though,
SQLite,   with   its   bind   in   capabilities   will   win   out   the   day   unless   they   are   writing   a
business class application which requires a business class database like PostgreSQL.
If you ever interview for a job programming in C++, Java, Mono, or any other OOP
language and they ask you if you understand object serialization, simply get up and walk
out without answering.  Shops like these still exist and they shouldn't.  What is the point
of serialization?  To store information for future use.  What is the purpose of a database?
To   store   information   for   future   use.     When   the   information   is   in   a   database,   other
applications written in other languages can access it.  When information is serialized to a
file, you have to load it back into a compatible object.  As you can see, shops still doing
serialization are in desperate need of a qualified Systems Architect.

71

Chapter 1 – Fundamentals
1.4 Friends and Protection

If you thought the previous discussion on structures, classes and the constants within
was an eye glazer, you are really going to love this section.   We brushed the topic of
protection (also known as access modifiers) last section.   This section will attempt to
explain them better and discuss a debacle known as friends.
C++   tried   to   set   the   standard  for   access,  and  tried  to  keep   it   simple.     Until  the
creators of Qt came up with the concept of Signals and Slots, C++ protection  failed
miserably.
C++ Access

Public

Protected

Private

Member of same class

Y

Y

Y

Member of Derived class

Y

Y

N

World

Y

N

N

Friend function

Y

Y

Y

Friend class

Y

Y

Y

If no protection was listed for a class member or method, and no protection had been
specified   earlier   in   the   class   definition,  the   default   protection   level   is   private.     It
shouldn't be difficult to imagine that things got out of hand with many of the C++ class
libraries.   Everything was either friend or public because you needed to get access to
things the original developers kept locked away.
Let me clear up one major point of C++ confusion here:
class my_class : public some_other_class {…}

The above statement does not cause only the public items to be inherited, all items
will be inherited.  What this does is set the minimum protection level to be applied to
those inherited things.  If we had chosen to say “protected” instead of “public” all of the
public members and methods would be inherited as private in my_class.   All equal or

72

Chapter 1 ­ Fundamentals

higher protection levels would remain the same.
C++ is a major stickler for not allowing the downgrading of protection.  If a method
is declared private, you cannot derive a new class and override that method with a public
version.
Java, developed some years after C++ hit the market, had the benefit of being able to
see what didn't work in C++ and tried to fix such things in the Java specification.  Java
added   an   access   type   and   dropped   “friend.”     Java   also   tried   to   eliminate   multiple
inheritance.     Indeed,   it   removed   the   direct   ability,   then   had   to   add   Interfaces   to   the
language   and   allow   for   multiple   Interfaces   because   single   level   inheritance   couldn't
solve most of the problems developers needed to solve.

Java Access

Default

Public

Protected

Private

no modifier
package private
Member   of   same
class

Y

Y

Y

Y

Member   of   same
package

Y

Y

Y

N

Member   of   derived
class in same package

Y

Y

Y

N

Member   of   derived
class   in   different
package

N

Y

*

N

World

N

Y

N

N

Chapter 1 – Fundamentals

73

I'm sure you noticed that lovely little * in the table.   I wish it weren't so, but, we
have to delve a bit deeper at this point.  The definition generated by your JVM for your
new class will contain all of the protected elements and methods from the base class,
however, you cannot access the data of an instance of a base class using your new class
definition.
Java got rid of pointers because the programmers working on the Java specification
could   never   make   pointers   work.     It   sounds   cruel,   but   it   is   pretty   much   the   truth.
Pointers  got   abused  in   C,   I  don't   think   the   English  language   contains   a  word   which
accurately  describes  what happened  to them  in C++.   It was  not uncommon  to have
classes with many levels of inheritance from some BaseObject.   Since C++ supported
quiet   promotion/demotion   as   long   as   the   classes   had   common   ancestors,   really   bad
things would happen.

Illustration 3: Generic Class Hierarchy

I always loath creating inheritance diagrams.   No matter how you do it, someone
always   wants   the   arrow   heads   pointing   the   other   direction   or   the   boxes   organized
differently.     For   the   sake   of   this   discussion,   inherited   from   both   BaseObject   and
OtherBaseObject.  DerivedC inherited from DerivedB.

74

Chapter 1 ­ Fundamentals

You   can   list   a   method/function   parameter   as   “DerivedC   *c_ptr”   or   “BaseObject
*bo_ptr”   and   receive   one   or   the   other,   usually   without   any   complaints   from   the
compiler.     As   long   as   the   method/function   receiving   the   pointer   really   only   needed
things which existed in the BaseObject class, life was good.  If you cast a BaseObject to
a DerivedC object in a method/function which really needed the Derived C capabilities,
life was not so good for you.
What the little * in the table is trying to indicate is that Java doesn't support this
oft­abused C++ capability, mainly because it eliminated pointers.
Microsoft, in its desperate attempt to put a new coat of paint on its Java product,
changed the names of things.   To start with, package became assembly.   C# removed
multiple inheritance and friend classes, but kept pointers.
C#/Mono

Public

Protected Internal

Internal

Protected Private

Member of 
same class

Y

Y

Y

Y

Y

Member of 
same assembly

Y

Y

Y

N

N

Member of 
derived class 
in same 
assembly

Y

Y

Y

Y

N

Member of 
derived class 
in different 
assembly

Y

Y

N

Y

N

World

Y

N

N

N

N

Access

Chapter 1 – Fundamentals

75

C# has a wee bit of an oddity.  The “default” protection for things declared inside of
a class or a struct is private.  The default protection for things declared outside of a class
or   struct,   but   within   a   namespace   is   internal.     Interface   members   and   Enumeration
members implicitly have public access and do not allow modifiers.
“Protected Internal” is read as “protected or internal” not with an “and” joining them
as most would think.
Most   people   say   default   access   for   C#   is   “the   most   restricted   access   you  could
declare for that member.”   The operative word is “could.”   If you declare your class
public, you cannot declare your setter methods private.  If you are inheriting from a class
which declares a method public, you cannot override that method as private in your new
class.  We will discuss this a bit more when comparing namespaces vs. packages.

1.5 Packages, Assemblies, and JNI
Yes, we are going to veer off into packages and assemblies at this point, not because
they should come next, but because I want to create some code to verify that C#/Mono
access   table   we  created   in  the   previous   section.    You   will   find   a  lot   of  information
scattered about the Internet offering up conflicting wording on the various access levels.
I am guessing the vast majority of production C# code uses Protected Internal just to
keep from going insane.
Packages   end   up   being   bundled   into   JAR   files   when   working   with   Java.     An
“Assembly” is Microsoft's shiny new name for anything built with the mcs command.
This could be a DLL or executable.  In terms of Mono the DLL is replaced by a shared
library.   I covered the ins and outs of packages in  The Minimum You Need to Know
About Java and xBaseJ  ISBN­13: 979­0­9823580­3­0 and  The Minimum You Need to
Know About Java on OpenVMS   Volume 1  ISBN: 0­9770866­1­5 so I am not going to
waste paper covering that topic yet again.  Find one of these books and read it.

76

Chapter 1 ­ Fundamentals

One thing we will mention yet again is JNI.  The Java  Native  Interface is a set of
tools and specifications which makes your C language functions callable by Java classes.
It  is  a  rough  specification  and  we  worked  with  it  almost  exclusively  in  the  Java  on
OpenVMS book.  The JNI is required because your C modules will be executing inside
of   a   process,   yet   outside   of   the   protected   virtual   machine   environment.     The   Java
community   deliberately   makes   it   quite   a   burden   to   gain   access   to   outside   routines
because it wants all “common” system services to be provided by the VM and found
somewhere   in   the   System.blah.blah   package   tree.     The   problem   is   that   high­end
operating   systems   are   so   vastly   ahead   of   feeble   platforms   like   Windows,   Unix,   and
Linux that the “common” set of system services can't even knock on the door of what is
available natively on the platform.  Hence, Java development on high­end platforms is
always a significant pain.
I'm talking about the JNI first because this is one of the places where Microsoft was
looking to more tightly couple Java to their worthless Windows platform.  C#/Mono did
not add a JNI (C#NI) layer.  They chose to provide some automatically generated code
and   link   directly   to   the   platform­specific   library   file.     This   my   friends,   is   where
portability took a big stinky dump and a whole lot of lawyers got involved.
There were many arguments tossed about.  The Java community was tossing about
the slogan  “Write  Once, Run Anywhere”  and quietly  ignoring anything having to do
with JNI. Most of the books covering the JNI have long since been removed from the
marketplace, with the exception of my Java on OpenVMS book.  No matter what you do
with the JNI, if you want others to be able to use it, some kind of installed or shareable
image has to be created and installed in a manner which makes it accessible to the JVM.
What Microsoft was attempting to do was make the entire WINAPI available to Web
sites, thus tightly coupling those sites to Microsoft desktops.  When the lawyers got done
and   the   dust   started   to   settle,   Microsoft   was   pretty   much   tossed   out   of   the   Java
community and .NET (pronounced DOT NOT by most industry insiders even though
Microsoft's marketing department pronounces it DOT NET) started to emerge.

Chapter 1 – Fundamentals

77

During the introduction chapter, you saw the following:
roland@linux-c345:~/mega_Mono> mcs helloworld.cs
roland@linux-c345:~/mega_Mono> Mono helloworld.exe
Hello World!
roland@linux-c345:~/mega_Mono>

The output of the mcs command is actually called a single file assembly.  There are
a lot of compilation options for this command line.  There are also multiple commands.
mcs – uses 1.0 specification with parts of 2.0 and 3.0
gmcs – uses 2.0 and 3.0
smcs – uses Silverlight/Moonlight to create applications for use in a browser.
When adding multiple modules to a library your command line would look much
like the following:
mcs -t:library -o my_lib module1.cs module2.cs module3.cs

Standard Unix/Linux line shell script line continuation rules would apply.   Since I
do not know what shell you are running, I cannot provide a definitive answer.   When
compiling your C modules you will need to include the ­fPIC compiler option on the
command   line.     This   tells   the   compiler   to   do   the   extra   work   of   generating   position
independent code.  This type of code cannot be generated on all processors.  Assuming
you   get   all   of   your   C   modules   to   compile   cleanly   using   gcc,   you   will   then   issue   a
command line looking much like the following:
gcc -combine -shared -Wl,-soname,libmylib.so.1 -o libmylib.sl.1.o.1 \
module1.o module2.o module3.o module4.o

78

Chapter 1 ­ Fundamentals

The combine option says we want it all in a single output file.  The shared option
indicates we are creating a shared library.  The odd looking combination of uppercase W
followed by a lowercase l followed by ­soname, libmylib.so.1 actually all goes together
and cannot have any intervening spaces.  The first tells gcc to pass the next option to the
linker.   The comma following that option tells gcc to continue passing the next linker
option.  A soname is a field of data in a shared object file.  It contains a “logical name
string” which describes the functionality of the object.  All Linux shared object libraries
must start with  lib and end with a .so just in front of the library version.  The version
information is actually kept in the file name.   You only change the soname when you
significantly change the library in such a way that it is no longer backwardly compatible.
If  you have  a shared  object  library  and  are  in doubt  as  to how  far  it is  backwardly
compatible, you can use the following command:
objdump libname.so.1.3.4 -p | grep SONAME

As always with gcc, the ­o option names our actual output file.  I used the bash line
continuation to stick all of the object modules on the next line.
bld_testaccess.sh
1
2
3
4
5

mcs -t:library -out:mylib1.dll mybase.cs deriv1.cs same1.cs
mcs -t:library -out:mylib2.dll -reference:mylib1.dll deriv2.cs
mcs -out:testaccess1.exe -reference:mylib1.dll,mylib2.dll testaccess1.cs

I'm not exactly certain if it was due to some recent updates or the fact we now have
more switches on the mcs command line, but ­o caused complaints that I should use ­out:
instead.  I'm really not crazy about the DLL and EXE extensions either, but, this is what
Microsoft  wants.    Notice  how  you  need  to  specify  the  libraries  you  will  use  on  the
compilation line?  This is because C# does not have header files.  When coding in C++
you would have simply included all of the header files with all of the prototypes and the
linker would have been left with the chore of finding the correct library.

Chapter 1 – Fundamentals

79

mybase.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

using System;
namespace MyBase
{
public class MyBaseClass
{
public void the_public_method()
{
Console.Out.WriteLine("You Accessed MyBaseClass public method");
}
protected internal void the_protected_internal_method()
{
Console.Out.WriteLine(
"You Accessed MyBaseClass protected internal method");
}
internal void the_internal_method()
{
Console.Out.WriteLine("You Accessed the internal method");
}
protected void the_protected_method()
{
Console.Out.WriteLine("You Accessed the protected method");
}
private void the_private_method()
{
Console.Out.WriteLine("Hello World!");
}
}
}

This stuff is pretty self explanatory.  I created one method for each type of access
protection.  When it is invoked it spits a line out to the console.

80

Chapter 1 ­ Fundamentals

deriv1.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

using System;
using MyBase;
//
// First derived class will be compiled into same library
// We can call everything but private
//
namespace Deriv1
{
public class MyDerivedClass : MyBaseClass
{
public void test_access()
{
Console.Out.WriteLine("Testing Derived class in same assembly");
the_public_method();
the_protected_internal_method();
the_internal_method();
the_protected_method();
Console.Out.WriteLine(" ");
}
}
}

same1.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

using System;
using MyBase;
//
// This class just happens to be in same assembly
// We can call eveyrthing but protected and private
//
namespace Same1
{
public class Same1Class
{
public void test_access()
{
MyBaseClass mb = new MyBaseClass();
Console.Out.WriteLine(
"Testing class in same assembly but not derived");
mb.the_public_method();
mb.the_protected_internal_method();
mb.the_internal_method();
Console.Out.WriteLine(" ");
}
}
}

Chapter 1 – Fundamentals
deriv2.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

using System;
using MyBase;
//
// Second derived class will be compiled into different library
// We can call everything but internal and private
//
namespace Deriv2
{
public class MySecondDerivedClass : MyBaseClass
{
public void test_access()
{
Console.Out.WriteLine("Testing Derived class in different
assembly");
the_public_method();
the_protected_internal_method();
the_protected_method();
Console.Out.WriteLine(" ");
}
}
}

81

82

Chapter 1 ­ Fundamentals

testaccess1.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

using
using
using
using
using

System;
MyBase;
Deriv1;
Same1;
Deriv2;

namespace TestAccess1
{
class TestAccess1
{
static void Main(string[] args)
{
MyBaseClass mb = new MyBaseClass();
// From outside world we can only access public
//
Console.Out.WriteLine(
"Testing World access outside of assembly");
mb.the_public_method();
Console.Out.WriteLine(" ");
MyDerivedClass md = new MyDerivedClass();
md.test_access();
Console.Out.WriteLine(" ");
Same1Class s1 = new Same1Class();
s1.test_access();
Console.Out.WriteLine(" ");
MySecondDerivedClass md2 = new MySecondDerivedClass();
md2.test_access();
}
}
}

Each derived class tests by simply trying to access the methods.  The same1class and
this class must declare instances of the object in order to test.  Please note that C#/Mono
does not let you declare an object on the stack like C++ did.  Listing line 13 declares a
reference  named mb to an object of MyBaseClass type.   Until we call new to actually
create an instance of that object the reference is either null or undefined.   Remember,
C#/Mono is mostly white­washed Java.  If you read “The Minimum You Need to Know
About Java on OpenVMS    Volume 1” you will find a nice explanation of this instance
and reference stuff in the section titled “Everything is a Class  (almost).”

Chapter 1 – Fundamentals

83

Since I put the actual testing code in each of the classes, we only needed to create
the world access testing in this class.
roland@linux-c345:~/mega_Mono> Mono ./testaccess1.exe
Testing World access outside of assembly
You Accessed MyBaseClass public method
Testing Derived class in same assembly
You Accessed MyBaseClass public method
You Accessed MyBaseClass protected internal method
You Accessed the internal method
You Accessed the protected method
Testing class in same assembly but not derived
You Accessed MyBaseClass public method
You Accessed MyBaseClass protected internal method
You Accessed the internal method
Testing Derived class in different assembly
You Accessed MyBaseClass public method
You Accessed MyBaseClass protected internal method
You Accessed the protected method

1.6 Programming Assignment 1
You didn't really think I was going to get to page 100 in this book without starting to
hand out programming assignments did you?  Your assignment is to modify this code to
test each of the access methods which are not allowed according to the chart.  Yes, you
will have to edit and compile many times because there is no way for you to complete
this assignment on a single pass.

1.7 Programming Assignment 2
It should come as no surprise to you that C# has the same “this” pointer as C++.
You are to add private data elements to the base class, then add methods to each of the
the derived test classes where you cast the “this” pointer to the base class and attempt to
access both private methods and private elements.

84

Chapter 1 ­ Fundamentals

1.8 Native Code Continued
We brushed on the topics of native access and unmanaged code section 1.5, but I
needed to show you how to build Mono libraries before we continued on with accessing
native   libraries.     Some   things   are   similar   and   some   things   are   different   from   our
discussion about access Mono routines/classes in DLL files.  To start with, Mono forks
off   rather   distinctly   from   C#   when   it   comes   to   calling   native   code.     C#   expects
everything  to be in a DLL file and isn't  too polite  about any deviation.   C# will not
automatically append the .DLL to the name if you accidentally type a period at the end
of your file name.
I'm going to be quite straight forward with this section and tell you that most Java
programmers punt when it comes to writing JNI.  If they cannot purchase a class which
already  does   what  they   need,   they   simply   refuse   to   write   the   code.     If  you   want   to
understand why read “The Minimum You Need to Know About Java on OpenVMS”.
Anyone who has read the Microsoft publications on calling C/C++ code from C#
will be a bit confused when it comes to how Mono chose to do things.  It wasn't just the
Mono community, GNU had a lot to do with it as well.   On the worthless Windows
platform, you only link DLLs.   On the worthless Windows platform Microsoft forces
you to use their Visual Studio for development and thus, controls how everything gets
done without actually exposing much of it.
The original version of this example did all of the calculations inside of the C and
C++ functions.  I could not get it to link correctly on OpenSuSE.  The problem is that
GNU didn't implement the pow() function like other things.  If you are creating a straight
C or C++ program you must use “­lm” on the compilation line to inform the linker about
pow().  I did not find a magic method of making this work with mcs.  Yes, I'm sure many
will volunteer some kind of solution, but I didn't feel like digging quite that deep in the
manuals.  It is either rarely done or scoffed at, because, there is nothing about it on­line
other than the error message you get.

85

Chapter 1 – Fundamentals
NativeClass.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

using System;
using System.run-time.InteropServices;

// gotta have this

public class NativeClass
{
[DllImport ("MyLib")]
private static extern double amort_1( double loan_amount,
double interest,
double compound_rate);
[DllImport ("MyLib")]
private static extern double balance_remaining( double loan_amount,
double interest,
double compound_rate,
double curr_compound);

public static void Main()
{
Console.Out.WriteLine("$350,000 for 60 months at 5.25%");
double monthly_interest = 0.0525/12.0;
double compound_rate = Math.Pow( (monthly_interest+1) , 60);
double monthly_payment = amort_1( 350000.00, monthly_interest,
compound_rate);
Console.Out.WriteLine(" Monthly Payment {0:C}", monthly_payment);
Console.Out.WriteLine("\n\n");
Console.Out.Write("Balance paid by payment 40: ");
double curr_compound = Math.Pow( (monthly_interest+1) , 40);
double balance = balance_remaining( 350000.00, monthly_interest,
compound_rate, curr_compound);
Console.Out.WriteLine("{0:C}",balance);
}

30
31
32
33 }

Our   example   program   is   going   to   call   some   “existing”   mortgage   formulas.     I
intended   this   to   be   a   quasi­real   world   example.     If   there   were   any   existing
heritage/legacy/pre­existing functions out there a company would not want to rewrite or
invent, it would be financial stuff.  If I hadn't been screwed by GNU's implementation of
pow(), this example would have been perfect.   As this example unfolded, I ended up
having to use the Pow() method provided by Mono to calculate portions of the formulas
which makes the actual formulas look weird.

86

Chapter 1 ­ Fundamentals

fun_1.c
1
2
3
4
5
6
7
8
9
10
11
12
13

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double amort_1( double loan_amount, double interest, double compound_rate)
{
printf( "\nloan_amount $%9.2f
interest %7.6f
compound_rate %f\n\n",
loan_amount, interest, compound_rate);
return (loan_amount *
((interest * compound_rate ) / (compound_rate - 1 )));
}

From a language perspective, there is nothing interesting here.  We get away with
passing   doubles   because   Mono   relies   on   GNU;   hence   the   types   are   the   same.    The
double type will not be the case with other compilers, nor would it be the case if other
switches were used on the compilation line.
fun_2.cpp
1
2
3
4
5
6
7
8

#include <math.h>
extern "C" double balance_remaining( double loan, double interest,
double compound_rate, double curr_compound)
{
return (loan * ( compound_rate - curr_compound)
/ ( compound_rate - 1));
}

Notice that we have to force the C language calling convention when using C++.
With various DOS/Windows/and OS/2 compilers we had __cdecl keywords which could
be forced in to alter calling conventions.  
http://en.wikipedia.org/wiki/X86_calling_conventions
http://www.openwatcom.org/index.php/Calling_Conventions

Chapter 1 – Fundamentals

87

bld_native.sh
1
2
3
4
5
6
7
8
9

gcc -fPIC -c -o fun_1.o -Wall fun_1.c
gcc -fPIC -c -o fun_2.o fun_2.cpp
gcc -combine -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0.1 \
fun_1.o fun_2.o

mcs -out:NativeClass.exe -lib:/home/roland/mega_Mono NativeClass.cs

The   ­fPIC   compiler   switch   tells   the   compiler   to   always   create   relocatable   code.
While this is “known to be the default” on x86 Linux platforms, it's not always the case,
particularly   if   you   include   oddball   calls   like   pow().     Quite   simply   ­Wall   tells   the
compiler to display all warnings.
If all you do is include the highlighted ­lib switch when compiling your Mono code
to use a shared object library, don't be surprised if you see the following error message
at either compile time or run time:
Mono error CS0006: cannot find metadata file ".so"

There   is   one   file   needed   which   I   have   yet   to   discuss.     Please   look   back   at   the
DllImport line highlighted in our cs file.   I chose not to discuss it then because it is a
much bigger discussion than its size would indicate.  This line, in its current state, is also
a massively significant fork from C#.  Remember, Microsoft is only worried about being
compatible with other versions of whatever product Microsoft is selling as an operating
system, but Mono is looking for compatibility with the world.  
Most people are intelligent enough to realize that Microsoft is very quickly on its
way to joining Singer and Wang as names covered by dust in the footnotes of computing
history.     Some   of   these   people   are   even   the   founders   and/or   early   employees   of
Microsoft who are now spending lots of their own cash either quietly or publicly backing
the   development   of   Mono   so   Microsoft   doesn't   join   that   long   list   of   once   mighty
computing giants that disappeared without actually contributing anything meaningful to
the  computing  industry.    There  have  been  many  names  since  the  early  1970s  which

88

Chapter 1 ­ Fundamentals

came, generated millions, then disappeared without leaving anything lasting behind.
You   will   find   that   most   Mono   code   ends   up   being   non­portable   because   the
developer   puts   some   platform   specific   name   in   the   DllImport   statement.     This   is   a
horribly   sad   state   of   affairs   and   one   which   should   not   exist.     The   Mono   run­time
automatically looks for progname.exe.config in the same directory it finds the exe file.
This config file is processed prior to your program.  Among the many things you can do
inside of the config is provide platform specific name translation.
NativeClass.exe.config
1
2
3

<configuration>
<dllmap dll="MyLib" target="libmylib.so.1.0.1" />
</configuration>

If you need to include “native code” for whatever reason, you can simply keep a
different  config   file   for  each  operating  system   and   have   your   install  (or   distribution
packager) rename the correct file.   Here we mapped the generic “MyLib” name to the
platform specific shared object library.
Building and running the program yields the following:
roland@linux-c345:~/mega_Mono> ./bld_native.sh
roland@linux-c345:~/mega_Mono> Mono NativeClass.exe
$350,000 for 60 months at 5.25%
loan_amount $350000.00

interest

0.004375

compound_rate

1.299432

Monthly Payment $6,645.09

Balance paid by payment 40:

$126,987.76

Admittedly, if this example had been physically re­using methods which did all of
the calculations the example would have had more real world implications to it.  One of
the reasons Microsoft wanted to make it so simple to link in “native code” was to try and
extend the usability of everything which was already written.  One of the biggest pitfalls
of executing  “native”  code  on the Web  is that the browser  which  connected  to your
service has a completely different OS behind it.

89

Chapter 1 – Fundamentals
1.9 Arrays

You   may   wish   to   pour   yourself   a   fresh   beverage   before   reading   this   section.
Traditionally, arrays were the beginning of pointer discussions in data structures classes.
If you happen to have been taught data structures while you were being taught PASCAL,
then, you should fully understand why the world hates PASCAL and those who keep
pushing it.
We were all taught to “view” arrays mentally as either a contiguous stack, or an
endless   string.     Your   very   first   set   of   examples   involved   only   integers,   usually
longwords,  and they seemed so simple.  
6

13

1

0

14

2

18

5

6

8

3

7

4
2
8
7

No matter how you mentally viewed the array, the choice of data types hid some
ugly alignment facts.  Most of you sat there happily coding array navigation by using a
pointer that was incremented by one rather than a subscript.  If you had not been forced
to endure taking an Assembly language class at this point, you had no idea what hardship
awaited you.

90

Chapter 1 ­ Fundamentals

Those who were lucky went on to take a C/C++ programming class.  There you got
a hint about just how ugly things really were under the hood.  Perhaps it took until after
graduation, but, eventually you asked the question “Why does C have both malloc() and
calloc()?”  If you spent any time at all as a maintenance C programmer, you witnessed
some God­awful abuses of malloc() to force getting a contiguous region just so someone
could inefficiently manipulate a pointer rather than dereference a subscripted variable.
MBAs in the computing world love to make the exact same mistakes as every other
MBA  who  has come  before  them.    It appears  that  the kinds  of  engineers  who  these
MBAs   talk   with   also   like   to   commit   the   same   mistakes.     In   the   early   days   of   the
mainframe computer, designers decided that memory was so expensive that no company
or   government   could   ever   afford   more   than   X   amount   of   it.     Software   was   not   an
industry then, hardware was.   The hardware engineers didn't want to limit the address
space   for   their   as­of­yet­uninvented   devices,   so   they   picked   a   high   base   address   for
hardware   add­on   cards,   thus   creating   the   stage   for   a   memory­hardware­memory
segmentation issue.
Skip a few years forward and you will find the designers of the original IBM PC
making   the   justification   that   the   largest   mainframe   in   production   only   had   640K   of
RAM, so how could a toy computer need more?  Not only did this thinking give us the
magic 640K boundary you hear about in the DOS world, it also gave us that treacherous
384K region above it where adapter cards could be addressed, and memory managers
attempted   to   load   things   high.     In   other   words,   we   relived   the
memory­hardware­memory segmentation issues again.
Every computer operating system which allows for paging or swapping to disk must
in some way deal with memory segmentation because you need to measure the amount
of memory being moved around.  What is inexcusable is the memory holes created by
hardware   designers.     The   combination   of   memory   segmentation   with   memory   holes
made arrays far more complex than they needed to be in C/C++ and other languages.

Chapter 1 – Fundamentals

91

We touched lightly on the PC memory model system in section 1.3.  Each “segment”
under DOS was 64K in size.  DOS did not directly support paging and/or swapping to
disk.  An “address” under DOS fit into a longword and was of the form segment:offset.
Every memory model except Compact used this type of address.   Under the Compact
memory model everything had to fit into one segment, so all pointers were only a word
in size and they contained only the offset.
I   am   sorry   that   I   have   to   expose   you   to   this   level   of   discussion,   but,   without
understanding   the   vicious   flaw   created   by   the   hardware   geeks,   you   cannot   begin   to
understand just how difficult arrays were to originally implement.  Of course, you have
to take a look at some pretty common code to understand why this was.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

char *line_in, *tmp;
line_in = malloc( 40000);
do
{
memset( line_in, '\0', sizeof( line_in));
fgets( line_in, sizeof( line_in) -1, in_file);
if ( !feof(in_file))
{
tmp = &line_in[0];
while (*tmp != '\0')
{
if (*tmp == 'A')
*tmp = 'b';
tmp++;
}
}
}

while (!feof(in_file));

Other than a perplexing question as to why anybody would want to replace A with b
in this manner, there is really nothing wrong with this code.   I haven't compiled and
tested it, but we aren't looking for a syntax error.  (Okay, I didn't check for the malloc
failure and didn't free, but that's not where we are headed with this discussion.)  There
was nothing in most compiler and operating system environments to stop malloc() from
allocating memory across “segment boundaries.”  It was not uncommon to see the exact
same executable file run perfectly on many different DOS­based computers, then fail
miserably on the next installation because that user had different drivers or something

92

Chapter 1 ­ Fundamentals

loaded which changed the starting address of the free heap.  There were many compiler
bugs involving failure to increment the segment when the offset rolled over.
Had the above code been written to not use pointer math, it would have worked
correctly in all environments.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

char *line_in;
int x;
line_in = malloc( 40000);
do
{
memset( line_in, '\0', sizeof( line_in));
fgets( line_in, sizeof( line_in) -1, in_file);
if ( !feof(in_file))
{
x = 0;
while (line_in[x] != '\0')
{
if (line_in[x] == 'A')
line_in[x] = 'b';
x++;
}
}
}

while (!feof(in_file));

The push to use pointers instead of this syntax came from many directions.  First off,
many of us were using desktop computers with a whopping 4.77Mhz clock speed.  The
CPU in your current cell phone runs rings around those old chips.  We had to save clock
cycles wherever we could and nearly every geek of the day could quote off the top of
their head just how many clock cycles *tmp saved over line_in[x].
C++ had to maintain backward compatibility with C, so all “native or natural” data
types had arrays created as they were in C, but all arrays of objects were created using an
Array   class.     Every   C++   compiler   and   library   vendor   rushed   to   enhance   the   C++
language further by providing their own String classes to eliminate the previous coding
examples.  Eventually a String class was made part of the C++ standard, complete with
iterator, compare, substring, find, and many other methods types.   Not only could you
add to your String object, you never had to allocate it or know its size.  There was no
longer any realistic possibility of writing past the end of a string buffer.

Chapter 1 – Fundamentals

93

Java didn't have to support C, so, it removed all native memory management and
forced all arrays to be Array objects.  Java even removed the syntax which could confuse
a developer.
HelloWorldArray.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

import java.util.Random;
import java.util.Arrays;
public class HelloWorldArray
{
public static void main(String[] args)
{
System.out.println( "Hello World!");
int [] ar1 = new int [] {11,6,2,46,9};
int ar2[];
ar2 = new int [6];
Random gen = new Random();
System.out.print( "Second array");
for (int x=0; x < ar2.length; x++)
{
ar2[x] = gen.nextInt();
System.out.print( " " + ar2[x]);
}
System.out.println( "\n\nSorted output");
System.out.print( "Array One: ");
Arrays.sort(ar1);
for (int k=0; k < ar1.length; k++)
System.out.print( " " + ar1[k]);
System.out.print( "\nArray Two: ");
Arrays.sort( ar2);
for (int j=0; j < ar2.length; j++)
System.out.print( " " + ar2[j]);
System.out.println( "");
}
}

Listing lines 11 and 12 show the primary methods of declaring arrays in Java.  What
is important to note is that if you put a number in the [] as you would in C, you will get a
syntax error.  

94

Chapter 1 ­ Fundamentals

Listing line 17 shows how we use the length member variable and listing line 25
shows how to use the sort() method provided by the Arrays class.  Please note that the
sort()   method   isn't   part   of   the   array   you   create.     The   Arrays   class   contains   utility
methods for comparing, searching, and sorting native data type arrays, it's not actually
the class you derive from when creating an array.   This is the reason we could not do
ar1.sort().
I will show you the output now, but we won't discuss it until we discuss our next
program.
roland@linux-c345:~/mega_Mono> javac HelloWorldArray.java
roland@linux-c345:~/mega_Mono> java HelloWorldArray
Hello World!
Second array -910660675 464638207 -841371297 -2115529447 -836877961 2101164408
Sorted output
Array One: 2 6 9 11 46
Array Two: -2115529447 -910660675 -841371297 -836877961 464638207 2101164408

Chapter 1 – Fundamentals
helloworldarray.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

using System;
using System.Collections;
namespace HelloWorldArray
{
class Hello
{
static void Main(string[] args)
{
Console.Out.WriteLine("Hello World!");
int [] ar1 = new int [] {11,6,2,46,9};
int[] ar2;
int[] ar3 = {28, 34, 66, 77, 1, 6, 2};
ar2 = new int [6];
Random gen = new Random();
Console.Out.WriteLine("Second Array");
for (int x=0; x < ar2.Length; x++)
{
ar2[x] = gen.Next();
Console.Out.Write( " " + ar2[x]);
}
Console.Out.WriteLine( "\n\nSorted output");
Console.Out.Write( "Array One: ");
Array.Sort(ar1);
for (int k=0; k < ar1.Length; k++)
Console.Out.Write( " " + ar1[k]);
Console.Out.Write( "\nArray Two: ");
Array.Sort( ar2);
for (int j=0; j < ar2.Length; j++)
Console.Out.Write( " " + ar2[j]);
Console.Out.WriteLine( "");
Console.Out.Write( "\nArray Three: ");
Array.Sort( ar3);
for (int j=0; j < ar3.Length; j++)
Console.Out.Write( " " + ar3[j]);
Console.Out.WriteLine( "");
}
}
}

95

96

Chapter 1 ­ Fundamentals

Just look at how shockingly different C#/Mono is from Java! (cough cough cough)
First we include System.Collections instead of java.util.Arrays.  Next we find that you
cannot put the [] on the right side of a variable name to declare an array reference.   I
added the third array to point out an interesting twist C# allows which currently isn't part
of the Java specification.  Notice how it will automatically create the objects to be stored
in the array without us explicitly telling it to.  I believe this to be a concession to C/C++
programmers who have been used to typing things like:
int x_array [] = {24, 66, 32, 55, 77, 11};

Our next two highlighted lines have little to do with arrays and more to do with just
how drastically different Microsoft made C# from Java.  (cough profusely here!)  Instead
of   the   Java   Arrays.sort()   call   we   call   the   C#/Mono   Array.Sort().     More   importantly
Random doesn't have a nextInt() method like Java, it has a Next() method.
I'm  telling  you, Microsoft  spared no effort when it came to making C# different
from Java!
One   thing   they   did   not   bother   building   into   C#/Mono   arrays   is   the   FORTRAN
ability to start at any base using any step.  While you may not understand it now, when
you are organizing stuff by years and didn't have contiguous years of information, that
was a great tool.
The output of our sample program shouldn't really shock you, or should it?
roland@linux-c345:~/mega_Mono> mcs helloworldarray.cs
roland@linux-c345:~/mega_Mono> Mono helloworldarray.exe
Hello World!
Second Array
1421218565 2116754422 905560231 1579982750 1635971461 1856576989
Sorted output
Array One: 2 6 9 11 46
Array Two: 905560231 1421218565 1579982750 1635971461 1856576989 2116754422
Array Three:

1 2 6 28 34 66 77

Chapter 1 – Fundamentals

97

If you compare this output to the Java output it should be painfully aware that we
didn't obtain any negative numbers.   Java only allows you to set a seed value which
improves   the   distribution  of  random  numbers,  but,  if  you  don't  provide  a  maximum
value on the nextInt() call, any value in the 2^32 range can be returned.  If you provide a
maximum value, the range will be zero and the value provided.
C#, by contracts, starts with a base of zero.  When you call Next() you can pass a
maximum value by itself to cap the return, but the only way to get a  potentially negative
number is to pass both a minimum and maximum value to Next().  While you might not
think much of this now, I can tell you from experience it's a pretty massive difference.
Most of you never test with or trap for negative numbers.  I admire Java for throwing
that monkey wrench into the mix early.

1.10 Programming Assignment 3
You are to write both Java and Mono programs to print out 100 random numbers
without using a seed value.   Run each multiple times and compare the output.   Does
either  Java  or Mono  always  provide  you  the  same  predictable  set  of  pseudo­random
numbers?

1.11 Enums
I'm not a big fan of enums.   Yes, I believe enums have their place, but they are
poorly taught and even more poorly designed.   The problem  is that programmers are
taught   by   the   white   smocked   wearing   OOP   crowd   that   “an   object   should   contain
everything.”  Students then end up creating all of these half­arsed systems that hard code
all aspects of an object in enums then serialize stuff out to flat files.  Students then get
jobs in the real world and get Post Traumatic Stress Disorder when they are told the
company  issuing their  check wants  all  of the data in a relational  database, not some
serialized flat file on their local PC.
Here is the rule:   Unless you are writing a graphics library like Qt or Zinc, never,
under any circumstances, use an enum.

98

Chapter 1 ­ Fundamentals

Enums have been abused and universities have been absolutely wretched when it
comes   to   teaching   proper   production   quality   software   development.     Other   than
graphical user interface primitives which will never be stored in a database, there is no
good reason to use an enum in production.  
Let's take a familiar example, a Polo Shirt in a clothing catalog and walk through the
reasoning.    The  Polo  Shirt  has  a single  base  catalog  item  number  assigned  to  it  for
ordering.  The person placing the order is then asked to choose a size and a color along
with any Monogramming they want done.  What really happens in a production system
is that each size and color option translates either directly or indirectly into the values
completing the actual inventory item number.  An OOP programmer fresh out of school
will create a class Polo Shirt which contains enums for color and size along with an
internal constant for the catalog item number.  In short, they create something worthless.
The entire production system  is going to revolve around a central database.   The
table which is used to generate the catalog, either on­line or in print, will contain the
catalog item code, a short description (item title), a long description, and then either an
image in a blob, or a URL to a stock image.  An inventory table will exist containing one
row for each UPC from the vendor.  Each UPC will be tied to one combination of size
and color for that shirt.  If your vendor is polite, the first N digits of the UPC will be the
same for all items, and the last couple digits will vary sequentially, but don't count on it.
Because   of   this   each   row   in   UPC   table   will   contain   a   repeating   key   column   for
inventory_item   or   inventory_parent_item,   depending   upon   how   your   system   was
designed.  The catalog table will also contain this inventory_parent_item value.
It should be noted here that very old retail, and most direct manufacturer database
and   system   designs   will   be   different.     The   last   10   years   has   seen   a   push   for   every
manufacturer in the world to assign a unique UPC to each and every permutation of their
product line.  Old apparel ordering systems for manufacturers used to simply break up
items by material and pass the size along as information to the piecework ticket because
only the cutter needed to know the size.  I'm sure some systems like that still exist and
may be used internally, but, if you are selling to any of the major retailers, you have

Chapter 1 – Fundamentals

99

some other system which interfaces with them and uses a unique UPC for each possible
combination.
Why has this push happened?   Consider for a moment the Stafford Wrinkle Free
Executive   men's   suit   shirt.     While   it   comes   in   several   colors   and   many   size
combinations, white and blue tend to be the most widely sold with white leading by far.
(Not only is the shirt worn by men with suits, but, many restaurants mandate it or the
Oxford version of it for their female waitstaff.)  When your local J.C. Penny's stocks out
of the white 18” neck 36” sleeve version of this shirt, they don't want to place an order
for   more   white   Wrinkle   Free   Executive   shirts   and   let   the   supplier   guess   at   the   size
because that's how you end up with a store full of 15” necks and 32” sleeves nobody can
fit into.
Inventory management has moved into the 21 st  century.   While many retail chains
still have people with the title “buyer”, they are generally only the buyer of new items.
The vast majority of inventory replenishment happens without any human involvement.
When the sale scanned at the cash register sets the current inventory below the safety
stock quantity the re­order will either occur instantly or with the “nightly” job stream.
Since we must cover enums to be complete, let us return to their discussion.  Unless
you force a starting value for your enum, it will start at zero.  During the days of C/C++
enums used to equate  to integer, they are now their own type and must be cast to a
numeric data type if you wish to use the value.  This may confuse some people because
under C#/Mono each enum must have a “base type”, which by default is int, but can be
any integral type.  You can change the integral type by using a “:” followed by the type
as our example program shows.

100

Chapter 1 ­ Fundamentals

helloworldenum.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

using System;
namespace HelloWorldEnum
{
class Hello
{
enum AutoIgnition :long
{GASOLINE=536, FUELOILNO2=494, ETHYLALCOHOL=689,
METHANOL=878,SULPHUR=470};
static void Main(string[] args)
{
Console.Out.WriteLine("Hello World!");
Console.Out.WriteLine("AutoIgnition values:");
Console.Out.WriteLine("GASOLINE = {0}",
(double)AutoIgnition.GASOLINE);
Console.Out.WriteLine("FUELOILNO2 = {0}",
(double)AutoIgnition.FUELOILNO2);
Console.Out.WriteLine("EHTYLALCOHOL = {0}",
(double)AutoIgnition.ETHYLALCOHOL);
Console.Out.WriteLine("METHANOL = {0}",
(double)AutoIgnition.METHANOL);
Console.Out.WriteLine("SULPHUR = {0}",
(double)AutoIgnition.SULPHUR);
}
}
}

roland@linux-c345:~/mega_Mono> mcs helloworldenum.cs
roland@linux-c345:~/mega_Mono> Mono helloworldenum.exe
Hello World!
AutoIgnition values:
GASOLINE = 536
FUELOILNO2 = 494
EHTYLALCOHOL = 689
METHANOL = 878
SULPHUR = 470

Yes, I provided you with the same kind of bad example you will find all over the
Internet.  Rather than putting data in a database, I used an enum to declare a bunch of
constant values.  Notice that I used a long data type even though all of these values could
have easily fit into an integer.   You also need to note that you cannot use any type of
floating point for an enum, it must be some variant of an integer data type.  Please note
that you can convert an integer into a floating point data type as I did at listing line 17.

Chapter 1 – Fundamentals

101

If you do not provide any values, simply a list of names, the names will have values
starting sequentially with zero and incrementing by one.  I chose to assign every one of
my enums a value.  What happens when you leave some in the middle of unsorted values
without values assigned?

1.12 Programming Assignment 4
Either modify this program or create your own.   Create two different enums, one
with a bunch of numbers assigned before and after in no particular order, but leaving
three   or  four  named   enumerations   without   values  assigned   in   the  middle.    For  your
second enum leave them at the end.  Have your program print out all values like I did.
See what gets assigned by the compiler, and if it even compiles.

1.13 Programming Assignment 5
Enums are just plain weird.  All of the doc you read on­line tells you that they will
default to public access no matter what you do.  Take the programs we created earlier to
test the various access methods and add enums everywhere.   Identify  all  of the places
where the public nature of an enum overrides its enclosing security.

1.14 Properties
Here we have a name which came about simply because marketing wanted a new
buzzword.  In the days of C++ we had member variables.  All member variables were
supposed to be prefixed by “m_” so it was obvious to anyone reading the code you were
talking about a member variable.  Most old timers, myself included, couldn't really bring
themselves to consistently use “m_” in front of our member variables.  Eventually there
were many IDEs which would not only force the thing in front, but would automatically
generate a set and a get method for the variable.  Some shops must have a very strict IDE
combined with a group of former Nazi SS officers heading up the code reviews, because,
yes, all of their code follows “the convention.”  There code is also unreadable.

102

Chapter 1 ­ Fundamentals

Names also started to carry warts.  Actually, most of the warts came from habits of
days gone by.  Any programmer who grew up working with BASIC was used to seeing a
$ at the end of a variable to indicate a string, a % to indicate an integer, and nothing to
indicate   a   floating   point   …   that   is,   at   least   until   we   created   record   definitions   with
gender neutral names.  In BASIC you could change the type of a % from INTEGER to
LONG, but you could not change it to floating point without taking the % off the end,
the  compiler  simply  wouldn't  allow  it.    Windows  programmers  adopted  an  incorrect
interpretation of “Hungarian Notation” for naming their variables.
TCHAR
bool
unsigned long
void*
MyObject**

szMyChar[STRING_SIZE];
bMyBool;
ulMyLong;
pMyPointer;
ppMyObjects;

I have had to read and write I don't know how many lines of stuff which looked like
this over the years.  Some used this naming convention and the “m_” prefix for member
variables.  The longer the variable name, the more unreadable things became.
m_udMaximumDailyWithdrawlLimitForAccount
Isn't that just a lovely read.   Things got a bit uglier when it came to system level
documentation.  You see, DOS/Windows was an OS which was just kind of hacked at
without any real design.  When you work with a real OS which had real design done up
front, you have systems documentation which looks like this:
FDV$GETAL(

OPTIONAL STRING text BY DESC [write],
LONG terminator BY REF [write],
STRING start_field BY DESC [read],
LONG start_index BY REF [read])

Many of you will recognize the above as the language independent documentation
for the FMS GETAL() function as found in the OpenVMS application development book
of this series.   Each line lists the OS native data type, a descriptive name, the passing
mechanism, and in [] at the end, the type of access the function requires to this particular
piece of data.  ( BY DESC means by descriptor which is an OS specific type safe and
secure method of passing parameters.)

Chapter 1 – Fundamentals

103

On lesser  platforms  where  the documentation  creators  were  writing  for only  one
language, it was not uncommon to see an access wart prefixed to the other warts for
parameters.
rw_udMaximumDailyWithdrawlLimitForAccount
Many C++ programmers simply used C++ as a better C.   Since all struct member
variables   had   public   access,   they   simply   declared   all   member   variables   public   and
completely skipped the need for setter and getter methods.
Java tried to improve on by calling each member variable a “class property” and in
some circles they called them object properties reasoning that only static ones could be
called “class properties.”   Further confusion was added by Java when it extended its
Hashtable class to create a Properties class.  The purpose of the Properties class was to
allow   string   pairs   of   “property”   and   “value”   to   be   stored   via   some   semi­permanent
method.
Serious   insult   to   injury   happened   when   the   various   platforms   started   allowing
applications   to   save   application   properties   in   various   locations   and   files.     Each
application would save things like the current window size and position on the display,
color and/or color schema, and various user configuration values.  When you as a user
started the application again it came back up exactly where you closed it down.  In many
cases, especially with test editors, it would even open up the same file and put the cursor
back to the exact same spot you were on with your complete do and undo history loaded.
Microsoft   must   have   combined   the   teams   which   gave   us   Microsoft   Money,
Microsoft   Bob,   and   Windows   Vista   when   they   decided   to   put   together   a   “crack”
technical team to come up with how they wanted to handle properties.   Once you see
what they did with Properties you will readily believe that all Microsoft products have
hideous amounts of code bloat.  Here you declare all of your member variables private,
then  create  a property  with a different  name  which  may provide  a get()  and/or set()
method.    If  the  property  has  only  a get()  method,  it is considered  read­only.   These
methods are now called accessors.  They look weird and function like specialty classes.

104

Chapter 1 ­ Fundamentals

wine.cs
1 using System;
2
3
4
class Wine
5
{
6
private string m_wineType;
7
private string m_wineMaker;
8
private double m_usGlasses;
9
private double m_ukGlasses;
10
11
public string Wtype
12
{
13
get { return m_wineType;}
14
set { m_wineType = value;}
15
}
16
17
public string Maker
18
{
19
get { return m_wineMaker;}
20
set { m_wineMaker = value;}
21
}
22
23
public double Ml
24
{
25
get { return m_ukGlasses * 125.0; }
26
set { m_usGlasses = value / 250.0; m_ukGlasses = value / 125.0; }
27
}
28
29
public double UKGlassCount() { return m_ukGlasses;}
30
public double USGlassCount() { return m_usGlasses;}
31
}
32
33
class Program
34
{
35
static void Main(string[] args)
36
{
37
Console.Out.WriteLine("Hello World!");
38
Wine Chardonnay = new Wine();
39
Wine Merlot = new Wine();
40
41
Chardonnay.Wtype = "Chardonnay";
42
Merlot.Wtype = "Merlot";
43
44
Chardonnay.Maker = "Charles Shaw";
45
Merlot.Maker = "Carlo Rossi";
46
47
Chardonnay.Ml = 750;
48
Merlot.Ml = 5000;
49
50
Console.Out.WriteLine(

Chapter 1 – Fundamentals
51
52
53
54
55
56
57
58

105

"You have {0} US glasses of {1} Chardonnay",
Chardonnay.USGlassCount(), Chardonnay.Maker);
Console.Out.WriteLine(
"You also have {0} UK glasses of {1} Merlot",
Merlot.UKGlassCount(), Merlot.Maker);
}
}

roland@linux-c345:~/mega_Mono> mcs wine.cs
roland@linux-c345:~/mega_Mono> Mono wine.exe
Hello World!
You have 3 US glasses of Charles Shaw Chardonnay
You also have 40 UK glasses of Carlo Rossi Merlot

You   may   find   it   difficult   to   believe,   but   a   lot   of   effort   went   into   creating   this
example.     I   needed   to   show   you   both   the   good   and   the   bad   when   it   comes   to   this
philosophy.  In real life applications you will need to keep multiple private members in
lock step from a single transaction.  Yes, I could have redesigned this to store milliliters
and   done   the   conversion   on   the   output,   but   that   would   have   robbed   you   of   a
programming assignment.  
What if this was a real inventory object where it needed to track OnHand, OnOrder,
BackOrdered,   CustomerBackOrdered,   MTDUnitsSold,   and   36   months   of   prior   sales
history?  I've done many inventory management systems in my day and if you plan on
doing anything remotely resembling order forecasting or inventory management that's
the least of the information you need.  A single customer order will need to either reduce
OnHand while increasing MTDUnitsSold, or it will increase CustomerBackOrdered, or
it could actually manipulate all three if you only had enough inventory on hand to do a
partial fill.  This “philosophy” of Properties and accessors Microsoft is foisting upon us
has some incredibly short­sighted flaws.

106

Chapter 1 ­ Fundamentals

1.15 Programming Assignment 6
Part 1: Create a constructor for the Wine class which requires both the wine type and
maker to be provided.   Remove the set portions of the accessors for these two values.
Make the object store only milliliters for inventory and do the count conversions in the
appropriate methods.  
Part   2:   After   you   get   the   above   working,   add   methods   to   clear   the   milliliter
inventory and to increment it.   Change the test program to feed in a various milliliter
amounts from various bottles as you would when counting inventory, then print out both
glass counts for both wine types.
Part   3:   Declare   a   private   default   constructor   for   the   Wine   class.     Retest   your
program.   Does everything still work correctly or do you need to call the now private
default constructor at the start of your constructor?

1.16 Parameter Passing
We've been passing parameters to methods for a while, but I've tried to keep it to a
minimum.   The cleanest way for me to explain this would be to cover only C# at this
time then sprinkle in some ugly stuff at the end for seasoning.
C# always defaults to passing by value, but the value it chooses isn't what you may
be thinking of as a value or the value.
Take a moment and really chew on that statement.
I'm serious.  There are many bad descriptions and definitions floating around on the
Web when it comes to C# parameter passing.  Worse yet, you will find many “clever”
descriptions   which   are   “legally”   correct,   but   not   in   the   best   interest   of   a   new
programmer.

Chapter 1 – Fundamentals

107

Sections   1.2   and   1.3   of   this   chapter   spent   quite   a   bit   of   time   talking   about   the
hard/native/primitive/value   data   types,   structures,   and   classes.     Structures   were
originally used to forme organized collections of primitive data types much like records.
Under C# they have morphed into something resembling light weight classes with one
critical difference.   A struct is still considered a value data type despite its class­like
syntax and capabilities.
Surf  around  the Web and  you will find  many places  stating  that value  types  are
passed   by   value   and   objects   are   passed   by   reference.     You   will   even   find   sample
programs “proving” the statement.  Here's the truth:
Wine Chardonnay = new Wine();

Chardonnay is a reference to an instance of a Wine object which was created by the
new operator.  Chardonnay is passed by value by default.  Because it is a reference, the
method/function receiving it references the object instance created by new.    If we were
to explicitly pass Chardonnay by reference, we would be passing  a reference of this
reference.   We could actually change the object Chardonnay referenced in our called
method   or   function   if   we   pass   Chardonnay   by   reference.     When   the   reference
Chardonnay is passed by value the caller can only use or modify various portions of the
object to which Chardonnay refers.   This explanation holds true for all objects except
strings.  C#/Mono really buggered string handling.
If you are shiny new to programming that last example is a lot to chew.   If you
started out programming in C with pointers, then had references added by C++ only to
have pointers taken away by Java, this isn't so much for you to swallow.  It's a road well
traveled, just with different signs on it now.  During the days of C, we had only pointers.
Unlike C++, neither C# nor Java support default parameter values.  Both languages
lost the ability when they tossed header files out of their language specification.  In C++
the compiler uses the prototype to fill in default values which will be used at run time.
Both C# and Java require a developer to create default parameter values by overloading.
The overloading practice is error prone and quite confusing.

108

Chapter 1 ­ Fundamentals

test_ptr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

#include <stdio.h>
void change_it( int **a, int *b) {
*a = b;
}
void assign_it( int *a, int b) {
*a = b;
}
int main(){
int *x_ptr, x, y;
x_ptr = &x;
assign_it( x_ptr, 21);
printf( "x after first call %d\n", x);
assign_it( &x, 33);
printf( "x after second call %d\n", x);
y = 1;
change_it( &x_ptr, &y);
printf( "x after third call %d\n", x);
printf( "*x_ptr after third call %d\n", *x_ptr);
return 1;
}

roland@linux-c345:~/mega_Mono> gcc test_ptr.c -o test_ptr
roland@linux-c345:~/mega_Mono> ./test_ptr
x after first call 21
x after second call 33
x after third call 33
*x_ptr after third call 1

The interesting portion of this code is the parameter list for the two subroutines,
change_it() and assign_it(), found at listing lines 3 and 7.  You will notice that the actual
code inside each subroutine is identical, but, as you can see from the output, drastically
different things happen when the subroutines are called.  (Any function which does not
return a value is called a subroutine when programming in C.)  We pass a pointer to a
pointer as the first parameter in change_it().   When we subsequently change the value
the pointer points to (remember * means “value at”) what we are really changing is the
pointer in our main module.  C# has this same issue if you force a reference.  It just has
trouble with strings.

109

Chapter 1 – Fundamentals
test_ref.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

using System;
class TestRef
{
void change_it( string a, string b) {
a += b;
Console.Out.WriteLine( "\ta from inside of change:
}

{0}",a);

void assign_it( ref string a, string b) {
a = b;
}
static void Main(string[] args)
{
string str1 = "original";
string str2 = str1;
TestRef t1 = new TestRef();
t1.change_it( str1, " and still the best");
Console.Out.WriteLine( "str1: {0}", str1);
Console.Out.WriteLine( "str2: {0}", str2);
t1.assign_it( ref str1, "New and Improved");
Console.Out.WriteLine( "str1 after assign_it: {0}", str1);
Console.Out.WriteLine( "str2: {0}", str2);
t1.change_it( str1, " but we kept what you liked");
Console.Out.WriteLine( "str1 after change_it: {0}", str1);
Console.Out.WriteLine( "str2: {0}", str2);
}
}

roland@linux-c345:~/mega_Mono> mcs test_ref.cs
roland@linux-c345:~/mega_Mono> Mono test_ref.exe
a from inside of change: original and still the best
str1: original
str2: original
str1 after assign_it: New and Improved
str2: original
a from inside of change: New and Improved but we kept what you liked
str1 after change_it: New and Improved
str2: original

110

Chapter 1 ­ Fundamentals

We need to talk about two things here.  First, when you want to pass a parameter by
ref you have to actually use the ref (or out) keyword as shown on listing lines 11 and 24.
C# is not like C++ when it comes to references, it will not automatically create one for
you.  The second thing to notice is that we really only got a copy of the string.  Every
shred of documentation I can find says string is a reference data type, but this certainly
isn't reference behavior as is shown by the highlighted output lines.
What happens when you use a real reference class/object?
TestClassRef.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

using System;
class TestClass
{
public string txt;
}
class Program
{
void change_it( TestClass a, string b) {
a.txt += b;
Console.Out.WriteLine( "\t from inside of change:
}
void assign_it( ref TestClass a, TestClass b) {
a = b;
}
static void Main(string[] args)
{
TestClass tc1 = new TestClass();
TestClass tc2 = new TestClass();
TestClass tc3 = new TestClass();
Program p1 = new Program();
p1.change_it( tc1, "Original");
p1.change_it( tc2, tc1.txt);
p1.change_it( tc3, "spare parts");
Console.Out.WriteLine( "tc1 {0}", tc1.txt);
Console.Out.WriteLine( "tc2 {0}", tc2.txt);
Console.Out.WriteLine( "tc3 {0}", tc3.txt);
p1.assign_it( ref tc1, tc3);
Console.Out.WriteLine( "After assign_it");
Console.Out.WriteLine( "tc1 {0}", tc1.txt);
Console.Out.WriteLine( "tc2 {0}", tc2.txt);

{0}",a.txt);

Chapter 1 – Fundamentals
38
39
40
41
42
43
44
45
46
47
48
49
50
51 }

111

Console.Out.WriteLine( "tc3 {0}", tc3.txt);
p1.change_it( tc1, " but we kept what you liked");
Console.Out.WriteLine( "After change_it");
Console.Out.WriteLine( "tc1 {0}", tc1.txt);
Console.Out.WriteLine( "tc2 {0}", tc2.txt);
Console.Out.WriteLine( "tc3 {0}", tc3.txt);
p1.assign_it( ref tc1, tc2);
Console.Out.WriteLine( "After assign_it");
Console.Out.WriteLine( "tc1 {0}", tc1.txt);
Console.Out.WriteLine( "tc2 {0}", tc2.txt);
Console.Out.WriteLine( "tc3 {0}", tc3.txt);
}

roland@linux-c345:~/mega_Mono> mcs TestClassRef.cs
roland@linux-c345:~/mega_Mono> Mono TestClassRef.exe
from inside of change: Original
from inside of change: Original
from inside of change: spare parts
tc1 Original
tc2 Original
tc3 spare parts
After assign_it
tc1 spare parts
tc2 Original
tc3 spare parts
from inside of change: spare parts but we kept what you liked
After change_it
tc1 spare parts but we kept what you liked
tc2 Original
tc3 spare parts but we kept what you liked
After assign_it
tc1 Original
tc2 Original
tc3 spare parts but we kept what you liked

Our first class simply has a string member  element (or property if you insist on
using the new lingo.)  Because we created this class without deriving it from any other
class,   any   declarations   of   it   will   be   an   honest   to   goodness   reference   without   any
qualifiers spelled out in fine print like the string class has.

112

Chapter 1 ­ Fundamentals

Notice that our Program class now contains the methods for changing and assigning.
Instead   of   strings,   most   of   the   parameters   are   now   an   instance   or   reference   of   our
TestClass.  We still only force a reference with the assign_it() method, but look at the
difference in output!  The first call assigning tc3 to tc1 really did change the reference.
We know this because the later change_it() call involving tc1 actually changed the value
in tc3! The final assignment of tc1 to tc2 proves beyond a doubt we really changed tc3.
What about that object we created originally for tc1?   It's just floating around out
there waiting for our application to run long enough that garbage collection finds it, or
that our entire region is wiped when our program  ends.   C#/Mono  doesn't give us a
method of deleting it under program control.  It does provide the IDisposable Interface
which would let our class implement Dispose(), however, that method is supposed to be
used   for   releasing   non­managed   resources.     It   does   not   actually   free   the   managed
memory used by the object instance.  (* see next section)
In short, the  String  class lugied  up parameter  passing  because  Microsoft  tried to
make   C#/Mono   easier   to   learn   for   newbies.     While   String   is   a   reference   class,   the
equality and inequality operators were overridden to compare object values instead of
object references.  If you come from a C++ or Java background, you have gotten used to
String  being a class  which  operates  like  all other  classes.    Since  Microsoft  wants to
dumb down the IQ level required for programming, they made the class String behave
somewhat like a native data type.
This is a throwback to the days of BASIC PLUS on the PDP 11/70 under RSTS/E.
This early version of BASIC allowed a user to create a string variable by simply coding:
200 B$ = “My String”

Uber Geeks of the day actually knew that the first byte of a BASIC string would
store an unsigned binary integer containing the length of the string and the rest of the
characters would occur sequentially behind that byte in memory like an array.  Dynamic
strings couldn't be more than 255 bytes back then, but the programmer got to use a string
as a “native” data type.

Chapter 1 – Fundamentals

113

1.17 Garbage Collection, Destructors, and GUI Toolkits
The previous section contains the mantra beginners are taught to recite from day
one.  They are supposed to let the C#/Mono environment make all object destruction and
resource releasing decisions.  Yes, there are command line arguments which allow a user
to change the garbage collection engine, boundary separator, and even the size of the
nursery where objects are created, but a pure C#/Mono developer is never supposed to
do anything with garbage collection.
Would you be shocked to learn that Dot Not 1.1 added the IDisposable Interface
along with the Dispose() method on top of class finalizers?  I thought not.  The Dispose()
method combined with a finalizer is a real house of cards.   In most cases if you have
Dispose() you should call GC.SuppressFinalize( this).  Why?  Because there should be
no external resources left to release once Dispose() is done.
Why did Microsoft have to bow to the industry?  Because no matter how great your
garbage collection algorithm, once an object needed “unmanaged resources” or pinned
memory for use by entities outside of the environment, there is no method of defining
“done” until the program is complete.  When dealing with database interfaces that could
return thousands of rows which had to be translated into local space, it soon became
obvious that garbage collection combined with a dynamically expanding VM couldn't fix
this problem.
One   of   the   biggest   tools   employed   by   the   various   garbage   collection   engines   is
relocation.  When dealing with managed resources, the collection engine is free to move
or   pack   all   of   the   existing   objects   together   to   free   up   a   large   or   larger   contiguous
memory region for object creation.   When memory in this region is pinned because it
was used to transfer data either into or out of a database buffer, that memory cannot be
moved for the life of the program unless the programmer has a method of informing the
environment they are done with the memory.

114

Chapter 1 ­ Fundamentals

Thanks   to   C#/Mono   being   a   Java   clone,   a   programmer   cannot   directly   call   an
object's destructor or finalizer.   A call to Dispose() is considered lighter weight than a
call to a finalizer.  In truth it should be.  Only free resources allocated outside of the VM
and pinned memory in your Dispose() method.   Everything else will automatically be
taken care of by the environment when the time comes.  We don't have a good method of
telling  the  environment  we  are  done  with  a  C#/Mono  object,  so  freeing  up  physical
resources is the best we can do.
Depending upon which collection engine you select and the parameters you provide
on   the   command   line,   garbage   collection   may   very   well   run   before   each   and   every
allocation.  I can tell you from experience that you definitely do not want that to happen
if   your   program   has   any   size   or   does   anything   real.     The   run­time   becomes
excruciatingly long.
Much like the Java JNI kit, C#/Mono provides us with GC.Collect().   You do not
ever want to invoke this in your application.  If there is even the slightest instability with
how you or a third­party library handle external resources, calling this method is a stack
dump waiting to happen.  You need to immediately call GC.WaitForPendingFinalizers()
which will release control to the threads which have an object identified for garbage
collection.
You may have noticed that I have yet to create a destructor for you.  Eventually I
will, but not right now.  A developer needs to create a destructor for a C#/Mono class
only when they allocate resources outside of the run­time environment.  Whenever you
open a file on disk via a non­C#/Mono tool, connect to a database, allocate a port, call
OS   native   services,   etc.  you   need  to   create  a   destructor  for  your  class  to   ensure  all
resources are released back to the OS.  The Mono/C# environment is not going to make
any attempts at releasing your external resources until after your program completes or it
absolutely has to due to the age and size of the object which allocated them.

Chapter 1 – Fundamentals

115

Many of you new to the field will be shocked to hear this, but one of the main
decision points when choosing a GUI toolkit is how well it cleans up after itself.  I know,
most of you will be clamoring that it should be based on features, or the “look & feel”
being consistent with whatever you are currently using, but that would be the reason
MBAs and newbies choose toolkits.  The professional developer chooses a toolkit based
upon how easy it makes his or her programming life and how well it stops bugs from
getting to production.
If you have  done any programming  in the C++  world  within  the past  five  years
you've been hearing about a toolkit called Qt which is now owned by Nokia.  This toolkit
has both  an Open Source  and a commercial  version.   The Open Source  version  was
chosen to be the main library used by the K Desktop developers (more commonly called
KDE developers) which added thousands of developers to the Qt product the second the
decision was made.  Trolltech, the owners at the time, were very receptive to the Open
Source community so a large amount of code produced by that community made it into
the base toolkit.
It's not fair to call Qt a GUI library.   It is a complete  application toolkit having
generic classes for flat files and direct support for many database formats along with a
great screen/forms designer.   The only thing it doesn't have right now, but I'm told is
being worked on, is a report writer component like that of COBOL.
With   all   this   time   spent   singing   the   praises   it   should   not   surprise   you   that   two
different  Mono­Qt packages  exist.    The first  is Qyoto.   This is put  out  by  the  KDE
developers and has exceptional support for Doxygen.  The second is Qt4Dotnet and it is
based on the QtJambi Java bindings which are officially supported by Nokia.
I   don't   see   these   two   particular   tools   ever   merging   while   Qt   is   still   actively
developed.  When Qt4 was coming out it was a massive change from Qt3.  Even with
backward  compatibility  turned  on, most Qt3­based programs  ceased  to function.   As
KDE gets more and more components it will take longer and longer to fully migrate to a
new Qt release.  Thus it makes sense to have two different Qt usage libraries.

116

Chapter 1 ­ Fundamentals

Besides the invention of signals & slots, Qt added a level of application stability the
industry has never before seen with a toolkit.   The root object/class which is used to
derive all other classes under it keeps track of all classes which are derived from it and
instantiated.  The destructor for this object walks down that list at program conclusion
and nukes everything which has to do with the Qt library.
Some of you may think it is no big deal that a GUI library cleans up behind itself,
but Qt is an Application development library.  It has classes for flat files, hashed files,
databases and more.  I have tested it many times and covered it in “The Minimum You
Need to Know About Qt and Databases,” so I can tell you with complete honesty that Qt
really   does   close   all   connections   and   clean   things   up   quite   well.     Given   the   design
philosophy supposedly behind C#, that it should clean up behind a programmer and stop
all resource/memory leaks from happening, Qt fits in quite nicely.
Gtk#   is   the   C#   GUI   toolkit   in   widest   use   today.     That   is   also   the   toolkit
MonoDevelop (the Open Source Mono IDE) is written with.  Gtk is the default Gnome
toolkit, but the Ubuntu Gnome developers have made a public decision to use Qt from
now on.  Qt has the ability to emulate the native look and feel on any target platform, so
you really can write once and compile for all targets.  (Yes, you can force a custom look
and feel and maintain it on all targets if you wish.)
If you want to plan for the future, you will use one of the Qt­based toolkits.   The
only  downside  is that signals  and slots  have not  been fully  ported  to the DOT NOT
environment at the time of this writing.  The upside is that your application will have a
native look and feel no matter what platform it runs on.

Chapter 1 – Fundamentals

117

1.18 Namespace vs. Package
After the brutal onslaught of information I've provided in this chapter this section
will   seem   rather   anti­climactic.     For   the   most   part,   a   namespace   and   a   package   are
simply  a  way  of  grouping  definitions  into  controllable  entities:  Either  allows  you  to
import a single class/item or the entire group.   The only real difference is the naming
convention for Java dictates the directory and JAR structure because the JVM uses the
actual name as a path when it goes hunting through its directories and JARS.  
C# simply uses the name when it goes rummaging through the DLLs it knows about.
Remember our prior examples.  We had to link every DLL and SO specifically.  Your
EXE file already knows exactly which file it wants and first looks in the same directory
as the EXE, then the few other places it knows about.

1.19 Statements and Style
I'm not going to waste a lot of paper covering the same logic and control statements
we will be using extensively in the example programs.  This isn't a syntax reference, it's
a  jump  start  for  skilled  programmers.    Suffice  it to  say  that C#/Mono  has  the same
while(), do while(), and for() loops we are used to using with a subtle twist or two.  It has
the same if statements and switch statements, just no fall through on the cases.
Most importantly, you should never, under any circumstances use the following:
a = (b > 0) ? b : 0

This is very bad coding style and there is simply no excuse possible for it.  If you
want to hack out code that looks like the worst Perl ever written, then please, go work in
Perl and leave us alone!
Another statement you may find in code is the “null­coalescing” operator.   I may
actually have to thank someone at Microsoft for creating this operator.  It removed most
of the ugly reasons people used to justify the decision operator (?:) that we just discussed
and makes code a bit more readable.  When you aren't working with reference types the
syntax can be a bit freaky, especially for C++ programmers.

118

Chapter 1 ­ Fundamentals

int? k = null;
int j = k ?? -2;

In part, I'm not certain I like the idea of using an operator to extend the valid range
of values for a native data type, but, I can see the point.  They most likely keep a special
flag which gets set when you declare “int?”.  The freaky part is that C++ programmers
used to declare reference variables by placing & at the end of the datatype, so a quick
read could lead to confusion.
If you programmed in Java, you are used to seeing syntax like this:
for( float j : studentGradeArray)
sum += j;

Well, C# changed the syntax:
foreach( float j in studentGradeArray)
sum += j;

I'm sympathetic to the new verb, but, if you do much embedded SQL or many stored
procedures, you will begin having difficulty as foreach exists there, but has different
syntax.
We might as well finish this section by stating that C# has the same try­catch­finally
error handling structures that both C++ and Java had.

Chapter 1 – Fundamentals

119

1.20 Summary
C#/Mono came to us out of a flurry of legal battles and heated words in the press
between  two large  corporations.   Microsoft,  having  read the  writing  on the wall and
realizing it had less than 10 years left as a corporation, desperately tried to bind the
wildly popular Java platform to its legacy Windows platform (which started out as the
Windows Application under DOS, despite the fraudulent package labeling) to squeeze
out a few more years of corporate earnings.  Microsoft lost its legal battles and quickly
rebadged   its   Java  compiler   as   C#,  tweaking   a  few   things  here   and  there.    To  make
Internet development easier they also created a tool set called .NET which much of the
industry pronounces DOT NOT just to tweak them.
It  should  be noted  that  a  few of  the  more  famous  Microsoft  people  are  pouring
money,  information,  and  resources  into  the  Mono  project.    Windows  will  soon  be a
memory in the IT world, like Wang, Singer, and Xerox Park, but unlike them, will not
have left its mark on the industry unless Mono survives on the new desktop platforms
and  gets   migrated  to  the   mainframe   platforms  (which  are   now   your  robust  database
server platforms.)
Since   Java   has   the   feeling   it   was   written   by   SUN   so   they   could   make   use   of
programmers that couldn't learn all of C++, it should come as no surprise that Java stole
heavily from C++ which absolutely thieved from C.  C#, being a massive clone of Java,
then, by extension, also thieved from C and stole heavily from C++.   The justification
you will hear time and time again is that each creator wanted their language/tool to be
quickly   adopted,   so,   it   had   to   mimic   the   syntax   of   the   most   popular   programming
language on the planet at the time.  Keep in mind “most popular” != “most lines of code
in production” != “most core business systems written in”.  Despite all of the marketing
dollars spent to try and change it, “Most lines of code in production” honors still belong
to COBOL and will at least until Y3K.

120

Chapter 1 ­ Fundamentals

Hopefully C#/Mono will be the last blatant rip­off we see of the C language.  Before
you all get up in arms remember that I've been in this industry since before C burst onto
the scene.   Yes, I've written mountains of code in it and enjoyed much of it.   My pet
peeve is that now every language looks the same and it is getting extremely difficult for
language   syntax   highlighters   to   be   developed   for   text   editors.     You   are   one   or   two
language rip­offs away from losing all of your good tools.
Today, when you see a snippet of code in a magazine article, you actually have to
read the article to find out what language they are using, unless you happen to see one of
the key differences:

Java uses System.out.println() while C#/Mono uses Console.Out.Writeline() and
C++ uses something like out << but could also use the C printf() statement and
its variations.  

C++ uses a “;” after the closing } for a class definition, but neither Java nor C#
do.  

C++ and C# have pointers, though they are declared differently, but Java does
not.

C#, to date, is the only one of these languages with the null coalescing operators
of ? And ??.

Only C++ supports default parameters in a single method declaration.

Yes, there will be many other subtleties if you are really paying attention, but just
how often are people paying that close of attention to a snippet in a magazine?
Until recently Mono had the severe limitation of only supporting the Gtk# interface.
While this made for natural looking applications on the Gnome desktop, it made for
some odd looking stuff everywhere else.   Thankfully there have been efforts to bring
forth Qt which emulates the native look and feel of every platform it runs on unless you
physically force it to have a different look and feel.

Chapter 1 – Fundamentals

121

C#/Mono  has  some  incredibly  weird  default  protection  rules.    Default  protection
within a class or struct is  private, but within a  namespace  is  internal.   With C++ the
default protection within a class is private but within a struct is public.  C++ does not
have   a   default   namespace   level   protection.     When   it   comes   to   Java,   the   default   (no
modifier) protection level is “package­private.”
In short, the confusion you feel is real.  These languages are so similar in syntax that
it is nearly impossible to try learning all three within a short period of time.   Until Qt
entered   the   world   of   C++,   most   veteran   C++   programmers   did   not   use   an   IDE
(Integrated   Development   Environment.)     When   Mono   entered   the   scene,   and   IDE
became mandatory, but now that Qt is available for Mono, we are back to being able to
use regular editors again.

1.21 Exercises
1. When you finish declaring a class, does C#/Mono require you to end it with a
";"?
2.  What bitwise operator does Mono have that C++ does not?
3. What is the smcs command used to create?
4. What main difference is there between a class and a stuct in C#/Mono?
5. What programming language has the most lines of code in production today?
6. There   is   only   one   C#/Mono   protection   level   which   cannot   be   accessed   by   a
derived class in the same compilation unit, what is it?
7. Where must you declare a constant in Mono?  In C++?
8. Who puts out Qyoto and what is it?
9. What is the maximum positive value a 16­bit signed binary integer can hold?
10. When you want the mcs command to create a library, what 2 (two) switches
must be used?

122

Chapter 1 ­ Fundamentals

11. What does LITTLE_ENDIAN mean?
12. In Mono, what happens with this equation if m is 7:  (m++ == 7) || (n++ == 4);
13. Does C#/Mono allow you to drive a struct from another struct?
14. Do   Mono   and   C   use   the   same   data   type   for   Double   when   using   the   GNU
compiler on Linux?
15. What is the "null­coalescing" operator?
16. What is returned by a call to Java nextInt() when you don't provide a maximum
value?
17. What is Packed Decimal?
18. What   is   the   only   reliable   method   of   transfering   C#   Decimal   data   between
machine types?
19. What does: int*  x1, x2, x3; declare in Mono?  In C++?
20. What are the two methods of "pinning" a memory allocation to actual physical
memory?
21. Can you declare both pointer variables and entity variables in the same Mono
declaration?
22. How do you raise a number to a power in Mono?  In C++?
23. What is the default protection for C#/Mono things declared outside of a class or
struct but within a namespace?
24. What is the C#/Mono rule of thumb when it comes to default protection?
25. What source code documentation tool should you be using with C#/Mono?
26. What is the default storage format for MySQL on most platforms?
27. Does C#/Mono provide native indexed file support?

Chapter 1 – Fundamentals

123

28. If   you   read   and   write   data   to/from   its   source   via   SQL   does   that   mean
transactions must be supported?
29. What is the default protection for C#/Mono  declarations  occuring inside of a
class or stuct?
30. How is "Protected Internal" really read?
31. If you declare your C#/Mono class public, can you declare your setter methods
private?
32. What C#/Mono protection level do you assign when you only want other class
members to have access to an item?
33. What   system   method   must   immediately   follow   the   call   to   force   garbage
collection?  Why?  What does this method do?
34. How  do  you   indicate   which  library   or   libraries   you   wish  to  use   on   the   mcs
command line?
35. What   one   file   does   the   Mono   run­time   automatically   look   for   in   the   same
directory as the executable file?
36. What is the syntax for a loop which processes each element of a float array?
37. In Mono, how do you prototype  a C fuction  named  amort_1()  which returns
double and exists in MyLib?
38. What is returned by a call to Java nextInt() when you do provide a maximum
value?
39. What does C#/Mono call get() and set() methods for properties?
40. Does C#/Mono support default parameters?
41. What kind of data type does C#/Mono consider a struct?
42. When writing a function in C++ which will be called from Mono, how must you
declare it?

124

Chapter 1 ­ Fundamentals

43. If   your   class   implements   IDisposable,   what   system   call   should   be   in   your
Dispose() method?
44. Should a class have both a Dispose() method and a finalizer?  Why or why not?
45. What benchmark does a developer use to choose a GUI or other toolkit?
46. What does the ­fPIC switch tell the GNU compiler to do?
47. What single act makes most C#/Mono code nonportable?
48. Where must the [] be placed when declaring an array in Mono?
49. Who puts out Qt4DotNet and what is it?
50. When must you create a destructor for your class?
51. How do you force passing a parameter by reference?
52. Does C#/Mono allow you to change the base data type of an enum?
53. What should your Dispose() method do?
54. What is the primary method of Qt object communication/interaction?
55. What is the only way to potentially get a negative number from the Mono Next()
function?
56. What system call does C#/Mono provide to force garbage collection?
57. What is the default parameter passing method of C#/Mono?
58. When must you implement IDisposable and include a Dispose() method in your
class?
59. What 3GL programming language  has a Report Writer written  into its ANSI
standard?
60. What  is one of the biggest  tools  employed  by the various  garbage  collection
methods?  Why?

Chapter 1 – Fundamentals

125

61. When a parameter declaration calls for a reference instead of a value, will C#
automatically convert a value like C++?
62. Given the following: Wine Chardonnay = new Wine();  What is Chardonnay?
63. What is the only method of implementing default parameters in C#/Mono?

You have been reading a preview. To learn more about this award
winning book series and find out how to purchase works by this author
please visit http://www.theminimumyouneedtoknow.com