I've heard there are differences between languages about the meaning of the keyword static, but I've not found a good list that consolidates those differences.
Here's what I know about the meaning of static in C++:
For local static variables within a function, the variable is initialized at startup and the value is saved across function calls.
Static data members are shared among all instances of a class. In other words, there is only one instance of a static data member. Static data members must be initialized at file scope.
Static member functions have access only to static members.
In recursive code, a static object or variable is guaranteed to have the same state in different instances of a block of code.
Static objects and variables defined at file scope only have internal linkage. No other files may use them.
How does the meaning of static change in other languages?
C
The keyword can change either the linkage or the duration (lifetime) of an object.
Variables are always initialized to 0
Functions have internal linkage.
If declared in file level scope: variables have internal linkage and static duration (i.e. exists throughout the lifetime of the program)
If declared in block scope: variables have no linkage but static duration
There can multiple declarations of the same static variable in a translation unit. However, note that they must be the same. E.g: at file-level scope:
int a; // a has external linkage
static int a; // a now has static linkage
// same as if you wrote: static int a = 0;
//...
static int b; // static linkage
extern int b; // extern loses its meaning, b still has internal linkage
//...
extern int b; // b has external linkage
static int b; // error
//...
void func() {
static int x; // automatic linkage, static duration
// same as if you wrote: static int x = 0;
}
C++
At file level scope the usage has been deprecated for both variables and members in favor of anonymous namespaces. Exists only as compatibility
Variables still get default initialized (as in C) to 0
"6.7 The zero-initialization (8.5) of all local objects with static storage duration (3.7.1) or thread storage duration (3.7.2) is performed before any other initialization takes place [...] "
Variables have static storage duration unless accompanied by a thread_local specifier (from C++0x onwards)
There can be only one definition of a static in a translation unit
Member variables/functions mean they are properties of the class and not the instances
Legal access syntax: instance.property or Class::property
Static member functions can only access only static member variables
No this pointer for such functions
Non-static members can however access any static member
At file level objects have internal linkage except for class members which have a class scope
Class members need to be defined either in the class declaration or outside explicitly via class name and scope resolution operator
Cannot use this in a static method
ActionScript
Class methods as in C++
cannot use this or super in a static method
Accessed only through class name and not instance name
Not inherited
Derived classes however have access to bases' static properties
Variables that are declared with both the static and const keywords must be initialized at the same time as you declare the constant
Object Oriented Design
The Singleton design pattern is considered by many as a glorified static object
Used in Factory design pattern
I may have missed a lot of other things -- feel free to chip in.
In Delphi the static keyword is used exclusively for defining class methods. In Delphi a normal class method can be declared virtual and overridden in a subclass. Additionally Delphi has a self variable, similar to the this pointer in other languages. However in a class method the self points to the class in which the method is called instead of an instance.
Declaring a class method static means:
It cannot be overridden in a subclass
It does not have a self pointer
This means a static class method can only access class members in the class it was defined in, while a normal class method can access overridden class members in derived classes.
There are other informal uses of static in the Delphi documentation usually referring to a feature unchangability (is that a word?). For instance a static array vs a dynamic array. All instance methods in Delphi are static unless declared otherwise.
In C# it pretty much always means: "related to a type rather than an instance of the type".
In VB.NET, a Static variable is just like a C++ local static variable.
However, there is no class-wide Static; use Shared instead.
In C# there are 3 ways a static keyword can be used:
On class definition, which means the class will only expose static members and cannot be instanciated
On a class member, which means that the member can be called without having to instanciate the class.
On a constructor, which means that the static constructor will allways be called before a static member is called. (Those are mostly performance bottlenecks and therefore not recommended)
Hope this helps.
Python has the decorator #staticmethod, which when applied to a class member, makes the method available on the class rather than instances, and passes no automatic arguments to the method. The #classmethod decorator performs a similar function, but passes the class as the first argument, making it much more useful.
In C, static flags a function or global variable as local to the file its located in.
It's kinda like private in other languages. Sorta.
If it's in a function, then static preallocates that variable in the data section of the binary, rather than on the stack at run time.
In VB.NET static is used procedure level to mean the variable is associated with all executions of the procedure (it's preserved from call to call). That's a bit of an arcane usage in an Object-Oriented application though.
The counterpart is "Shared" which means the method or member is type level (you don't need an instance to access it).
Wikipedia summarizes many different meanings of static:
Static Methods, static variables, static typing.
Related
I understand objects are just chunks of data, where the first member variable starts at the exact same location as the object. For example, an object whose pointer points to location 0x0100, will also have the first member variable located at 0x0100.
But how do interfaces in a language like Java, which have no implementation, work? These are purely abstract types.
As in, how does a CPU or compiler know to interpret Object A as Interface X, or Object B as Interface X and Y depending on the context? Is this something done at the compiler level, that has no bearing on the lower level interpretations?
You need to understand that in languages like Java & C#, the first member of an instance is a pointer to a class-shared object; this object participates in identifying the actual class that was instantiated, in checking down casts, in determining the overrides to call for virtual method invocations, and in determining the implementation to use for interface method invocations.
But how do interfaces in a language like Java, which have no implementation, work? These are purely abstract types.
Sure interfaces themselves are "abstract", but the interface methods are always invoked on instances of concrete classes (that implement the interfaces), so that's where implementation comes in.
The language treats interfaces, similar to classes (both abstract and concrete), assigning their methods to indexes, and using those method indexes in lookup (at the class-shared object of the instance) to find the actual implementation to invoke.
So, key is that the interface methods are given positions in the array of method references within the class-shared object of each instantiable type (that implements the interface), such that each class could have a different implementation of an interface method.
Let be the interface
interface A {
void hello();
void hello2();
}
We can immediately define the function with the interface as a parameter
void function example (i A) {
i.hello();
i.hello2();
}
What exactly will be compiled here?
Interface function calls.
And how is this possible?
It is possible because an interface type variable contains as many pointers to functions as there are functions defined within the interface.
Interface in short is a structure that contains pointer variables to functions.
Now any class that implements the interface can be assigned to it. With this allocation, pointer variables to functions (of the interface) are "filled" with the addresses of the functions located in the vmtable (of the class).
This means that an interface variable always sees the functions defined in it and only them (unless casted to the class)
----------------------------------
So for example if a class implements the interface.
class B implements A {
public int justAField;
#Override
public void hello() {
System.out.println("Hi.");
}
#Override
public void hello2() {
System.out.println("Hi2.");
public void anotherMethod() {
System.out.println("Another one.");
}
}
We can have
example(new B())
The calls i.hello(); i.hello2(); trigger the corresponding functions of the class
I am learning about virtual function tables and their representation by analyzing a binary of a simple program written in Visual C++ (with some optimizations on).
A few days ago I asked this question while being stuck on virtual method table content with identical COMDAT folding on.
Now I'm stuck on something else: whenever I analyze a class, I need to find its Virtual Method Table. I can do this by finding either its RTTITypeDescriptor or _s_RTTIClassHierarchyDescriptor, finding a cross reference on it, which should lead me to the _RTTICompleteObjectLocator. When I find a cross reference to the Complete Object Locator, it is written just before the VMT (basically -1st entry of the VMT).
This approach works on some classes (their names start with C in my program). Then there are classes, that are named with I in the beginning and I am able to pair them with other classes starting with C -- for example there is class CClass and it inherits from IClass. These I-classes are probably serving as interfaces to the C-classes and thus they probably only contain abstract methods.
By searching a cross reference to Type Descriptor or Class Hierarchy Descriptor of any of the I-classes I cannot find anything -- there is no Complete Object Locator that would lead me to the VMT of the class (that should be full of references to pure_virtual call if I am correct about the all-abstract methods in the I-classes and if I understand correctly what VMT of abstract class looks like).
Why do the I-classes have no VMT? Did the compiler optimize it out because it would just be full of references to pure_virtual call and manages it in a different way?
These "interfaces" abstract classes probably have need no user written code in any their constructors and destructors (these either have an empty body and no ctor-init-list, or simply are never user defined); let's call these pure interface classes.
[Pure interface class: concept related but not identical to Java interfaces that are (were?) defined as having zero implementation code, in any member function. But be careful with analogies, as Java interfaces inheritance semantic isn't the same as C++ abstract classes inheritance semantic.]
It means that in practice no used object ever has pure interface class type: no expression ever refers to an object with pure interface type. Hence, no vtable is ever needed, so the vtable, which may have been generated during compilation, isn't included in linked code (the linker can see the symbol of the pure interface class vtable isn't used).
The documentation states that:
The nested class describes an object whose construction ensures that
the standard iostreams objects are properly constructed, even before
the execution of a constructor for an arbitrary static object.
As seen at:
https://msdn.microsoft.com/en-gb/library/fbyc90zw.aspx
But since static objects have an undefined init ordering how does ios_base::Init ensure that it runs before them?
I would hazard that the order of initialization of static variables is undefined, but the order of constructor calls for creation of an object/variable (static or not) is well defined.
The ios_base::Init class is nested in the ios_base class. So when any ios_base instance is constructed, the ios_base::Init constructor is run as well.
It doesn't matter which of the possible static instances of an object using ios_base exist or what order they run in. All that matters is that the ios_base::Init gets to run and initialize the standard streams first (all other constructor calls to ios_base::Init likely do nothing since the work is already done by the first constructor call).
My intention was to create a singleton, but do not know how to handle this in Rust, I have read this and this, but not sure if that's the way to create a simple singleton because one speaks of a "mutable singleton" and the other of a "safe-static-singleton".
A singleton is just a lazily initialized piece of static data. That means you really do want lazy-static.
Note that
For a given static ref NAME: TYPE = EXPR;, the macro generates a unique type that implements Deref<TYPE> and stores it in a static with name NAME.
which means NAME is actually akin to the constructor of the "singleton", and &*NAME is the "singleton" itself.
I am currently reading an existing code in MS Visual C++ 6.0. I notice a code pattern where they cast object into a structure.
There is a CMemory object.
CMemory a;
MY_STRUCTURE_A* a = (MY_STRUCTURE_A*)(void *)a;
MY_STRUCTURE_B* a = (MY_STRUCTURE_B*)(void *)a;
I checked the Custom memory class and it really is a class object. It does have a = operator defined but I do not think that would allow it to be reinterpreted to a structure. Why is this being done. How is an object type being cast to different objects?
Any idea why this is being done? I know there is a reinterpret_cast and I am guessing that this technique of casting to void pointer to a structure pointer is similar. But I am not sure if it is the same. Is this pattern safe casting a class object to a struct?
Note: the CMemory is just an arbritary name of the object used. It is not part of the MFC class.
Added based on Necrolis' comment.
The CMemory and it has only 3 members declared in the following order (1) char pointer, (2) int specifying the allocated memory of (1), and (3) a previous and next pointer to other instance of CMemory. It also has a lot of member method. From what I understand, even if I directly cast a class to a structure. The class would start should start with the first member variable which is the char pointer.
class CMemory {
public:
CAMemory();
... Other methods
private:
char *m_pMemory;
int m_memorySize;
... Other field
}
Going by the name of the class and the casting, CMemory is more than likely a generic memory block tag (for a GC, arbitrary hash table etc), and to access the memory its tagging requires a cast. Of course this is a "best guess", it means nothing without seeing the full code for CMemory.
Is this safe, totally not, its not only UB, but there is no check (at least in your example) as to whether the object you casting to is the object represented by the memory layout. Also, with this being C++, they should be avoiding C casts (as you have noted. the double cast is in fact to get around compiler errors/warnings, which is always the worst way to solve them).