home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c      Meh, in C you gotta define EVERYTHING      243,242 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 242,905 of 243,242   
   Tim Rentsch to Andrey Tarasevich   
   Re: function pointer question   
   07 Jan 26 21:52:16   
   
   From: tr.17687@z991.linuxsc.com   
      
   Andrey Tarasevich  writes:   
      
   > On Tue 1/6/2026 12:41 PM, Kaz Kylheku wrote:   
   >   
   >>>> typedef double operation(double, double);   
   >>>> /* ... */   
   >>>>   
   >>>> extern operation add, sub, mul, div;   
   >>>>   
   >>>> static struct {   
   >>>>       char *name;   
   >>>>       operation *function;   
   >>>> } ops[] = {   
   >>>>       { "add",      add },   
   >>>>       { "subtract", sub },   
   >>>>       { "multiply", mul },   
   >>>>       { "divide",   div }   
   >>>> };   
   >>>   
   >>> ... with a remark that `extern` is completely redundant here.   
   >>>   
   >>>     operation add, sub, mul, div;   
   >>   
   >> Butlonly because operation is a function type, so the concept of   
   >> a tentative definition doesn't apply.   
   >   
   > Yes, to me it feels like it has way less potential to mislead with an   
   > extern`. But I can't really say whether this perception is objectively   
   > inherent in the construct, or it is just the fact that it is an exotic   
   > way of declaring functions (for me and, probably, for most people).   
   >   
   > However, while it is true that the concept of a tentative definition   
   > doesn't apply, I still don't quite get your point.  What if were an   
   > object type and the concept would apply?  Are you implying that   
   > tentative definitions should be avoided (i.e. that all object   
   > definitions should include an initializer)?   
      
   If we ignore "static" for the moment, there is a simple rule:   
   use 'extern' for declarations, and nothing for definitions.   
   This rule works for both functions and objects.   
      
   Now if we add "static" back into the mix, and limit the discussion   
   to functions, the same rule applies provided we stipulate that   
   everything is pre-declared.  Thus, always use 'extern' or 'static'   
   to declare (in advance) a function, and on the function definition   
   don't use any storage class.   
      
   Unfortunately, the way 'static' works for objects is not symmetric.   
   There is no way to write a non-defining declaration for a static   
   object.  And, what is worse, once an object has been declared (and   
   so tentatively defined) with 'static', then any definition must also   
   use 'static'.  Hence we have a new rule:  always use 'extern' or   
   'static' when declaring a function or object, and leave off both   
   when defining a function or object, /except/ 'static' must be used   
   when defining a static object.  C would have been nicer if 'static'   
   for objects worked the same way as 'static' for functions.  Oh well.   
      
      
   >> The lack of extern could trip someone up who refactors the   
   >> code such that the operations are object types:   
   >>   
   >>    named_operation add, sub, mul, div; // oops, multiple definition   
   >>   
   >>    static named_operation ops[] = { add, sub, mul, div };   
   >   
   > Again, I'm at a bit of a loss.  What is this intended to illustrate?   
      
   To me the example looks flawed (and not because of multiple   
   definitions).  My advice is to stick with the rule described above   
   for declarations and definitions.   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca