Does the static keyword affect scope?
Asked Answered
J

5

7

In C89, does the static keyword affect scope?

My software lead told me:

"A variable marked static at the top of a file doesn't technically have global scope any longer. Static is a scope qualifier as well as a storage keyword. Scope is a concept that covers visibility of symbols, though visibility is automatically compiled to have storage duration intrinsically tied in by almost all languages. By this I mean that you can't name a scope that doesn't also define the storage duration in C/C++. Expression scope is not user defined and in C/C++ covered by l-param and r-param Block scope is fully lexical in C/C++ by user defined bodies Function scope is fully lexical in C/C++ by user defined bodies and declarations File scope does not technically exist in C/C++, as globals and module scope take over depending upon lexicon Module scope is keyword defined using static in C/C++, other scope lexicon change the rules for access but the visibility remains module based Global scope is the default in C/C++ when no other scope applies and is lexically controlled by the extern keyword The issue is that static is not JUST a scope qualifier as a keyword. It is a scope qualifier AND a memory keyword."

I'm confused. I've always thought that static relates to the visibility between translation units and the storage duration of the variable. Both of which are unrelated to scope. Is this not the case? Is the static/scope relationship different in C++?

Jordans answered 10/6, 2016 at 16:16 Comment(6)
"Module"? C doesn't have modules.Jenkins
You probably are better to have this argument with your lead, not us.Paulie
I feel very sorry for your team. This person clearly does not not know what he/she are talking about. Also I wouldn't be using C89 to teach C.Marasmus
Yes, the static keyword serves two distinct purposes in C. That's about the only thing this guy seems to have right. The number of times he uses "C/C++" like that means something is a good clue. There is no such thing as "global scope" in C. File scope is the largest possible scope that you can have, so static is not going to affect the scope of a symbol. It affects storage duration and linkage.Miele
It sounds like your software lead is as confused as you and is blustering his way through to make it look like he knows what he's talking about.Anticlockwise
There is no language "C/C++". If your lead does not know that and cover the differences, she is definitively in the wrong position. He also seems to confuse linkage, scope and lifetime. What is a "memory keyword", btw? I did not find this is the standard.Kilburn
M
7

A variable marked static at the top of a file doesn't technically have global scope any longer.

"Global scope" is not a concept that exists in C. The proper term is file scope. In C++, a similar concept exists called the global namespace. It seems that overtime people combined the two terms.

Static is a scope qualifier as well as a storage keyword.

static is not a scope qualifier, it is a storage-class specifier. static can affect linkage and storage duration, but not scope.

Scope is a concept that covers visibility of symbols, though visibility is automatically compiled to have storage duration intrinsically tied in by almost all languages.

