Programming vs. Engineering vs. Mathematics.

20 June, 2008 (17:28) | Programming, Humor | 0 comments

An experiment was conducted in order to study the differences between programmers, engineers, and mathematicians. One programmer, one engineer, and one mathematician were all locked in separate classrooms for one week. Each classroom contained all of the normal things you’d find in a classroom: chalkboard, chalk, desks, etc. In addition to that each classroom contained water, one can of food (enough to feed a person for a week), but no can opener. At the end of the week, they opened the programmer’s door first. The programmer walked out. When they looked in the classroom they saw the can beat to hell, but opened. When they opened the engineer’s door, the engineer walked out. In the classroom were a bunch of equations and diagrams written on the board, one small dent in the can which was all that was required to open it. Lastly they opened the mathematician’s door. No one came out. They looked in and saw the mathematician laying dead on the floor, the can of food untouched, and a long series of equations on the chalkboard. But at the end of the equations was written the phrase: “A solution exists”.

Getting your extension to work with Firefox 3.0

18 June, 2008 (13:20) | JavaScript, Programming | 0 comments

When you develop a Firefox extension you’re required to specify the minimum and maximum versions of Firefox which your extension is known to work with. This is done by specifying a minVersion and maxVersion in the install.rdf file inside your plugin’s archive. Since my ClearSkyPlugin isn’t likely to break in any future version of Firefox, I attempted to bypass the version checking by setting the minVersion to 1.0, and the maxVersion to 9.0.
Of course, today Firefox 3.0 was released and my extension was detected as incompatible. After some twiddling I managed to figure out I had to set the minVersion to 1.0.* to get things to work.

If you’re having trouble getting your downloaded extensions to work, you might just disable extension version checking altogether.

Simple speach example in C#.

12 May, 2008 (15:57) | .Net, Snippets | 0 comments

This uses reflection to avoid the clerical task of adding a project reference:

System.Type t = System.Type.GetTypeFromProgID("SAPI.SpVoice");
object o = System.Activator.CreateInstance(t);
t.InvokeMember("Speak", System.Reflection.BindingFlags.InvokeMethod, null, o, new object[] { "test", 0 });

If you don’t mind adding a reference, then the whole thing can be done in one line:

new SpeechLib.SpVoice().Speak("This is a test", SpeechLib.SpeechVoiceSpeakFlags.SVSFDefault);

Beware of System.nanoTime() in Java

25 April, 2008 (16:45) | Java, Programming | 0 comments

The documentation for System.nanoTime() (and the function’s name itself) leads developers to believe it’s a much more accurate timer than anything else Java provides. Depending on which set of documentation you read, it claims to use “the most precise available system timer”. While I can’t speak for any architecture other than x86, I can state that System.nanoTime() is broken for multi-CPU or multi-core x86 systems, and generally unreliable on all x86 systems. The problem lies in the RDTSC instruction which retrieves the number of CPU ticks since the CPU started. On multi-core systems, each core will have its own tick count, and they will not match, so every time your process switches CPUs, you get a different measurement. The issue is compounded by the fact that some power management systems actually alter the CPU’s frequency to save power, which breaks the functionality even on single core, single CPU systems.

In general, do not use System.nanoTime() in any program which you don’t plan to strongly control how it is run, and the environment it is run in.

Implementation of DES in C

16 March, 2008 (23:31) | Cryptography, Security, Code | 0 comments

