Re: [RFC] An idea for general kernel post-processing automation in FreeBSD
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