+ John & Félix & Patryk & Henrik
> On Mar 6, 2025, at 1:44 PM, Qing Zhao <qing.z...@oracle.com> wrote:
>
> Hi,
>
> Since I sent the patch series for “extend counted_by attribute to pointer
> fields of structure” two months ago, a lot of discussion were invoked both in
> GCC community and CLANG community:
>
> https://gcc.gnu.org/pipermail/gcc-patches/2025-January/673837.html
> https://discourse.llvm.org/t/rfc-enforcing-bounds-safety-in-c-fbounds-safety/70854/131?u=gwelymernans
>
> After reading all these discussions, understanding, studying, more
> discussions,
> and finally making the whole picture clearer, we came up with a proposal to
> change
> the current design and add a new syntax for the argument of counted_by
> attribute.
>
> The original idea of the new syntax was from Joseph, Michael and Martin, Bill
> and Kees
> involved in the whole process of the proposal, providing a lot of suggestions
> and
> comments. Really appreciate for the help from all of them.
>
> In this thread, I am also CC’ing several people from Apple who worked on the
> -fbounds-safety
> project on CLANG side: yeoul...@apple.com <mailto:yeoul...@apple.com>,
> d_tard...@apple.com <mailto:d_tard...@apple.com>, dl...@apple.com
> <mailto:dl...@apple.com>,
> and dcough...@apple.com <mailto:dcough...@apple.com>.
>
> Please take a look at the proposal in below.
>
> Let me know if you have any comments and suggestions.
>
> Thanks.
>
> Qing.
>
> =========================================
>
> New syntax for the argument of counted_by attribute
> --An extension to C language
>
> Outline
>
> 0. A simple summary of the proposal
>
> 1. The motivation
> 1.1 The current syntax of the counted_by argument might break existing legal
> C code
> 1.2 New requests from the users of the counted_by attribute
> 1.2.1 Refer to a field in the nested structure
> 1.2.2 Refer to globals or locals
> 1.2.3 Represent simple expression
> 1.2.4 Forward referencing
>
> 2. The requirement
>
> 3. The proposed new syntax
> 3.1 Legal C code with VLA works correctly when mixing with counted_by
> 3.2 Satisfy all the new requests
> 3.2.1 Refer to a field in the nested structure
> 3.2.2 Refer to globals or locals
> 3.2.3 Represent simple expression
> 3.3 How to resolve the forward reference issue in section 1.2.4?
>
> Appendix A: Scope of variables in C and C++
> --The hints to the design of counted_by in C
> Appendix B: An example in linux kernel that the global cannot be "const"
> qualified
>
>
> 0. A simple summary of the proposal
>
> We propose a new syntax to the argument of the counted_by attribute:
> * Introduce a new keyword, __self, to represent the new concept,
> "the current object" of the nearest non-anonymous enclosing structure,
> which allows the object of the structure to refer to its own member inside
> the structure definition.
>
> * With the new keyword, __self, the member variable can be referenced
> by appending the member access operator "." to "__self", such as,
> __self.member.
>
> * This new keyword is invalid except in the bounds checking attributes,
> such as "counted_by", etc., inside a structure definition.
>
> * Simple expression is enabled by this new keyword inside the attribute
> counted_by with the following limitation:
> A. no side-effect is allowed;
> and
> B. the operators of the expression are simple arithmetic operators, and the
> operands could be one of:
> B.1 __self.member or __self.member1.member2...(for nested structure);
> B.2 constant;
> B.3 locals that will not be changed after initialization;
> B.4 globals that will not be changed after initialization;
>
>
> 1. The motivation
>
> There are two major motivations for this new syntax.
>
> 1.1 The current syntax of the counted_by argument might break existing legal
> C code
>
> The counted_by attribute is currently defined as:
> (https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-counted_005fby-variable-attribute)
>
> counted_by (count)
> The counted_by attribute may be attached to the C99 flexible array member
> of a structure. It indicates that the number of the elements of the array is
> given by the field "count" in the same structure as the flexible array member.
>
> For example:
>
> int count;
> struct X {
> int count;
> char array[] __attribute__ ((counted_by (count)));
> };
>
> In the above, the argument of the attribute "count" is an identifier that
> will be
> looked up in the scope of the enclosing structure "X". Due to this new scope
> of variable, the identifier "count" refers to the member variable "count" of
> this
> structure but not the global variable defined outside of the structure.
>
> This is a new scope of variable that is added to the C language. In C, the
> default available scopes of variable include only two scopes, global scope
> and local scope.
>
> The global scope refers to the region outside any function or block.
> The variables declared here are accessible throughout the entire program.
>
> The local scope refers to the region enclosed between the { } braces, which
> represent the boundary of a function or a block inside functions. The
> variables
> declared within a function or a block are only accessible locally inside that
> function or that block and other blocks nested inside.
>
> (Please see Appendix A for more details on scope of variables in C and C++
> and why the current design of counted_by attribute is a disaster to C)
>
> Note, the { } brace that marks the boundary of a structure does not change
> the current scope of the variable with the default scoping rules in C.
>
> As a result, in the above example, with C's default scoping rule, the "count”
> inside counted_by attribute _should_ refer to the global variable "count" but
> not the member variable in the enclosing structure.
>
> A more compelling example is shown below when mixing counted_by attribute
> with C's Variable Length Array (VLA).
>
> void boo (int k)
> {
> const int n = 10; // a local variable n
> struct foo {
> int n; // a member variable n
> int a[n + 10]; // for VLA, this n refers to the local variable n.
> char b[] __attribute__ ((counted_by(n)));
> // for counted_by, this n refers to the member variable n.
> };
> }
>
> This code is bad. The size expression "n+10" of the VLA "a" follows the
> default
> scoping rule of C, as a result, "n" refers to the local variable "n" that is
> defined
> outside of the structure "foo"; However, the argument "n" of the counted_by
> attribute of the flexible array member b[] follows the new scoping rule, it
> refers
> to the member variable "n" inside this structure.
>
> It's clear that the current design of the counted_by argument introduced a
> new
> scoping rule into C, resulting an inconsistent scoping resolution situation
> in
> C language.
>
> This is a design mistake, and should be fixed.
>
> 1.2 New requests from the users of the counted_by attribute
>
> The counted_by attribute for Flexible Array Member (FAM) has been adopted in
> Linux Kernel extensively. New requests came in in order to cover more cases.
>
> 1.2.1 Refer to a field in the nested structure
>
> This was requested from linux kernel.
> https://www.spinics.net/lists/linux-rdma/msg127560.html
>
> A simplified testing case is:
>
> struct Y {
> int n;
> int other;
> }
>
> struct Z {
> struct Y y;
> int array[] __attribute__ ((counted_by(?y.n)));
> };
>
> in the above, what should be put instead of "?" to refer to the field "n" of
> the
> field "y" of the current object of this struct Z?
>
> NOTE, we should completely reject the use cases that refer to a field in an
> outer structure from an inner non-anonymous structure, such as:
>
> struct A {
> int count;
> struct B {
> int other;
> int z[] __attribute__ ((counted_by(?)));
> } b;
> };
>
> In the above, we should not allow the counted_by "?" of the FAM field "z" of
> the struct B to refer to the member variable "count" of the outer struct A.
> Otherwise, when an object with the struct B is passed to a function, there
> will be error when refer to the counted_by of its field "z".
>
> However, the counted_by attribute of a field in the inner anonymous structure
> should be allowed to refer to a field of the outer structure. Since the inner
> anonymous structure can not be used independently of its enclosing structure,
> such as:
>
> struct A {
> int count;
> struct {
> int other;
> int z[] __attribute__ ((counted_by(count)));
> };
> } a;
>
> In the above testing case, the counted_by attribute for the field "z" of the
> inner
> anonymous structure should be able to refer to the field of the outer
> structure.
>
> 1.2.2 Refer to globals or locals
>
> One request from linux kernel is here:
> https://lore.kernel.org/all/202309221128.6AC35E3@keescook/
>
> A simple example is:
>
> int count;// global variable
> struct X {
> int count; // member variable
> char array[] __attribute__ ((counted_by(??count)));
> // How to refer to the global variable "count"
> // but not the member variable "count" of the struct X?
> }
>
> when the counted_by attribute tries to refer to the global variable "count”
> outside
> the structure, how to distinguish it with its member variable "count"?
>
> NOTE, Users need to make sure that the global or local variables should not
> be
> changed after they are initialized; otherwise, the results of the array bound
> sanitizer and the __builtin_dynamic_object_size is undefined.
>
> Theoretically, We should limit the globals and locals ONLY to const qualified
> globals and locals to avoid abusing of this feature in the future. However,
> due
> to the existing code in linux kernel cannot be easily changed with const
> qualifier.
> We have to relax the limitation. See Appendix B for such an example in linux
> kernel.
>
> In the future language extension, We should limit the globals and locals ONLY
> to const qualified globals and locals.
>
> 1.2.3 Represent simple expression
>
> This was requested multiple times from Linux kernel. One of the requests is:
> https://lore.kernel.org/lkml/20210727205855.411487-63-keesc...@chromium.org/
>
> For example:
>
> int elm_size;
> struct X {
> int count;
> char array[] __attribute__ ((counted_by(?count * elm_size)));
> }
>
> in the above, what should be put instead of "?" to represent this simple
> expression?
>
> NOTE, We should limit simple expressions to:
>
> A. no side-effect is allowed,
> and
> B. the operators of the expression are simple arithmetic operators, and the
> operands
> could be one of the following:
> B.1 the member variable of the enclosing structure or inner structure of
> the enclosing structure;
> B.2 constant;
> B.3 locals that will not be changed after initialization;
> B.4 globals that will not be changed after initialization;
>
> 1.2.4 Forward referencing
>
> This request is only for counted_by attribute of pointers. Since the flexible
> array
> members(FAM) are always the last field of the containing structure, forward
> reference issue does not exist for counted_by of FAM.
>
> How should we handle the situation when the counted_by attribute refers to
> a member variable that is declared after the pointer field in the structure?
>
> For example:
>
> struct bar {
> char *array __attribute__ ((counted_by(??count)));
> int count; }
>
> in the above, how can we refer to the field "count" that is declared after
> the
> pointer field "array" in the structure?
>
> 2. The requirement:
>
> This is an extension to C language, We should avoid adding a new scope of
> variable (as the current syntax of the counted_by attribute for FAM) to break
> the existing legal C code. We should follow the default C language scoping
> rules, keep the current valid C code working properly.
>
> 3. The proposed new syntax:
>
> * Keep the default C scoping rules.
>
> * Introduce a new keyword, __self, to represent the new concept, "the current
> object”
> of the nearest non-anonymous enclosing structure, which allows the object
> of the
> structure to refer to its own member inside the structure definition.
> This is similar
> as the concept of "this" in C++, except that __self should be treated as a
> special
> variable but not a pointer.
>
> * With the new keyword, __self, the member variable can be referenced by
> appending
> the member access operator "." to "__self", such as, __self.member. This
> is similar
> as referring a member variable through a variable with the structure type
> in the C
> language.
>
> * This new keyword is invalid except in the bounds checking attributes, such
> as
> "counted_by", etc., inside a structure definition.
>
> * Simple expression is allowed inside the attribute counted_by with the
> following limitation:
>
> A. no side-effect is allowed,
> and
> B. the operators of the expression are simple arithmetic operators, and the
> operands
> could be one of:
> B.1 __self.member or __self.member1.member2...(for nested structure);
> B.2 constant;
> B.3 locals that will not be changed after initialization;
> B.4 globals that will not be changed after initialization;
>
> With the new syntax, the problems 1.1, 1.2.1 and 1.2.2 and 1.2.3 can be
> resolved
> naturally as following:
>
> 3.1 Legal C code with VLA works correctly when mixing with counted_by
>
> The previously bad code mixing with VLA is now:
>
> void boo (int k)
> {
> const int n = 10; // a local variable n
> struct foo {
> int n; // a member variable n
> int a[n + 10]; // for VLA, this n refers to the local variable n.
> char b[] __attribute__ ((counted_by(__self.n)));
> // for counted_by, this __self.n refers to the member variable n.
> };
> }
>
> Now, We keep the default C scoping rule and make the counted_by referring
> to member variable in the same structure correctly without ambiguity.
>
> 3.2 Satisfy all the new requests
>
> With this new syntax, all the new requests in section 1.2 (except 1.2.4
> Forward
> referencing) are resolved naturally.
>
> 3.2.1 Refer to a field in the nested structure
>
> struct Y {
> int n;
> int other;
> }
>
> struct Z {
> struct Y y;
> int *array __attribute__ ((counted_by(__self.y.n)));
> };
>
> 3.2.2 Refer to globals or locals
>
> int count;
> struct X {
> char others;
> char array[] __attribute__ ((counted_by(count)));
> }
>
> Since the new syntax keeps the default scoping rule of C language, the
> "count”
> without any prefix inside the counted_by attribute refers to the current
> visible
> variable in the current scope, that is the global variable "count”.
>
> 3.2.3 Represent simple expression
>
> When we can distinguish globals/locals from the member variables with this
> new syntax, simple expressions are represented naturally:
>
> int elm_size;
> struct X {
> int count;
> int *array __attribute__ ((counted_by(__self.count * elm_size)));
> }
>
> More complicated example:
>
> struct foo {
> int n;
> float f;
> }
>
> A.
> #define NETLINK_HEADER_BYTES 8
> struct bar1 {
> struct foo y[5][10];
> char *array __attribute__ ((counted_by(__self.y[1][3].n -
> NETLINK_HEADER_BYTES)));
> }
>
> B. struct bar2 {
> int n;
> char *array __attribute__ ((counted_by((struct foo){.n = 4 }.n)));
> };
>
> C.
> struct bar3 {
> int n;
> char *array __attribute__ ((counted_by((struct foo){.n = 4 }.n + __self.n)));
> };
>
>
> 3.3 How to resolve the forward reference issue in section 1.2.4?
>
> The new syntax naturally resolved all the problems we listed in section 1.2
> except the forward reference issue:
>
> If the member variable that is referred inside the counted_by is declared
> after
> the pointer field with the counted_by attribute, such as:
>
> struct bar {
> char *array __attribute__ ((counted_by(__self.count)));
> int count; }
>
> In the above code, when "__self.count" is referred, its declaration is not
> available,
> compiler doesn't know its type yet.
>
> If it is a regular global or a local variable, this is a source code error, C
> FE reports
> an error and aborts. User should fix this coding error by adding the
> declaration
> of the variable before its first reference in the source code.
>
> Theoretically, in C, we should treat this as a source code error too.
> However, due to existing cases in the application (i.e, Linux Kernel), in
> order to
> avoid the source code change which might be painful or impossible due to
> existing ABI, can we accept such cases and handle it in compiler?
>
> I think this might be doable during the implementation of the counted_by
> attribute
> in C FE:
>
> A. when C FE parses the new keyword __self, the whole containing structure has
> not yet been seen completely, as a result, the FE has to insert a placeholder
> for
> __self, and delay the real IR generation after the whole structure being
> parsed.
> So, a small late handling ONLY for this placeholder _cannot_ be avoided.
>
> B. Then during this late handling of the placeholder, the C FE already parses
> the
> whole structure, the declaration of the field is known at that time, the
> forward
> reference issue can be resolved naturally.
>
> This can be illustrated in the following small example:
>
> struct bar {
> char *array __attribute__ ((counted_by(__self.count)));
> /* We haven't encountered 'count' yet, so we assume it's something like
> 'size_t' for now when inserting the placeholder for "__self". */
> int count;
> }; /* At this point, we know everything about the struct, we can handle
> the placeholder for "__self" and also go back and use 'int" for
> the type to refer count */
>
>
> Appendix A: Scope of variables in C and C++
> --The hints to the design of counted_by in C
>
> Scope of a variable defines the region of the code in which this variable can
> be accessed and modified.
>
> 1. What's common on the scope of variables between C and C++?
>
> **First, there are mainly two types of variable scopes:
>
> A. Global Scope
> The global scope refers to the region outside any function or block. The
> variables declared here are accessible throughout the entire program
> and are called Global Variables.
>
> B. Local Scope
> The local scope refers to the region enclosed between the { } braces,
> which represent the boundary of a function or a block inside functions.
> The variables declared within a function or a block are only accessible
> locally inside that function or that block and other blocks nested inside.
>
> NOTE 1: the {} brace that mark the boundary of a structure/class does
> not change whether the current scope is global or local.
>
> **Second, if two variables with same name are defined in different scopes,
> one in local scope and the other in global scope, the precedence is given
> to the local variable:
>
> [opc@qinzhao~]$ cat t1.c
> // Global variable
> int a = 5;
> int main() {
> // Local variable with same name as that of
> // global variable
> int a = 100;
> // Accessing a
> __builtin_printf ("a is %d\n", a); return 0;
> }
> [opc@qinzhao~]$ gcc t1.c; ./a.out
> a is 100
> [opc@qinzhao~]$ g++ t1.c; ./a.out
> a is 100
>
>
> 2. What's different on the scope of variables between C and C++?
>
> C++ has 3 additional variations of scopes:
>
> A. Instance Scope (member scope):
>
> The instance scope, also called member scope, refers to the region inside
> a class/structure but outside any member function of the class/structure.
> The variables, i.e, the data members, declared here are accessible to the
> whole class/structure. They can be accessed by the object (i.e., the
> instance)
> of the class/structure.
>
> [opc@qinzhao~]$ cat t2.C
> struct foo {
> int bar1(void) { return m; }; // m refers to the member variable
> int bar2(void) { int m = 20; return m; }; // return m refers to the
> local variable m = 20
> int bar3(void) { int m = 30; return this->m; }; // this->m refers to
> the member variable
> foo (int val) { m = val; }; // m refers to the member variable
> int m; // Member variable with instance scope, accessible to the whole
> structure/class
> };
>
> int main ()
> {
> struct foo f(10);
> __builtin_printf (" bar1 is %d \n", f.bar1());
> __builtin_printf (" bar2 is %d \n", f.bar2());
> __builtin_printf (" bar3 is %d \n", f.bar3());
> return 0;
> }
> [opc@qinzhao~]$ g++ t2.C; ./a.out
> bar1 is 10 bar2 is 20 bar3 is 10
>
> Explanation: The member variable "m" is declared inside the structure "foo"
> but
> outside any member function of "foo", it has instance scope. This variable is
> visible to all the member functions of the structure "foo". when there is a
> name
> conflict with a local variable inside a member function, for example, "bar2”,
> the local variable has higher precedence. When trying to explicitly refer to
> the
> member variable in the member function, adding the C++ "this" pointer before
> it, for example, "bar3”.
>
> NOTE 2: the {} brace that marks the boundary of a structure/class changes the
> variable scope to "instance scope" in C++.
>
> B. Static Member Scope
>
> The static member scope refers to variables declared with the static keyword
> within the class/structure. These variables can be accessed using the class
> name without creating the instance.
>
> [opc@qinzhao~]$ cat t3.C
> struct foo {
> static int m; // Static member variable with static member scope,
> // accessible in whole structure/class
> };
> int foo::m = 10;
> int main ()
> {
> __builtin_printf (" foo::m is %d\n", foo::m);
> return 0;
> }
> [opc@qinzhao~]$ g++ t3.C; ./a.out
> foo::m is 10
>
> NOTE 3: static member in structure is not available in C.
>
> C. Namespace Scope
>
> A namespace in C++ is a container that allows users to create a separate
> scope
> where the given variables are defined. It is used to avoid name conflicts and
> group
> related code together. These variables can be accessed using their namespace
> name and scope resolution operator.
>
> [opc@qinzhao~]$ cat t4.C
> namespace foo {
> int m = 10; // Namespace scope variable
> };
> int main ()
> {
> __builtin_printf (" foo::m is %d\n", foo::m);
> return 0;
> }
> [opc@qinzhao~]$ g++ t4.C; ./a.out
> foo::m is 10
>
> NOTE 4: namespaces are not available in C language.
>
> 3. A simple summary comparing C to C++
>
> A. there are only two variable scopes in C:
>
> global scope
> local scope
>
> all the other 3 variant variable scopes in C++,i.e., instance scope (member
> scope),
> static member scope, namespace scope, are not available in C.
>
> Since there is no static member and namespace in C language, accessing to
> static
> member variables of a structure or variables declared in another namespace is
> not needed in C at all.
>
> NOTE 5: However, accessing the member of a structure inside the structure is
> needed for the purpose of counted_by extension in C.
>
> B. the {} brace that represents the boundary of the structure does not change
> the
> scope of the variable in C since C doesn't have instance scope (i.e.,member
> scope);
>
> The following examples can show these limitation in C language.
>
> C currently support variable length array (VLA), whose array size could be a
> variable expression. VLA is only supported in local scopes in C.
>
> [opc@qinzhao~]$ cat t5.c
> void boo (int k)
> {
> const int n = 10;
> struct foo {
> int m;
> int a[n + k];
> };
> }
> [opc@qinzhao~]$ gcc t5.c -S
>
> Explanation: This is good. The {} brace that marks the boundary of the
> structure "foo”
> does NOT change the scope of the variable n and k, their definitions reach
> the
> declaration of the array member field a[n + k].
>
> However, when changing the testing case as:
> [opc@qinzhao~]$ cat t6.c
> void boo (int k)
> {
> const int n = 10;
> struct foo {
> int m;
> int a[n + m];
> };
> }
> [opc@qinzhao~]$ gcc t6.c -S
> t6.c: In function ‘boo’:
> t6.c:6:15: error: ‘m’ undeclared (first use in this function)
> 6 | int a[n + m];
> | ^
>
> Explanation: C does not have the concept of instance scope (member scope),
> there is no syntax provided to access the instance scope (member scope)
> variables inside the structures. Therefore, the reference to the member
> variable
> "m" inside the declaration of the array member field a[n + m] is not visible.
>
> 4. What's the possible approaches for the counted_by attribute as a C
> extension.
>
> The major thing for this extension is:
> Adding a new language feature in C to access the member variables inside a
> structure.
>
> Based on the previous comparison between C and C++, there are two possible
> approaches:
>
> A. Add a new variable scope: instance scope (member scope) into C
>
> The definition of the new instance scope of C is:
>
> The instance scope, also called member scope, refers to the region inside a
> structure.
> The variables, i.e, the members, declared here are accessible to the whole
> structure.
> They can be accessed by the object (i.e., the instance) of the structure.
>
> The {} brace that marks the boundary of a structure will change the variable
> scope
> to "instance scope"; a variable name confliction between other scopes
> (including global/local) and instance scope will give precedence to instance
> scope.
>
> The compiler's implementation on this approach could be:
> ** a new variable scope, "instance scope" is added into C FE;
> ** the "instance scope" has the higher precedence than the current
> global/local scope;
> ** the {} brace for the boundary of a structure is the boundary for the
> "instance scope";
> ** a member variable that is referenced inside this structure could be
> treated as this->member.
> ** reference to a global variable inside the structure need a new syntax.
>
> B. Add a new syntax to access instance scope (member scope) variable within
> the structure while keeping C's default scoping rules.
>
> The {} brace that marks the boundary of a structure will NOT change the
> variable
> scope. There are still only two variable scoping, global and local.
>
> In order to explicitly access a member inside a structure, a new syntax need
> to
> be added. This new syntax could reuse the current designator syntax in C
> (prefixing the member variable with "."), or adding a new keyword similar as
> "this”,
> such as, "__self", and prefixing the member variable with “__self."
>
> With the above approach A, we can keep the current syntax for counted_by;
> but not sure how easy to extend it for simple expression and nested structure.
>
> However, the major problem with this approach is: it changes the default
> scoping
> rule in C languages. this additional variable scoping will break existing
> legal C code:
>
> [opc@qinzhao~]$ cat t7.c
> void boo (int k)
> {
> const int n = 10; // a local variable n
> struct foo {
> int n; // a member variable n
> int a[n + 10]; // currently, this n refers to the local variable n.
> };
> }
>
> When we take the approach A, within the structure "foo", the VLA a[n+10]
> will refer to the member variable n, but not the local variable n anymore.
> The existing code with VLA might work incorrectly.
>
> You can argue to only add the new variable scope for counted_by attribute,
> not for VLA, then how to handle the following case:
>
> [opc@qinzhao~]$ cat t8.c
> void boo (int k)
> {
> const int n = 10; // a local variable n
> struct foo {
> int n; // a member variable n
> int a[n + 10]; // for VLA, this n refers to the local variable n.
> char *b __attribute__ ((counted_by(n + 10)))
> // for counted_by, this n refers to the member variable n.
> };
> }
>
> This will be a disaster.
>
> So, I think that the approach A is not the right direction for a C extension.
>
> With the above approach B, a new syntax need to be implemented,
> and all the previous source code change in the application need to be
> modified.
>
> But I still think that approach B is the right direction to go.
> (Please refer to:
> ******Scope of variables in C++
> https://www.geeksforgeeks.org/scope-of-variables-in-c/
> ******Scope of variables in C
> https://www.geeksforgeeks.org/scope-rules-in-c/)
>
>
> Appendix B: An example in linux kernel that the global cannot be "const"
> qualified
>
> In linux kernel, the globals that will be referred inside counted_by
> attribute don’t
> change value, but they cannot be marked "const" since they are initialized
> during
> very early kernel boot.
>
> they _become_ architecturally read-only. i.e. they are in a memory region
> that
> is flipped to read-only after boot is finished.
>
>
>
>
>
>