Below is an implementation I did of DES back in the early 90’s while I was still in college. It’s one of the first complex C programs I wrote. It served its purpose back in the day, but now more advanced algorithms and APIs have eliminated the need for such things. It’s been heavily optimized, more so than is practical in today’s world, so you probably couldn’t get it to compile even if you wanted to use it. I post it here to reminisce on my programming ability at the time, and to give an example of the complexity/simplicity of implementing an encryption algorithm.

    1 #include <stdio.h>
    2 
    3 static int keyout[17][48];
    4 
    5 void des_init(),lshift(),cypher(),des_encrypt(),des_descrypt();
    6 
    7 void des_init(unsigned char *key){
    8  unsigned char c[28],d[28];
    9  static int pc1[56] = {57,49,41,33,25,17,9,
   10               01,58,50,42,34,26,18,
   11               10,02,59,51,43,35,27,
   12               19,11,03,60,52,44,36,
   13               63,55,47,39,31,23,15,
   14               07,62,54,46,38,30,22,
   15               14,06,61,53,45,37,29,
   16               21,13,05,28,20,12,04};
   17  static int pc2[48] = {14,17,11,24,1,5,
   18               3,28,15,6,21,10,
   19               23,19,12,4,26,8,
   20               16,7,27,20,13,2,
   21               41,52,31,37,47,55,
   22               30,40,51,45,33,48,
   23               44,49,39,56,34,53,
   24               46,42,50,36,29,32};
   25  static int nls[17] = {
   26   0,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
   27 
   28  static int cd[56],keyb[64];
   29  static int cnt,n=0;
   30  register int i,j;
   31 
   32  for(i=0;i<8;i++) /*Read in key*/
   33   for(j=0;j<8;j++) keyb[n++]=(key[i]>>j&0×01);
   34 
   35  for(i=0;i<56;i++) /*Permuted choice 1*/
   36   cd[i]=keyb[pc1[1]-1];
   37  for(i=0;i<28;i++){
   38   c[i]=cd[i];
   39   d[i]=cd[i+28];
   40  }
   41  for(cnt=1;cnt<=16;cnt++){
   42   for(i=0;i<nls[cnt];i++){
   43    lshift(c); lshift(d);
   44   }
   45   for(i=0;i<28;i++){
   46    cd[i]=c[i];
   47    cd[i+28]=d[i];
   48   }
   49   for(i=0;i<48;i++) /*Permuted Choice 2*/
   50    keyout[cnt][i]=cd[pc2[i]-1];
   51  }
   52 }
   53 
   54 static void lshift(unsigned char shft[]){
   55  register int temp,i;
   56 
   57  temp=shft[0];
   58  for(i=0;i<27;i++) shft[i]=shft[i+1];
   59  shft[27]=temp;
   60 }
   61 
   62 static void cypher(int *r, int cnt, int *fout){
   63  static int expand[48],b[8][6],sout[8],pin[48];
   64  register int i,j;
   65  static int n,row,col,scnt;
   66  static int p[32]={
   67     16,7,20,21,29,12,28,17,1,15,23,26,
   68      5,18,31,10,2,8,24,14,32,27,3,9,
   69     19,13,30,6,22,11,4,25};
   70 
   71  static int   e[48] = {32,1,2,3,4,5,
   72               4,5,6,7,8,9,
   73               8,9,10,11,12,13,
   74               12,13,14,15,16,17,
   75               16,17,18,19,20,21,
   76               20,21,22,23,24,25,
   77               24,25,26,27,28,29,
   78               28,29,30,31,32,1};
   79 
   80  static char s[8][64] = {
   81     14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7, /*s1*/
   82      0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
   83      4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
   84     15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13,
   85     15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10, /*s2*/
   86      3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
   87      0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
   88     13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9,
   89     10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8, /*s3*/
   90     13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
   91     13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
   92      1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,
   93      7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,/*s4*/
   94     13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
   95     10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
   96      3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,
   97      2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,/*s5*/
   98     14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
   99      4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
  100     11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,
  101     12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11, /*s6*/
  102     10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
  103      9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
  104      4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,
  105      4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,/*s7*/
  106     13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
  107      1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
  108      6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,
  109     13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7, /*s8*/
  110      1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
  111      7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
  112      2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
  113  };
  114 
  115  for(i=0;i<48;i++) expand[i]=r[e[i]-1]; /*Expansion Function*/
  116  for(i=n=0;i<8;i++) {
  117   for(j=0;j<6;j++,n++) b[i][j]=expand[n]^keyout[cnt][n];
  118  }
  119 
  120  /*Selection functions*/
  121 
  122   for(scnt=n=0;scnt<8;scnt++){
  123    row=(b[scnt][0]<<1)+b[scnt][5];
  124    col=(b[scnt][1]<<3)+(b[scnt][2]<<2)+(b[scnt][3]<<1)+b[scnt][4];
  125    sout[scnt]=s[scnt][(row<<4)+col];
  126    for(i=3;i>=0;i–){
  127     pin[n]=sout[scnt]>>i;
  128     sout[scnt]=sout[scnt]-(pin[n++]<<i);
  129    }
  130   }
  131   for(i=0;i<32;i++) fout[i]=pin[p[i]-1]; /*Permutation Function*/
  132 }
  133 
  134 static int p[64] = {58,50,42,34,26,18,10,2,
  135               60,52,44,36,28,20,12,4,
  136               62,54,46,38,30,22,14,6,
  137               64,56,48,40,32,24,16,8,
  138               5 = {58,50,42,34,26,18,10,2,
  139               60,52,44,36,28,20,12,4,
  140               62,54,46,38,30,22,14,6,
  141               64,56,48,40,32,24,16,8,
  142               57,49,41,33,25,17,9,1,
  143               59,51,43,35,27,19,11,3,
  144               61,53,45,37,29,21,13,5,
  145               63,55,47,39,31,23,15,7};
  146 
  147 static int invp[64]={
  148  40, 8,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,
  149  38, 6,46,14,54,22,62,30,37, 5,45,13,53,21,61,29,
  150  36, 4,44,12,52,20,60,28,35, 3,43,11,51,19,59,27,
  151  34, 2,42,10,50,18,58,26,33, 1,41, 9,49,17,57,25};
  152 
  153 void des_encrypt(unsigned char *input){
  154  static unsigned char out[64];
  155  static int inputb[64],lr[64],l[32],r[32];
  156  static int fn[32];
  157  static int cnt,n;
  158  register int i,j;
  159 
  160  for(i=n=0;i<8;i++)
  161   for(j=0;j<8;j++) inputb[n++]=(input[i]>>j&0×01);
  162 
  163  for(i=0;i<64;i++){ /*Initial Permutation*/
  164   lr[i]=inputb[p[i]-1];
  165   if(i<32) l[i]=lr[i];
  166   else r[i-32]=lr[i];
  167  }
  168  for(cnt=1;cnt<=16;cnt++){ /*Main encryption loop*/
  169   cypher(r,cnt,fn);
  170   for(i=0;i<32;i++){
  171    j=r[i];
  172    r[i]=l[i]^fn[i];
  173    l[i]=j;
  174   }
  175  }
  176  for(i=0;i<32;i++){
  177   lr[i]=r[i];
  178   lr[i+32]=l[i];
  179  }
  180  for(i=0;i<64;i++) out[i]=lr[invp[i]-1]; /*Inverse IP*/
  181 
  182  for(i=1;i<=8;i++)
  183   for(j=1;j<=8;j++) input[i-1]=(input[i-1]<<1)|out[i*8-j];
  184 }
  185 
  186 void des_decrypt(unsigned char *input){
  187  static unsigned char out[64];
  188  static int inputb[64],lr[64],l[32],r[32];
  189  static int fn[32];
  190  static int cnt,rtemp,n;
  191  register int i,j;
  192 
  193  for(i=n=0;i<8;i++)
  194   for(j=0;j<8;j++) inputb[n++]=(input[i]>>j&0×01);
  195 
  196  for(i=0;i<64;i++){ /*Initial Permutation*/
  197   lr[i]=inputb[p[i]-1];
  198   if(i<32) l[i]=lr[i];
  199   else r[i-32]=lr[i];
  200  }
  201  for(cnt=16;cnt>0;cnt–){ /*Main decryption loop*/
  202   cypher(r,cnt,fn);
  203   for(i=0;i<32;i++){
  204    rtemp=r[i];
  205    if(l[i]==1 && fn[i]==1) r[i]=0;
  206    else r[i]=(l[i] || fn[i]);
  207    l[i]=rtemp;
  208   }
  209  }
  210  for(i=0;i<32;i++){
  211   lr[i]=r[i];
  212   lr[i+32]=l[i];
  213  }
  214  for(i=0;i<64;i++) out[i]=lr[invp[i]-1]; /*Inverse IP*/
  215 
  216  for(i=1;i<=8;i++)
  217   for(j=1;j<=8;j++) input[i-1]=(input[i-1]<<1) | out[i*8-j];
  218 }
  219 
  220 int main(int argc, char *argv[]){
  221  unsigned char *key;
  222  unsigned char data[8];
  223  int n;
  224  FILE *in;
  225  FILE *out;
  226 
  227  if (argc!=4) {
  228   printf("rnUsage:  des [e][d] <source file> <destination file>rn");
  229   return 1;
  230  }
  231 
  232  key=(unsigned char*)getpass("Enter Key:");
  233  des_init(key);
  234 
  235  if((in=fopen(argv[2],"rb"))==NULL){
  236   fprintf(stderr,"rnCould not open input file: %s",argv[2]);
  237   return 2;
  238  }
  239 
  240  if((out=fopen(argv[3],"wb"))==NULL){
  241   fprintf(stderr,"rnCould not open output file: %s",argv[3]);
  242   return 3;
  243  }
  244 
  245  if(argv[1][0]==‘e’){
  246   while ((n=fread(data,1,8,in)) >0){
  247    des_encrypt(data);
  248    printf("data enctyted");
  249    if(fwrite(data,1,8,out) < 8){
  250     fprintf(stderr,"rnError writing to output filern");
  251     return(3);
  252    }
  253   }
  254  }
  255 
  256  if(argv[1][0]==‘d’){
  257   while ((n=fread(data,1,8,in)) >0){
  258    des_decrypt(data);
  259    if(fwrite(data,1,8,out) < 8){
  260     fprintf(stderr,"rnError writing to output filern");
  261     return(3);
  262    }
  263   }
  264  }
  265 
  266  fclose(in); fclose(out);
  267  return 0;
  268 }ntf(stderr,"rnError writing to output filern");
  269     return(3);
  270    }
  271   }
  272  }
  273 
  274  fclose(in); fclose(out);
  275  return 0;
  276 }



