NULL as a string terminator

Chris Preston cbp at icc.com
Mon Aug 20 10:02:27 AEST 1990


In article <134 at blekko.UUCP> skrenta at blekko.UUCP (Rich Skrenta) writes:
>robert at cs.arizona.edu (Robert J. Drabek) writes:
>
>>>> #define  EOS  '\0'
>
>> I see the difference as one between
>> using an object and using a name for the object.  My personal feeling is
>> that it is more polite to use the name.
>
>> '\0' has uses and interpretations other than "end-of-
>> string".  So when I see EOS I know for certain what I meant.  When I see
>> '\0' there is the chance that some other interpretation or use is meant.
>
>In many cases the object itself becomes familiar enough that it's
>instantly recognized.  '\0' is one such object.  If I saw in your
>code
>
>	*p = EOS;
>
>I'd have to run off to your .h files to find the definition of EOS.

  Perhaps a comment in an appropriate place might alleviate this.

>*You* like your non-standard name for '\0', but no one else will
>know what it means, and it's unlikely that it will ever be a Big Win
>for you (like if we start terminating strings with ^A or something).

  Then, it will be a very big win.  Using two characters would break
  much more software than would changing the terminator to a single
  different letter.  In the case of doing a sprinkling of assembly
  on DOS or CPM, the $ is used as a terminator (typically) when calling an
  interrupt service routine.  If you are doing assembly calls in a section
  of code you need only
  
  #if DOS
  #undef EOS
  #define EOS '$'
  #endif
  for ( this=that; someloop<ArraySize && etc; someloop++)
    if (someloop=ArraySize-1){
      (*array)[someloop]=EOS;
      CallToAssembly(*array);
    }else
      DoSomethingElse((*array)[someloop]);

  #if DOS
  #undef EOS
  #define EOS '\0'
  #endif

  Typically, one could even replace '$' and '\0' further with
  DOS_CPM_TERMINATOR and UNIX_DOS_C_CALL_TERMINATOR.  So, while you as
  a Unix or Dos or whatever programmer might not care about the others, it
  allows a level of abstraction that facilitates portability and
  maintainability.


  Mind you, I might like shorter labels, but one get's the idea.

>
>Other cases occur where someone makes #defines for error strings
>that are used only once:
>
>#define	FOO_BAR_ERROR	"foo bar error"
>#define UNDEF_BAZ_ERR	"undef baz err"
>
>I cringe when I come across code like this.  Needlessly removing objects
>a level is distracting and gains nothing.

  It seems here that if FOO_BAR_ERROR is something along the lines
  of 

  #define DATACOM_NOT_INIT "Datacomm was not initialized"

  might be usefull.  One could then modify this like so:

  #if MSDOS
  #define DATACOM_NOT_INIT "Execute datacomm.exe and restart the program"
  #elif  SYSV
  #define DATACOM_NOT_INIT "Contact you system administrator for datacomm startup"
  #elif BTOS
  #define DATACOM_NOT_INIT "Master Cluster datacomm not initialized"
  #else
  #define DATACOM_NOT_INIT "Datacomm is not initailized"
  #endif


  Now, which is more 1)Cost effective 2)Maintainable ergo 
  3)Good programming style? To go through and have to change this message
  every time you port the code, or allow for changes without having to
  modify the code beyond considering operational differences because
  your macros cover most of the bases?

  In fact, there are few instances in which text strings and constants
  should not be removed to a macro level (IMHO, mind you, IMHO).  
  To do so means that the programmer will need to know where the pertinent
  substitutions are located, and the programmer should insure that all
  labels are clear in their intent.  IMHO this just means that good
  programming requires more work up front and less work later on, but that
  is the tradeoff between development and maintenance.  It also impacts on
  the reusability of code.  Pay me now or pay me later.

>
>Rich
>-- 
>skrenta at blekko.commodore.com

cbp

cbp at icc.com



More information about the Comp.lang.c mailing list