• Advertisement

Archived

This topic is now archived and is closed to further replies.

What do extern and static really do?

This topic is 5104 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was going to only ask about extern, but if I could get some info on what declaring a variable as static really does, that''d be great too. By variable, here, I do not mean a member of a struct or class. I know what that does; just lettin you know. Anyway, if I declared a variable in C as extern int krpulskitanivic; // ignore name what would that really do to the variable? This is an old question that I don''t recall ever asking about. ~Resist Anna Nichole Smith

Share this post


Link to post
Share on other sites
Advertisement
it tells the compiler that there is a global variable called "krpulskitanivic" elsewhere in another file (an ''external'' file to this one) so you can then use that variable in that file, even though it is defined in another.
And static means that if its say a local variable in a function, it wont lose its value the next time the function is called, eg:

  
int GetNum()
{
static int Num = 0;
return Num++;
}

the first time you call it it will return 0, then if you call it again it will return 1 (not 0 had it not been static), then the next time 2, then 3 and so on.

Share this post


Link to post
Share on other sites
I know that much about static, but what if you declare an object that is global or defined in a source file (versus a header file).

For instance:

//foo.h
typedef unsigned int FooIndex;

void InitFoo ( FooIndex id );



//foo.c
#include "foo.h"

struct __FOO
{
// members
} static foo[1000];

void InitFoo ( FooIndex id )
{
// initialize foo members
}

Share this post


Link to post
Share on other sites
The effect of static depends on where the variable is. If a global variable or function is declared static, it has file scope; it can''t be used anywhere except the file it was defined in. If a variable inside a function is declared static, it has static storage duration; it''ll retain its value and address over all calls to that function. If that makes sense.

quote:
~Resist Anna Nichole Smith


The cow lady compels you.

Share this post


Link to post
Share on other sites
1) headers are just files that are inserted into your source where they''re #included.
2) one more thing: static variables go into the BSS, so they''re initialized to 0.

Share this post


Link to post
Share on other sites
quote:
Original post by Jan Wassenberg
1) headers are just files that are inserted into your source where they''re #included.

At its simplest. In most medium-to-large sized projects, however, multiple files include the same header and inclusion guards are necessary, etc, etc. Header files and the #include directive are legacy machanisms for resolving C and C++''s forward declaration requirements. They need to go.

quote:
2) one more thing: static variables go into the BSS, so they''re initialized to 0.

...For integer or integer-convertible types. For some user-defined types, the default constructor may be invoked.

Share this post


Link to post
Share on other sites
quote:
Original post by Jan Wassenberg
2) one more thing: static variables go into the BSS, so they're initialized to 0.

BSS is irrelevant to C and C++.

[edited by - SabreMan on December 5, 2002 7:16:35 AM]

Share this post


Link to post
Share on other sites
quote:
Oluseyi
At its simplest. In most medium-to-large sized projects, however, multiple files include the same header and inclusion guards are necessary, etc, etc.

Sure. But the #included files are still just inserted into the source file.

quote:
Oluseyi
Header files and the #include directive are legacy machanisms for resolving C and C++''s forward declaration requirements. They need to go.

What?!

> ...For integer or integer-convertible types. For some user-defined types, the default constructor may be invoked. <
Yes yes.


> 1. BSS is irrelevant to C and C++.
nope.

> 2. BSS is the uninitialised data segment.
weeell - I''d say the name BSS is overused.
In my case, VC stuffs static data into a segment it calls _BSS, which is zeroed out.

Share this post


Link to post
Share on other sites
quote:
Original post by Jan Wassenberg
> BSS is irrelevant to C and C++.
nope.

Yep. It has absolutely no bearing on the semantics of a C or C++ program. I'm led to believe there are platforms supporting C that have no concept of BSS, but the Standard mandates a file-scope static must behave in the same way.
quote:

> BSS is the uninitialised data segment.
weeell - I'd say the name BSS is overused.

I deleted that since my comment was irrelevant to what you said.