The difference between Java’s “final” and C#’s “const”

15 February, 2008 (20:01) | .Net, Java, C# | 0 comments

Final in Java is used to declare a class that can’t be subclassed, a method that can’t be overridden, or …

A final variable means the value won’t change, but the value can still be determined at run time:

final int i;
if ( j > 0 ){
   i =1;
} else {
   i = 2;
}

You get a compile time error if the final variable isn’t definitely unassigned anytime you assign to it:

final int i;
if(j>0){
   i=1;
}
if(a<10){
   i=1;
}

In C#, a “const” must be determined at compile time.

Learning to program: A complete curiculum

17 November, 2007 (16:28) | Programming | 0 comments

I’ve seen many, many posts in forums asking about some good books to read to either get started in computer science, or what next steps to take after having read one intro book on a specific language. Of course none of them state what their goals are, other than they “want to learn to program”. But someone who just wants to write an occasional one off application for fun would take a vastly different route than someone wanting to earn a living as a programmer. This post is for the latter group, those who need in depth knowledge of how to design and develop systems, and are willing to accept that a lot of the process of getting there require a lot of hard work.

I’m not going to recommend specific books for several reasons: 1) Which books are good changes with time, the books I used to cut my teeth on are mostly out of print. 2) There are likely several books which are more than sufficient in each category, so there is no best book, each individual should choose books which suit their needs. 3) There are a lot of resources on line which can augment a book, for example some of the on-line course lectures, and it would be best to stick with the book(s) used in the course. 4) I have not read every book in every category, nor do I even know enough people for our combined readings encompass every book in every category, so it would be impossible to fairly represent every book. 5) I don’t recommend anyone go out and buy all of these books at once and try to read them in one sitting, rather they’ll have to be studied over time, so a better book might have come out while you were working your way through a different one. I would recommend individuals read reviews of whatever books are popular at the time they’re in the market for them.

