Re: [RFC] An idea for general kernel post-processing automation in FreeBSD

From: Mark Millard <marklmi_at_yahoo.com>
Date: Wed, 24 May 2023 16:52:59 UTC
On May 22, 2023, at 13:16, Mark Millard <marklmi@yahoo.com> wrote:

> On May 22, 2023, at 03:00, Hans Petter Selasky <hps@selasky.org> wrote:
> 
>> On 5/22/23 01:07, Mark Millard wrote:
>>> In the C language standard, the original had a status of "no linkage"
>>> and "static storage duration". ("a block scope identifier
>>> for an object declared without the storage-class specifier
>>> extern" leads to the "no linkage" status.)
>>> The change still has "static storage duration" but now has "internal
>>> linkage" status instead. I'm being cautious about the distinction.
>>> (I'm looking at ISO/IEC 9899:2011 (E).)
>>> I've had trouble identifying the match of your wordings to the
>>> language standard, leaving me unsure of the interpretation to
>>> give your wording.
>>> I've yet to figure out why internal linkage could end up
>>> being required, given how the language specifies things.
>> 
>> Hi,
>> 
>> If you find something, let me know. I'll let the issue rest for some days.
> 
> Okay. File the below for later.
> 
> (Some detailed whitespace below might not survive.)
> 
> 
> I still find no reason in the C11 standard to change
> the code in question from:
> 
> Block Scope, No       Linkage, Static Storage Duration
> 
> into:
> 
> File  Scope, Internal Linkage, Static Storage Duration
> 
> I'll ponder the standard's text some more but I doubt
> that I'll find something that I've missed so far.
> 
> 
> I propose using 2 source files that I show below as
> the basis for terminology. I set them up based on
> text from the C11 standard. If you can explain why
> Internal Linkage would be required in terms of some
> similar example and terminology, it would help be
> sure I'm not missing something that you are
> referencing.
> 
> (Part of the text was just me trying to make sure that
> I'd appropriately covered the allowed combinations of
> official language concepts that are involved.)
> 
> 
> # more NameScope_Linkage_StorageDuration_combinations.c
> // For -std=c99 or c11 or c17 or c2x (showing c99):
> 
> // cc -std=c99 -pedantic -Wall -Wextra -c FileScope_ExternalLinkage_initialization.c
> // cc -std=c99 -pedantic -Wall -Wextra NameScope_Linkage_StorageDuration_combinations.c FileScope_ExternalLinkage_initialization.o
> // ./a.out
> 
> // gcc13 -std=c99 -pedantic -Wall -Wextra -c FileScope_ExternalLinkage_initialization.c
> // gcc13 -std=c99 -pedantic -Wall -Wextra NameScope_Linkage_StorageDuration_combinations.c FileScope_ExternalLinkage_initialization.o
> // ./a.out
> 
> 
> // Indentification of contexts and the subset covered here:
> 
> // Just objects (not macros, functions, tags, typedefs names, lables, etc.):
> //              (Note: function prototype scope is not relevant here)
> //
> // Scopes (visibility):   Block, File
> // Linkages:              None (No), External, Internal
> // Storage durations:     Automatic, Static (, Thread, Allocated)
> // Name space:            Ordinary Identifiers (Note: no alternatives)
> 
> // Note: I do not cover any thread-storage-duration related contexts here.
> // Note: I do not cover any allocated-storage-duration contexts here.
> 
> // Note: I do not cover the special non-lvalue expression contexts here
> //       that involve the combination:
> //       temporary-lifetime and automatic-storage-duration
> 
> // For reference:
> // Static Storage Duration: "Its lifetime is the entire execution of the
> //                           program and its storage value is initialized
> //                           only once, prior to program startup."
> //
> // It need not be tied to file scope or to external/internal linkage.
> 
> // Covered here:
> // Block Scope, No       Linkage, Automatic Storage Duration
> // Block Scope, No       Linkage, Static    Storage Duration
> // Block Scope, External Linkage, Static    Storage Duration
> // File  Scope, Internal Linkage, Static    Storage Duration
> // File  Scope, External Linkage, Static    Storage Duration
> 
> // Note: Only external linkage objects have a definition vs.
> //       declaration distinction.
> 
> // I count 4 distinct non-stack types of whole-program-lifetime
> // object contexts in that list: The static-storage-duration ones.
> // But:
> //
> // Block Scope, External Linkage, Static    Storage Duration
> //
> // can only be used to declare access to an external-linkage
> // defined elsewhere (defined outside any block scope).
> 
> // Note: There is no such thing as the combination:
> //       Block Scope, Internal Linkage, Static Storage Duration
> 
> // Note: "Each declaration of an identifier with no linkage
> //        denotes a unique entity." This prevents various
> //        forms of multiple declarations for the same
> //        namespace and scope combination.
> 
> #include <stdio.h>
> 
> // Note: Only automatic storage duration is in a call stack.
> int Using_BlockScope_NoLinkage_AutomaticStorageDuration(void)
> {
>    int BlockScope_NoLinkage_AutomaticStorageDuration = 1;
>    return ++BlockScope_NoLinkage_AutomaticStorageDuration;
> }
> 
> // Note: No direct notation for file scope access exists but
> //       the storage duration spans when the function is not
> //       in use.
> int Using_BlockScope_NoLinkage_StaticStorageDuration(void)
> {
>    static int BlockScope_NoLinkage_StaticStorageDuration = 1;
>    return ++BlockScope_NoLinkage_StaticStorageDuration;
> }
> 
> int Using_BlockScope_ExternalLinkage_StaticStorageDuration(void)
> {
>    // Note: Defined/initialized in FileScope_ExternalLinkage_initialization.c
>    //       Such an external definition is not allowed in block scope.
>    extern int ExternalLinkage_StaticStorageDuration; // a declaration
>    return ++ExternalLinkage_StaticStorageDuration;
> }
> 
> // Note: To have internal linkage requires a file scope declaration.
> static int FileScope_InternalLinkage_StaticStorageDuration = 1;
> // Note: after such an internal linkage definition, the following
> //       is allowed (not required) but does not change the status.
> //       "extern" does not always mean external-storage-duration.
> extern int FileScope_InternalLinkage_StaticStorageDuration;
> int Using_FileScope_InternalLinkage_StaticStorageDuration(void)
> {
>    // Note: after such an internal linkage definition, the following
>    //       is allowed (not required) but does not change the status.
>    //       "extern" does not always mean external-storage-duration.
>    extern int FileScope_InternalLinkage_StaticStorageDuration;
> 
>    return ++FileScope_InternalLinkage_StaticStorageDuration;
> }
> 
> // Note: Defined/initialized in FileScope_ExternalLinkage_initialization.c
> extern int FileScope_ExternalLinkage_StaticStorageDuration; // a declaration
> // Note: Without "extern", a definition would be allowed above, instead
> //       of having one in FileScope_ExternalLinkage_initialization.c .
> int Using_FileScope_ExternalLinkage_StaticStorageDuration(void)
> {
>    return ++FileScope_ExternalLinkage_StaticStorageDuration;
> }
> 
> int main(void)
> {
>    (void) Using_BlockScope_NoLinkage_AutomaticStorageDuration();
>    printf("Using_BlockScope_NoLinkage_AutomaticStorageDuration()   : %d (expect 2)\n"
>          , Using_BlockScope_NoLinkage_AutomaticStorageDuration());
> 
>    (void) Using_BlockScope_NoLinkage_StaticStorageDuration();
>    printf("Using_BlockScope_NoLinkage_StaticStorageDuration()      : %d (expect 3)\n"
>          , Using_BlockScope_NoLinkage_StaticStorageDuration());
> 
>    (void) Using_BlockScope_ExternalLinkage_StaticStorageDuration();
>    printf("Using_BlockScope_ExternalLinkage_StaticStorageDuration(): %d (expect 3)\n"
>          , Using_BlockScope_ExternalLinkage_StaticStorageDuration());
> 
>    (void) Using_FileScope_InternalLinkage_StaticStorageDuration();
>    printf("Using_FileScope_InternalLinkage_StaticStorageDuration() : %d (expect 3)\n"
>          , Using_FileScope_InternalLinkage_StaticStorageDuration());
>    printf("Accessing FileScope_InternalLinkage_StaticStorageDuration : %d (expect 3 again)\n"
>          , FileScope_InternalLinkage_StaticStorageDuration);
> }
> 
> 
> # more FileScope_ExternalLinkage_initialization.c
> // For -std=c99 or c11 or c17 or c2x (showing c99):
> 
> // cc -std=c99 -pedantic -Wall -Wextra -c NameScope_Linkage_StorageDuration_combinations.c
> 
> // gcc13 -std=c99 -pedantic -Wall -Wextra -c NameScope_Linkage_StorageDuration_combinations.c
> 
> // Defined at file scope here.
> // Used separately at block scope elsewhere.
> // The definition can not be in block scope.
> int ExternalLinkage_StaticStorageDuration = 1; // a definition
> 
> // Defined at file scope here.
> // Used separately at file scope elsewhere.
> int FileScope_ExternalLinkage_StaticStorageDuration = 1; // a definition
> 

It has been a few days. So I'll add the following.

Stepping outside the language definition, in
case you are curious about an example of how:

Block Scope, No       Linkage, Static    Storage Duration

can be handled by a toolchain, in a FreeBSD
main aarch64 context I get:

# nm a.out | grep Linkage
0000000000410c7c d BlockScope_NoLinkage_StaticStorageDuration.0
0000000000410c80 D ExternalLinkage_StaticStorageDuration
0000000000410c84 D FileScope_ExternalLinkage_StaticStorageDuration
0000000000410c78 d FileScope_InternalLinkage_StaticStorageDuration
00000000004005e4 T Using_BlockScope_ExternalLinkage_StaticStorageDuration
0000000000400594 T Using_BlockScope_NoLinkage_AutomaticStorageDuration
00000000004005b8 T Using_BlockScope_NoLinkage_StaticStorageDuration
000000000040063c T Using_FileScope_ExternalLinkage_StaticStorageDuration
0000000000400610 T Using_FileScope_InternalLinkage_StaticStorageDuration

"BlockScope_NoLinkage_StaticStorageDuration.0" is not a valid
C identifier but has a structure allowing making each such:

Block Scope, No       Linkage, Static    Storage Duration

unique when the identifier part is not: replacing the 0 in .0
with other numerals, incrementing values, say. The "d" status
avoids it being external.

Overall, then there is nothing else having a possible linkage:
"linkage none" in the C11 standard's terms.

===
Mark Millard
marklmi at yahoo.com