home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / os / vms / 19855 < prev    next >
Encoding:
Internet Message Format  |  1992-12-24  |  4.2 KB

  1. Path: sparky!uunet!spool.mu.edu!agate!ucbvax!lrw.com!leichter
  2. From: leichter@lrw.com (Jerry Leichter)
  3. Newsgroups: comp.os.vms
  4. Subject: re: cdd and c
  5. Message-ID: <9212241953.AA15525@uu3.psi.com>
  6. Date: 24 Dec 92 18:29:42 GMT
  7. Sender: daemon@ucbvax.BERKELEY.EDU
  8. Distribution: world
  9. Organization: The Internet
  10. Lines: 80
  11.  
  12.  
  13.     [Ung-Ho Yi asked:]
  14.     |>i am currently trying to include a string field from
  15.     |>cdd to my c program.
  16.     |>the string field in cdd was created for cobol, so when i tried to
  17.     |>include the field to my c program, i am one character short.
  18.  
  19.     [Paul Winalski answered:]
  20.     You've run into a fundamental problem here with the ways that the two
  21.     languages (COBOL and C) handle strings.  The string manipulation
  22.     functions in C deal with NUL-terminated strings.  COBOL does not.
  23.     There are two ways that you can reconcile this difference:
  24.  
  25.     1) In your C program, process the string without requiring the NUL
  26.        terminator. This means avoiding functions such as strlen(),
  27.        strcpy(), and the %s formatting directive in printf(), all of which
  28.        assume that a string is NUL-terminated.
  29.  
  30.     2) Define the field in your CDD record to be one character bigger than
  31.        it has to be (this is the CDD equivalent of saying char x[7] when
  32.        you want x to hold a string with 6 characters in it).  Then just
  33.        ignore the last character position in your COBOL code.
  34.  
  35.     It depends on your application which of these solutions is easier to
  36.     implement.  For example, if the field represents existing data in,
  37.     say, disk file records, you have no choice--the format is dictated by
  38.     the data on disk and your C code will just have to avoid using the
  39.     functions that depend on a NUL terminator.  On the other hand, if you
  40.     are designing the whole application now, you can make the string field
  41.     one bigger than it has to be, to accomodate C's NUL character.
  42.  
  43. I agree with most of what Mr. Winalski says, but disagree with his conclu-
  44. sions.  I'd very strong recommend taking his alternative 1 in just about all
  45. cases.
  46.  
  47. The problem with alternative 2 is that it only solves half to problem:  It
  48. leaves ROOM for a trailing NUL byte, but there is no way you are going to get
  49. COBOL or any other language that uses descriptor-based strings (i.e., any VMS
  50. language other than C!) to insert it for you reliably.  Every time you create
  51. a string constant, you'll have to insert the NUL yourself.  Every time you do
  52. any string operation - concatenate two strings, extract a piece of a string,
  53. calculate the length of a string - you'll have to remove and add those NUL
  54. bytes, since to those other languages they will be perfectly valid parts of
  55. the string.  The maintenance problems will kill you.
  56.  
  57. The only situation I might consider this would be one in which the C and COBOL
  58. programs never share a file.  Since the CDD field was created for COBOL, even
  59. if that's true today, I'd expect it to become false tomorrow.
  60.  
  61. You could avoid this problem by fixing up each field as you read the record
  62. into the C program.  That might make sense for a quick hack, but it's really
  63. not the right approach.
  64.  
  65. There are really only to places where C's assumption of a trailing NUL show
  66. up:
  67.  
  68.     - In string constants, which are implicitly NUL-terminated by the
  69.         compiler;
  70.     - In the string-related library functions.
  71.  
  72. You can easily avoid running into problems with either of these with just a
  73. bit of discipline in your programming.  For example, use descriptor-based
  74. "string constants" using the $DESCRIPTOR macro in descrip.h, and use the
  75. counted variants of the string functions.  For example, never use strcpy;
  76. use strncpy.  Even the "%s" printf() specification that Mr. Winalski mentions
  77. can be used:  Always specify it in the %.*s", and give the length of the
  78. string as an argument just before the pointer to the string.  (You can insert
  79. a constant field width where applicable, of course.)
  80.  
  81. While this requires some discipline, it will produce much more reliable C code
  82. (you won't have strings copied into fields too short to hold them, thus
  83. scribbling over other data).  A few carefully-chosen macros and support
  84. routines can go a long way.
  85.  
  86. The very low level of support for strings that's present in C to begin with
  87. makes this much more natural - and less painful - than trying to keep track of
  88. NUL's in languages with high-level support for string operations.
  89.  
  90.                             -- Jerry
  91.  
  92.