Required:

The following topics should be considered required reading for everyone. No matter which type of programming you plan to get into, the following topics will provide a foundation to build on. The order of the books is not all that important, though you would obviously want to learn the basics a programming language as a first step. I have tried to put them in order so that it wouldn’t hurt to follow through them in the order listed.

  • Basic language book: This can be something as basic as “Teach yourself x in y hours/days/weeks”. Just don’t expect to learn it as fast as the title says. The language you choose shouldn’t be of too much concern, by the time you’re ‘done’ with this program, you’ll likely have become familiar with many different languages. A very common mistake is for beginners to put too much weight into which is the best beginner language, just pick one and go.
  • A more in depth language book: The basic book probably skipped over a lot of the features of the language. Choose a book which goes over the language in depth. There are many introductory books which do a good job of presenting the important parts of a language, so you might be able to get by with a book which combines #1, and #2.
  • Data Structures and Algorithms: This is where you start to learn how to actually get work done, and get it done efficiently. This book, and the books that follow won’t focus so much on the programming language, but higher level concepts of how to design programs.
  • Programming Languages: There are lots of languages out there, each with their strengths and weaknesses. There are also many common features among different languages. This book will help you decide which language features are available and which one is the best tool for whatever task you’re about to undertake.
  • Computer organization: This book will definitely include assembly language as one of it’s topics, in fact many books titled “Assembly Language” will suit the bill nicely. The purpose of this topic is to get an idea of what’s going on under the hood to help you design more efficient systems, as well as explain why somethings are or aren’t possible.
  • Operating Systems: Odds are you won’t be working directly with a machine, but will rely on an operating system to make working with the different parts of the machine easier. This book will likely assume you’re somewhat familiar with assembly language. Note, this is not a book titled something like “Teach yourself Windows XP in 21 Days”, but is a book which doesn’t focus on a specific operating system. It will concentrate more on the underlying concepts of how operating systems are designed. That’s not to say a book on the operating system you’re using isn’t a useful resource though.
  • Discrete Mathematics: This book will almost definitely not contain any code, in fact, it might not even mention computers. It will abstract out the abilities of the computer into mathematical terms. This will allow you to transcend the specifics of the machine you’re working with to design efficient solutions to problems, while still keeping the solution as something that can actually be implemented on a computer.
  • Networking: This shouldn’t be a “Network Programming in <Language X>”, but a book which focuses on the underlying principles of network communication. The book will likely not contain a single line of code, but it’s OK if it does. I wouldn’t recommend a totally abstract book, rather something that focus on TCP/IP with explanations of why certain things exist (or don’t exist) in the protocols would be OK.

