asc("") and printf("%s",NULL)

A few days ago I was reminded of one of the differences between Solaris and GNU/Linux which caused a few headaches for Sun's desktop team back in the days of GNOME 1.2. The problem is that while you can printf("%s",NULL); in most Linux distributions, doing the same in Solaris caused the executable to exit and generate a core. There were some debates about the correctness of each approach. Should the program crash to tell the developer that he shouldn't be trying to print a NULL string (the Solaris behavior) or should the program continue happily along printing a NULL pointer? I can see some advantages in both approaches I suspect this and other "Linuxisms" will end up in OpenSolaris simply because they make it more convenient for average coders to throw together a quick and dirty program or for someone to compile and run the thousands of source packages out there which (perhaps unknowingly) take advantage of this Linuxism.

But thinking about this reminded me of a similar "bug/feature" in my very first computer, the Commodore 64 back in 1982 when 64K seemed an unbelievably excessive amount of memory for a computer which cost only $595. The built in blitter and 4 channel 16 bit synthesizer made it a really fun computer for me to write simulations and sound generator programs for my father's physical science class. If you look closely at many of the programs which were published for Compute! and other magazines of the time, you might notice something strange. When a character was read from the user (e.g. via get (a$) ), the asc(a$) function would convert the character to its numeric ASCII value. But in the code you would usually see something like this:

n = asc(a$+chr$(0))

J64 java emulator

What is going on here? There was a bug/feature in Commodore 64 BASIC V2 which raised an "Illegal quantity error." whenever a null string was passed to the asc() function. The Commodore 64's 6510 processor had the unusual ability of being able to peek the ROM and write to shadow RAM which shared the same address space and then disable ROM so that BASIC was running from RAM. This allowed modifications to the BASIC interpreter. Jim Butterfield, a Commodore expert and author once demonstrated a one byte poke which fixed this asc("") bug. Ever since I learned of this simple fix, I wondered why so many BASIC's had this same one byte bug. The Commodore 64, Vic-20, Atari, Amiga, and at least some versions of the Apple and IBM PC Basic's shared this same bug! What was going on? Well, as it happens, a little company known as Microsoft wrote versions of BASIC for nearly all 8 bit computers of the 1980s and 1990s. Was this one byte bug overlooked by Microsoft and propagated to all Microsoft inspired codebases or were Microsoft's developers following the same purist philosophy as Solaris developers who assert that "good coders shouldn't pass NULL into string functions?" Either way, when such a company grows to what it has now become, it can decide that this one byte bug is actually a feature.


The good ol' days of the C=64, the Action Replay, the Final Cartridge III, TurboASM, Time Cruncher, Cruel Cruncher, and the XAKK's Cross Linker...

You reminded me of a time when people who used computers were people that were actually interested in, and cared about them.

We have an order of magnitude faster machinery now, but the scene is not the same, now we have incompetence, ergo the "GNU/Linux way".

Incompetence and ignorance. That's what it is.

Posted by UX-admin on December 06, 2008 at 12:33 AM GMT+00:00 #

What sort of person would want to do:
anyway !?

Same kind of person that does not check if a malloc happend correctly then does not free it maybe?

Yes, it should crash.. Stops idiots writing programs!


Posted by EdwardOCallaghan on December 06, 2008 at 02:38 AM GMT+00:00 #

Maybe there should be a cc --newbie mode where referencing null pointers is O.K. ;-)

# uname -a
SunOS toshiba 5.11 snv_101a i86pc i386 i86pc
# cat hellonull.c
#include <stdio.h>

int main()
printf("Hello %s World!\\n",NULL);

# cc hellonull.c -o hellonull
# ./hellonull
Segmentation Fault (core dumped)
# pstack core
core 'core' of 2682: ./hellonull
fee63d90 strlen (8050a60) + 30
feeb2707 printf (8050a60, 0) + af
08050a12 main (1, 8047adc, 8047ae4, feffb7e4) + 12
0805096d _start (1, 8047be4, 0, 8047bf0, 8047c15, 8047c20) + 7d

Posted by bnitz on December 06, 2008 at 03:52 AM GMT+00:00 #

If you need to allow printing the contents of the address 0 as a string, you can either install a really ancient SunOS or create and lxzone and zlogin Lzone:

-bash-2.05b# uname -a
Linux linuxzone 2.4.21 BrandZ fake linux i686 i686 i386 GNU/Linux
-bash-2.05b# cat hellonull.c
#include <stdio.h>

int main()
printf("Hello %s World!\\n",NULL);


-bash-2.05b# cc -o hellonull hellonull.c
-bash-2.05b# ./hellonull
Hello (null) World!

Posted by bnitz on December 06, 2008 at 04:24 AM GMT+00:00 #

"The built in blitter and 4 channel 16 bit synthesizer..."

That was the Amiga, not the C64. :)

Posted by Adi on February 04, 2009 at 06:47 AM GMT+00:00 #

The C64's sprites might not quite meet the 'blitter' definition, but from I they were actually easier to use since they didn't rely on the slow CPU to do anything but load it with data and give it a location.

You're correct about the sound chip too. The C64 only had a 3 channel 8 bit synthesizer with an envelope, a few wave shapes, really nice frequency resolution and controllable analog filter but no sampling capability:
Hmm, there's a market for old SID chips? Just get me my chip puller.

The frequency resolution was so good, I wrote a simple program for my father to use in his physics class to demonstrate frequency beating and other things. His school wouldn't approve the $595 budget for a computer even though they would approve $1000 for a less practical dedicated audio frequency generator and another $1000 for an oscilloscope. How times have changed!

Posted by bnitz on February 04, 2009 at 07:10 AM GMT+00:00 #

Post a Comment:
Comments are closed for this entry.



« April 2014