home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / std / c / 2481 < prev    next >
Encoding:
Internet Message Format  |  1992-08-19  |  7.3 KB

  1. Path: sparky!uunet!snorkelwacker.mit.edu!thunder.mcrcim.mcgill.edu!sobeco!philmtl!vedge!hendrik
  2. From: hendrik@vedge.UUCP (Hendrik Boom)
  3. Newsgroups: comp.std.c
  4. Subject: Re: mixing prototyping and non-prototyping
  5. Message-ID: <28616@vedge.UUCP>
  6. Date: 19 Aug 92 15:55:06 GMT
  7. References: <spuler.713749345@coral.cs.jcu.edu.au>
  8. Organization: Visual Edge Software, St. Laurent, Quebec
  9. Lines: 189
  10.  
  11. spuler@coral.cs.jcu.edu.au (David Spuler) writes:
  12. : What are the rules regarding mixing old-style and new-style functions in C
  13. : programs?  Specifically, what mixtures must a compiler support,and which can
  14. : be legally allowed to bomb?
  15.  
  16. Here's my standard handout on this subject:
  17.  
  18. More light and heat on prototypes
  19.  
  20. A close reading of the ANSI C standard reveals the following 
  21. convoluted relationships between prototypes, old and new style
  22. function definitions, and function calls.  Please comment,
  23. especially if you detect errors in my interpretation.
  24.  
  25. First, some terminology.
  26.  
  27. A function definition is the thing that contains
  28. the executable code for the function. A function declaration
  29. only announces that a particular name is to be used
  30. as a name for the function, and does not contain the
  31. executable code for the function.  Any and all of a function
  32. definition, declaration, and call may contain information
  33. about the argument types, with varying significane.
  34.  
  35. We call them parameters in a declaration or definition,
  36. and arguments in a call.
  37.  
  38.  
  39.  
  40. Case: No prototypes at all.
  41. ---------------------------
  42.  
  43. This is how old-stype K&R C worked.
  44.  
  45. The interpretation by a compiler of parameters in a function
  46. definition and its interpretation of arguments in a call
  47. were independent.  To lesen the pain somewhat, conversion rules
  48. were defined that made things slightly more likely to match up.
  49.  
  50. ANSI defines the old-stype functions to worl as follows.
  51.  
  52. The old-style rules apply whenever a function has neither
  53. been declared with prototype syntax
  54. nor been defined with new-style syntax.
  55.  
  56. The function call applies a set of
  57. standard conversions, and the function definition expects
  58. the standard conversions to have been applied.
  59.  
  60. The standard conversions at the point of call are defined
  61. independent of the actual parameter types expected by the
  62. function definition.
  63.  
  64. To make this work at least some of the time,
  65. a function defined using old-style syntax,
  66. will expect its parameters to have been converted
  67. using the standard argument promotion rules.
  68.  
  69. A function with a single real argument, such as
  70.     f(r)real r;{    }
  71. will in fact expect a double.
  72. If you pass a double to it, the double gets passed as is.
  73. If you pass a real to it, the real will be converted to
  74. double at the point of call, and the double will be
  75. passed instead.
  76. If you pass an int, no conversion takes place. This will
  77. probably not work.
  78. If you pass a char, it will actually pass an int,
  79. which will probably not work.
  80.  
  81. Note: machines exist where the int representation is a
  82.     subset of the real representation. However, even on these
  83.     machines, a double is likely to be bigger than a real
  84.     or an int.
  85.  
  86.  
  87. Case: protoype at definition and call. (New-style rules)
  88. --------------------------------------------------------
  89.  
  90. If you have a function declared with a prototype,
  91. such as
  92.     int f(real);
  93. this indicates how the compiler is to call the function,
  94. and indicates that the parameter is to be passed by whatever
  95. conventions the compiler uses to pass real parameters.
  96. If the argument in a call is, for example, an integer,
  97. and the protoype indicates it should be a real,
  98. it will be converted to real, and passed using the parameter
  99. conventions for real. These might well differ from those for
  100. passing a double.
  101.  
  102. Case: prototype at use but not at definition.
  103. ---------------------------------------------
  104.  
  105. This can be expected to happen during transition from
  106. old-style to new.
  107.  
  108. If the call to function f occurs in a place where a prototype
  109. has been declared for f, but the function definition
  110. (probably in a separate compilation unit) uses old-style
  111. parameter syntax, trouble is likely to arise.
  112. The caller will perform a set of conversions based on the
  113. prototype, and the function will expect the arguments
  114. to have been converted without reference to a prototype.
  115. If these conventions differ, the arguments get trashed
  116. across the interface.  Ansi permits the old-new clash
  117. provided that the prototype define the arguments to
  118. have the types that they would have after conversion
  119. according to the non-prototype parameter conversion rules.
  120. This in general may differ from the types mantioned
  121. in the function definition.
  122.  
  123. In the case of our function with the single real argument,
  124.     f(r)real r;{    }
  125. the protoype must read
  126.     f(double);
  127. because f will expect any real argument to have been
  128. converted to double before it is passed.
  129.  
  130. Prototype at definition but not at use.
  131. ---------------------------------------
  132.  
  133. This is likely to occur during transition from old to new styles
  134. if the function is called from a separate compilation unit,
  135. or if the call occurs before the prototype or definition in
  136. the same compilation unit.
  137.  
  138. Again, this will work if the prototype declared the types
  139. that will result from the standard argument promotions.
  140. If the function is defined using new-stype syntax, the
  141. types of the parameters must be the same as the types in the
  142. prototype declaration.
  143.  
  144. If a function with a single real argument is defined using
  145. new-style syntax:
  146.     g(real x){   }
  147. then a call like g(r) will not work if the prototype for g is not
  148. at the point of call.  Even if the argument r is in fact a real,
  149. and g expects a real, absence of a protoype at the point of call
  150. will force the real to be promoted to double and passed as a double!
  151.  
  152.  
  153. The moral
  154. ---------
  155.  
  156. How do we use _NO_PROTO?
  157.  
  158. To make code work with and without prototypes, but to take advantage
  159. of them when they are available, use the following conventions.
  160.  
  161. (a)    Include parameters in function declarations
  162.     conditional on the absence of _NO_PROTO.
  163.     This will provide extra checking and argument conversions
  164.     and may detect a lot of silly errors.
  165.  
  166. (b)    Either 
  167.       - (b1) provide two versions of the parameter part of
  168.         a function definition, a new-style version
  169.         if _NO_PROTO is absent and  K&R style if it is
  170.         present,
  171.     or
  172.       - (b2) use only the old K&R style, but accept restrictions
  173.         on the parameter types that occur in any prototypes.
  174.         The parameters in the prototypes must be the ones that
  175.         remain after the standard argument promotions,
  176.         because a K&R function will expect these instead
  177.         of the types actually mentioned in its code.
  178.         Thus if the function expects a char, the prototype
  179.         must lie and say int or unsigned int (depending on the
  180.         platform). It the function expects a real, the
  181.         prototype must say double.
  182.         
  183. Note: For compatiblility with TAGS, the initial open
  184. curly brace of the function body must be at the left margin
  185. with the parameterds inside the #ifdef _NOPROTO . Otherwise
  186. TAGS will fail to notice that a function was defined at all.
  187.  
  188. Note: For non-Visual-Edge readers on the net:
  189. _NO_PROTO is a preprocessor symbol extensively used by
  190.  many software producers to govern the
  191. presence or absence of prototypes in header files.
  192. Its use is not dictated or mentioned by the ANSI standard.
  193.  
  194. -- 
  195. -------------------------------------------------------
  196. Try one or more of the following addresses to reply.
  197. at work:    hendrik@vedge.com,  iros1!vedge!hendrik
  198. at home:    uunet!altitude!ozrout!topoi!hendrik
  199.