Recommended:

For persons interested in game programming vs. those interested in business applications, the path taken will be different. Since my background is mostly in business applications, I can only recommend topics along those lines. Not all of these topics are specific to business programming per se’, but I don’t necessarily consider them to fall under the “required for everyone” heading. These topics are in no particular order and can be read concurrently with each other. And I would even go so far as to say you can read them concurrently with books in the “required” list.

  • SQL and database design: Almost every business application will involve the use of a database of some sort. It is important to be fluent in the use of databases in order to work efficiently.
  • Specific databases: Oracle and SQL Server, MySQL, etc: There are several different popular implementations of databases available, each with it’s own proprietary extensions to SQL. Unless you’re starting your own business, odds are you won’t get to choose which database implementation you get to work with, so it’s a good idea to be familiar with all of the most popular ones. Many books on a specific implementation also include a good into to SQL and database design, so you can combine this with book #1 on this list.
  • Design Patterns: Many programs share similar ideas, so much so that it’s a good idea to give certain ideas or “patterns” names. This allows you to discuss and explain patterns of programs with other developers at a much higher level. Additionally design patterns serve as examples of good design, and will save you the trouble of inventing them yourself. There is also a concept of “anti-patterns” (also called pitfalls) which are examples of common bad design, which can also be of great help. I would also like to warn you specifically of one anti-pattern, and that’s the overuse of design patterns. I’ve seen many programmers get too excited over design patterns that they want to use them everywhere, so it’s important to know when and where to use them.
  • Human Computer Interaction: Not all business applications involve a user interface, but you’ll likely end up writing many applications that do. Being able to develop a good, intuitive user interface is a very difficult task in most situations, but is one of the most important features required in order to make sure your application is actually useful.
  • Object Oriented Design: This is mostly a required concept, and is generally covered somewhat in even basic books on programming languages which are base on object oriented concepts. But it’s a good idea to study specifics of object oriented design in depth.
  • Computer Security: This is a definite must for any business application. It’s easy to be too naive and think no one will attempt to crack your application, or that they couldn’t possibly figure out your home grown obfuscation technique. Studying security will help you be skeptical about the security of every piece of your application and give you common tools to use to develop strong, robust, reliable systems.