Scope has nothing to do with visibility of symbols (in the linker sense). Linkage does (hence why it's called linkage). The second clause is gibberish.

By this I mean that you can't name a scope that doesn't also define the storage duration in C/C++.

This sentence also doesn't make sense. Consider a local static variable at block scope. It has static storage duration even though block scope defines automatic storage variables.

Expression scope is not user defined and in C/C++ covered by l-param and r-param

"Expression scope" makes no sense. "l-param" and "r-param are also meaningless words.

Skipping the part about "lexical" and "modules" because it makes zero sense.

The issue is that static is not JUST a scope qualifier as a keyword. It is a scope qualifier AND a memory keyword.

Again, static has nothing to do with scope or memory. Using this oversimplified explanation leaves out basically all other aspects of storage duration, scope and initialization so it just plain doesn't work.

Marasmus answered 10/6, 2016 at 16:47 Comment(1)
I like this answer.Contingency
N
3

Section 6.2.1 of the C11 standard defines what "scope" means:

For each different entity that an identifier designates, the identifier is visible (i.e., can be used) only within a region of program text called its scope. Different entities designated by the same identifier either have different scopes, or are in different name spaces. There are four kinds of scopes: function, file, block, and function prototype. (A function prototype is a declaration of a function that declares the types of its parameters.)

Section 3.1.2.1 of the C89/90 spec is almost identical:

An identifier is visible (i.e., can be used) only within a region of program text called its scope . There are four kinds of scopes: function, file, block, and function prototype. (A function prototype is a declaration of a function that declares the types of its parameters.)

So there is no such thing as global scope, at least as far as the C standard is concerned. An identifier defined outside of any function or block has file scope, and the presence or absence of static has no effect on that, only on the symbol's linkage, which is something completely different (but which your lead may be conflating or confusing with the term "scope").

Neurosis answered 10/6, 2016 at 16:42 Comment(2)
The one situation where static doesn't affect linkage is for a class data member in C++.Marasmus
@user6412786: in most situations it doesn't affect linkage -- the one place it does is for identifiers at file scope.Neurosis
H
1

Your informant is confused. static has no impact on scope whatsoever.

File scope is a misnomer because you can construct multifile translation units using #include directives or other hypothetical implementation-dependent facilities. Global scope is also a misnomer because a program can be made up of multiple translation units. Modules are still not part of the language.

static can affect linkage, but that is a different concept to scope.

Heavyladen answered 10/6, 2016 at 16:26 Comment(3)
"File scope" is not a misnomer. It's used explicitly by the C standard. "Global scope" is used interchangeably in informal speech, but the C++ standard explicitly refers to "global namespace". I also wouldn't call them misnomers unless you're implying the C and C++ standards get them confused.Marasmus
Part 2: "file" or "global" scope exists for one translation unit. "#include" is a copy/paste operation, it's part of the translation unit. See 2.1 "Separate Translation" in C++.Marasmus
@user6412786: I know that the C standard uses the term "file scope" but it is formally defined in terms of a translation unit, not a file, so yes, I do believe the term is a misnomer. (Admittedly, "translation unit scope" would be cumbersome.) As you say, C never refers to global scope and some people who use the term are in fact confused about what global might mean. Indeed, the confusion evidenced here between scope and visibility is a instance. There is no confusion in the standard w.r.t. "global namespace"; that namespace is in fact global, usually implemented with name-mangling.Heavyladen
A
0

The keyword static has several uses in C. For instance in a C source file at the top you might have:

#include <stdio.h>
//  .. other includes and comments and stuff

int  globallyVisibleInt = 0;    // a variable that other compilation units can see
static int fileVisibleInt = 0;  // a variable visible in the file from this point

The variable fileVisibleInt is created and initialized at the time the application loads however if you were to try to access it from some other compilation unit, you would get an error from the linker when trying to link.

You can also use static in a function to create a variable that will exist and maintain state.

int myFunc (int k)
{
    static int mySavedInt = 0;   // create and initialize a permanent int variable

    if (k > 10) {
        mySavedInt = k;  // use the variable to save a value for the next time function is called
    } else if (mySavedInt > 22) {
        // do some stuff
    }
}

The point at which a static variable is visible to the other source in the file is at the point where it appears in the source file and it's visibility is governed by the various scope rules. For instance a static defined in a function is only visible in that function or if a static is used in some other, more reduced scope such as an if or a for then it is a permanent variable that is only visible in that scope.

There are various phrases which are common usage but are not necessarily technically accurate or something you would find in the standards. For instance the phrase "global scope" means to me that the thing is visible outside of the compilation unit. By "module" I would assume function. For most day to day activities looseness of language works just fine.

In C++, static can be quite a bit different depending on whether you are using C++ constructs such as class and using static as a qualifier for methods and members or if you are using it the old C way.

See also:

File Scope and Global Scope: C & C++.

Why file scope static variables have to be zero-initialized?

Dr. Dobbs: Scope Regions in C++.

Aribold answered 10/6, 2016 at 17:17 Comment(0)
S
0

Actually I agree with your Software Lead in the concept not the terminologies ! Let's consider the following question:-

Q : Using static keyword with variable affects what ?

(Variable Scope - Variable Lifetime - Both)

A : in my opinion it affect both, but how ?

conside we have main.c , main2.c , main3.c

in main.c we declared static int x;

in main2.c we declared extern int x;

in main3.c we declared int x = 3;

in this case, main3.c and main2.c will share the same resource x, but another diffrent x is created and only seen by main.c only (this case shows how static keyword specified the VARIABLE SCOPE in which x acts for main.c)


Now, let's consider another senario in which a function that have a variable defined locally within it, so it is local by defination.

Using static keyword with that variable will result in retaining the variable values across the run time (during function several calls, it will just build on the value from the last call), which affects VARIABLE LIFETIME or in other words storage-class. Comparing this to another local variable that have shorter life time limited to the period inwhich function is being executed only.


Maybe that is what your Lead meant


code used:

main.c

#include <stdio.h>
#include"main2.h"
#include"main3.h"
static int x = 1;
int main()
{
    int r = x;
    printf("%d \n",r);
    int a = func2();
    printf("%d \n",a);
    return 0;
}

main2.c

extern int x;
volatile int func2()
{
    int r = 0;
    r = x;
    return r;
}

main2.h

#ifndef MAIN2_H_
#define MAIN2_H_
volatile int func2(void);

#endif /* MAIN2_H_ */

main3.c

int x = 5;
volatile int func3()
{
    int r = 0;
    r = x;
    return r;
}

main3.h

#ifndef MAIN3_H_
#define MAIN3_H_
volatile int func3(void);

#endif /* MAIN3_H_ */
Shalloon answered 1/3, 2023 at 4:33 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.