From: 643-408-1753@kylheku.com   
      
   On 2025-11-14, Kenny McCormack wrote:   
   > Wow! An actual on-topic C question. Don't see much of that around here   
   > these days...   
   >   
   > My question has to do specifically with "static" - as seen below - but also   
   > in general with these sorts of attributes of functions and variables.   
   >   
   > Suppose I have code like this:   
   >   
   > /* static */ char *foo(int);   
      
   If this is the first declaration of foo, foo gets external linkage.   
      
   > int somefun(...) { code that uses foo() }   
   > ...   
   >   
   > static char *foo(int bar) { definition of foo() }   
      
   This is now giving foo internal linkage in the same scope, which   
   is UB.   
      
   In C99, this was given in 6.2.2, paragraph 7:   
      
   "If, within a translation unit, the same identifier appears with both   
   internal and external linkage, the behavior is undefined.'   
      
   It's in the same numbered section and paragraph in the n3302 draft.   
      
   Obviously, this situation is easily diagnosable, in principle.   
      
   > Is foo() static or not?   
      
   Since the behavior is not defined, there need not even be a   
   translated unit.   
      
   > Does the order matter? Suppose the first reference   
   > to foo() had static and the second one didn't?   
      
   The order matters because a file scope declaration without   
   a storage class specifier, or even with the storage class   
   specifier "extern", inherits the previously declared linkage.   
      
   "extern" or the lack of specifier does not mean "give my identifier   
   externa linkage" but "give my identifier the previously declared   
   linkage, or else external".   
      
   "static" doesn't do that; it asserts internal linkage.   
      
   > Or is it a syntax error to have different declarations/definitions like   
   > this? What if they occur (as they usually will do) in different files (TUs)   
   ?   
   >   
   > Note that this came up in real life - I had to change a function that had   
      
   I've on rare occasion seen it in the past that GCC warned about an   
   identifier being given both linkages.   
      
   It does not require contorted or contrived circumstances in order   
   to occur.   
      
   It's suprising that in all the decades that 6.2.2 Paragrah 7 text   
   has existed, complex features have been added to the language.   
      
   Yet the simple matter of converting that to a constraint   
   has somehow esacaped attention.   
      
   Any half decent compiler should be diagnosing it already,   
   making it practically a no-op to implement the requirement   
   for that compiler?   
      
   Maybe there are situations in which the situation happens   
   (same identifeir appears with both linkages), which are not easily   
   diagnosable. I can't think of any at the moment, and   
   that wouldn't preclude having both a constraint violation for   
   the diagnosable cases, and leaving the 6.2.2/p7 text.   
      
   --   
   TXR Programming Language: http://nongnu.org/txr   
   Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal   
   Mastodon: @Kazinator@mstdn.ca   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|