Learn other languages:

Knowing only one programming language is almost like owning only one tool in your garage. I’m not saying you need to be a guru in a dozen different languages, but you should be fluent in at least a few languages, and a guru in one or two with the ability to become a guru in other languages quickly. While every business dreams of having all of their applications written in just one language, it’s something that pretty much never materializes, and certainly not for any successful business since the life of the business will certainly exceed the life of the language their applications are written in. So it’s an important marketable skill to be fluent in many different languages, as well as having the ability to pick up new ones without taking a week long training course. Just as an example, on any given day, I might program in as many as 13 different languages: VB6, VB.Net, C#, Java, Perl, C, C++ PHP, JavaScript, VBScript, Python, PL/SQL, Transact-SQL are all languages I use daily (but I don’t ask for your pity). I recommend knowing languages which encompass all of the following features (most languages will have several of these properties, but the idea is to learn several languages):

  • Object oriented language
  • Scripting language
  • Language with memory management built in.
  • Language without automatic memory management (C would be my recommendation)
  • Machine language
  • Static typing
  • Weak typing

Continued Learning

Once you’ve built a foundation, you can’t stop learning there. Computer programming is a field which is constantly changing and will require continued effort towards learning new and different techniques. So, if you don’t like learning new things, this probably isn’t the field for you. There’s a good chance that most of the techniques you learn today won’t be of much use 10 years from now, and whatever you’ll be doing 20 years from now will be barely recognizable as programming to a programmer today. Many of the underlying concepts change much more slowly than the actual technology, which is why it’s important to learn them. When you understand the concepts, it’s much easier to find a tool to make it happen.

Passing immutable types by reference in Java and C#

12 October, 2007 (18:26) | Java, C# | 0 comments

To many, it should be obvious what the following code prints:

public static void main(String[] args){
     int x=0;
     SomeMethod(x);
     System.out.println(x);
}

protected static void SomeMethod(int x){
     x=1;
}

The code prints 0, because “int” is a native type and is passed by value. But, what if we replace “int” with “Integer”?

public static void main(String[] args){
     Integer x=0;
     SomeMethod(x);
     System.out.println(x);
}

protected static void SomeMethod(Integer x){
     x=1;
}

This is where a lot of people get confused. Integer is an object type, and will be passed by reference, but the program still prints 0. Why? Even though x is a reference to an object, Integer is an immutable type, and the assignment “x=1″ is actually equivalent to “x=new Integer(1)”. This actually changes the value of x, rather than the value pointed to by x.

Fortunately this case is rarely the source of errors since it’s considered bad design to return values through parameters.

Although the above code is in Java, you will run into similar behavior with C# immutable types.

Computer Chronicles computer programming language debate from 1984

25 September, 2007 (13:02) | History | 0 comments

It’s amazing how often we still hear these same points being made today.

Does string interning in C# guarentee you only get one copy of a static value?

19 September, 2007 (22:15) | .Net, C# | 0 comments

Of course the answer is no, otherwise it wouldn’t be a very interesting post. The concept of interning is an attempt to save memory by allocating static values which match exactly to the same memory location, without regard to where they’re used in the application. But here’s in instance where it doesn’t quite work.

The String.Empty constant just contains the value “”. So logic would say that every value in the following code would point to the exact same location:

        static void Main(string[] args) {
            String t = "";
            String t1 = String.Empty;
            String t2 = String.Empty;
            String t3 = "";
            Console.WriteLine(t + t1 + t2 + t3);
        }

But, if you look at the disassembly, you find that the two values for “” were interned to one location (0226303Ch), and the String.Empty values were interned to another (0226102Ch):

String t = "";
00000033  mov         eax,dword ptr ds:[0226303Ch]
00000039  mov         esi,eax
String t1 = String.Empty;
0000003b  mov         eax,dword ptr ds:[0226102Ch]
00000040  mov         edi,eax
String t2 = String.Empty;
00000042  mov         eax,dword ptr ds:[0226102Ch]
00000047  mov         dword ptr [ebp-48h],eax
String t3 = "";
0000004a  mov         eax,dword ptr ds:[0226303Ch]
00000050  mov         dword ptr [ebp-4Ch],eax