[edited by - SabreMan on December 5, 2002 7:27:28 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Jan Wassenberg
Header files and the #include directive are legacy machanisms for resolving C and C++''s forward declaration requirements. They need to go.
What?!

Think about it. If module forward declaration requirements were eliminated (trivial; many languages have done so already - Java and Python spring instantly to mind), then we can declare and define all classes, algorithms and so forth in implementation (.cpp) files - which eliminates the need for export and neatly sidesteps the implementation complexities related to that keyword. Cross-referenced structures (A contains a pointer to B and B contains a pointer to A) become easier to declare (yes, they''re easy once you understand the limitations, but it trips up new users and is an unnecessary complexity). Only one file needs to be maintained per module.

The immediate downside that will be pointed out is that the elimination of header files will (supposedly) make it impossible to work with static libraries, traditionally distributed with header files. Actually, all that is needed is a packaging method such that a static library package can export it''s interface to other code modules, and good IDEs will present this information to the developer in an accessible form. This packaging format doesn''t even need to be standardized, since static libs and the like tend not to be standardized anyway.

Now that you''ve thought about it, don''t you think it''s perfectly logical?

Share this post


Link to post
Share on other sites
While we''re on the topic, what kind of performance overheads do you get from statics? Sounds like it would take some more memory, or is it just equivalent to having an extra global variable?

Share this post


Link to post
Share on other sites
quote:
Original post by Oluseyi
Think about it. If module forward declaration requirements were eliminated (trivial; many languages have done so already - Java and Python spring instantly to mind)

It''s not at all trivial to make a C++ compiler which doesn''t require forward declarations. For starters, you''d have to describe a protocol by which a compiled module exports it''s public interface, so that external references may fix-up to those exports. Effectively, you''d have a further blurring of the line between compiler and linker, and you''d have to come up with a new object code format.

Then, you''d have to iron out the problem brought about when you encounter a reference to something which hasn''t yet been declared. In the case of a value-type, you need to have the full definition. Python and Java both sidestep that by not allowing value-types - everything is a reference. While it is possible to do this, it''s not a trivial matter to retro-fit into an existing language.
quote:

Now that you''ve thought about it, don''t you think it''s perfectly logical?

It is, but it''s not trivial.

Share this post


Link to post
Share on other sites
quote:
Original post by NeverSayDie
While we''re on the topic, what kind of performance overheads do you get from statics?

Compared to what, exactly?

Share this post


Link to post
Share on other sites
You don''t get any overhead, its just a lookup. If you look at the disassembly, its something like (made up, dunno what the exact syntax is):
mov eax, [00402134]
exactly the same as with a global (since a static is - to the compiler - more or less just a global). Local variables are referenced with respect to esp (or is it ebp?), but AFAIK, theres no extra cycles in esp-4 compared to a static for example. A class'' member variable requires a pointer dereference (the this pointer) and an addition (if you''re using a variable other than the first in the class), which is an extra speed hit.

Although in all, a few extra cycles wont cost you a significant amount.

Share this post


Link to post
Share on other sites
quote:
Original post by elis-cool
...the first time you call it it will return 0, ...


Nit picking, but wouldnt it return 1 the first time you call it?

Share this post


Link to post
Share on other sites
2 differences (x86 specific):
1) instruction size - mov reg, [ebp+ofs] is 3 bytes [-128 <= ofs <= 127, of course]; mov reg, [addr] is 5-6 bytes (extra ModR/M if reg != eax)
2) locality - auto vars end up on the stack, while static data resides in the data segment or BSS. You get one cache line for the params / return address anyway, and your globals might just be ordered like:
important_var_1
huge_constant_array
important_var_2
=> better keep variables on the stack, if possible.

Share this post


Link to post
Share on other sites
Dark_Streak:

It''s a post-incriment. The variable is used THEN incremented.


int blah()
{
static int whatever = 0;
return whatever++;
}


That will return 0,1,2,3,etc.


int blah()
{
static int whatever = 0;
return ++whatever;
}


That will return 1,2,3,4,etc.

Share this post


Link to post
Share on other sites
quote:
Original post by Some Guy
Okay, what is BSS?








--{You fight like a dairy farmer!}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Some Guy
Okay, what is BSS?


Executable files (whatever they are called on their OS) these days are split up into section (usually .text {=code}, .data and often .bss or .rdata). The .text & .data sections usually have data in them in the exe file which is loaded to particular positions in memory. The BSS section usually has no data associated with it in the file, just a size & location is specified, so when the exe is loaded the OS creates a block of memory for it at the required location of the requisite size and in most OS''s the specification demands that the memory bytes are zero''ed out. As the C & C++ specs say that built-in integer convertable types that are global variables and have no initial value specified are zero, the linker/compiler often place these variables in the bss section.

Share this post


Link to post
Share on other sites

  • Advertisement