Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
193 views
in Technique[技术] by (71.8m points)

c++ - file scope and static floats

I've run into an interesting problem in an AI project of mine. I'm trying to format some debug text and something strange is happening. Here's a block of code:

    float ratio = 1.0f / TIME_MOD;

TIME_MOD is a static float, declared in a separate file. This value is modified based off of user input in another class (I have verified that the value is changed while still debugging within the scope of the "input" function), but whenever I try to divide by it in my outer loop I get the same number. (1 divided by the initial value of TIME_MOD).

Am I missing something regarding static variables and file scope?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think there is some confusion with the word "static". We have a keyword static that does different things in different contexts and we use the word "static" to name one of three classes of "storage durations". In some contexts static does not control the storage duration of objects but only "linkage" which is probably the main reason for the confusion.


Storage durations

A storage duration is a property of an object.

  • The memory of an object with static storage duration is allocated once and once only. Initialization depends on the kind of object and where it is defined. Once it is initialized, it generally stays alive until the execution of main ends. Objects you declare and define at global/namespace scope always have a static storage duration.

  • Objects with automatic storage duration can only be defined inside a block in functions. Such an object is created when execution reaches the definition. This can happen multiple times (recursion) which creates multiple objects. When execution leaves the block the objects are automatically destroyed.

  • Dynamically allocated objects have a dynamic storage duration. In this case the user controls the life-time of the objects via new, new[], delete, delete[] etc.


Linkage

Internal vs external linkage is about visibility of names across translation units. If you declare something with external linkage you introduce a name that can be used in other translation units as well to refer to the same entity as long as those other TUs contain the proper declaration (usually contained in a header file). If you define something with internal linkage you can't access it from another translation unit by name. You can even define multiple entities with the same name (one per TU) as long as you have no more than one with external linkage.


The keyword "static"

The effect of static depends on the context:

  • If you declare or define an object at global/namespace scope it is always an object with "static storage duration". The use of the keyword static at global/namespace scope doesn't affect the storage duration at all. Instead, it affects linkage. It declares the entity -- which might be a function as well -- to have internal linkage. So, the storage class specifier has been "misused" to do something completely different: enforce internal linkage. It's sort of the opposite of extern in this context. In C++ you can achieve the same effect with an anonymous namespace. You are encouraged to prefer anonymous namespaces over static to "minimize confusion".

  • static at class scope can be used to declare objects with static storage duration in the scope of the class. There's only one such variable and not one for each object.

  • static at function scope can be used to declare objects with static storage duration that is lazily initialized


If you say "static variable" it's not clear what you mean exactly. Do you refer to the "static storage duration" or "internal linkage"?

If you want to share a "global" variable across translation units you have to declare it in a header file as an entity with external linkage and define it in exactly one translation unit. Note that the keyword static is not used:

// myheader.hpp
extern int k; // declaring an int variable with external linkage

// foo.cpp
#include "myheader.hpp"
int k;        // defining an int variable with external linkage

// bar.cpp
#include "myheader.hpp"
int main() {
    return k;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...