On 2025-11-14, Kenny McCormack <
gazelle@shell.xmission.com> 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
--- PyGate Linux v1.5
* Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)