Question regarding static

S

somenath

I am not able to understand why the following program is not throwing error.

#include<stdio.h>
static int i;
foo ()
{
static int i;
}

int main(void)
{
return 0;
}

According to my understanding both the i have local linkage so object having same linkage defined twice. If this is correct then should not the compiler throw error?

-
Somenath
 
J

JohnF

somenath said:
I am not able to understand why
the following program is not throwing error.

#include <stdio.h>
static int i;
foo () {
static int i; }
int main(void) {
return 0; }

According to my understanding both the i have
local linkage so object having same linkage defined twice.
If this is correct then should not the compiler throw error?
Somenath

I think you could have answered your own question
if you'd tried just a little harder.
Compile and run the following. Now what do you think?...

#include <stdio.h>
static int i=0;
int foo () {
static int i=0;
i = i%3 + 1;
return i; }
int main (void) {
int foo(), n=0;
for ( n=1; n<=15; n++ ) {
i = i%2 + 1;
printf("%3d: imain=%d, ifoo=%d\n",n,i,foo()); }
return 0; }
 
B

BartC

somenath said:
I am not able to understand why the following program is not throwing
error.

#include<stdio.h>
static int i;
foo ()
{
static int i;
}

int main(void)
{
return 0;
}

According to my understanding both the i have local linkage so object
having same linkage defined twice. If this is correct then should not the
compiler throw error?

Both 'i' variables have space reserved in the same region. But the name of
'i' in foo() is local to that function, and it hides the outer 'i'. So there
is no clash in names that would be an error.
 
S

somenath

I think you could have answered your own question

if you'd tried just a little harder.

Compile and run the following. Now what do you think?...



#include <stdio.h>

static int i=0;

int foo () {

static int i=0;

i = i%3 + 1;

return i; }

int main (void) {

int foo(), n=0;

for ( n=1; n<=15; n++ ) {

i = i%2 + 1;

printf("%3d: imain=%d, ifoo=%d\n",n,i,foo()); }

return 0; }


As I understand main refer to the file scope i and foo refer to the i local to itself.
So imain have the value between 1 and 2 because of the expression i = i%2 + 1; and foo return i between 1 and 3 because of the expression i = i%3 + 1;

But I was confused as both the i have local linkage so both will be stored in same region of memory then how C compiler avoids saying both i is same.

After reading Bart's article I came to know that in spite of the fact they gets placed in same region they will be hidden
to each other.

So do get my understanding little better I did this in linux environment

gcc test.c -o test

readelf -s test

41: 0000000000600954 4 OBJECT LOCAL DEFAULT 24 i
42: 0000000000600958 4 OBJECT LOCAL DEFAULT 24 i.2126

Now I think I understand that C compiler encode i differently and put in same region of memory. Is my understanding correct?
But how does C compiler learn about scope?
 
J

James Kuyper

I am not able to understand why the following program is not throwing error.

#include<stdio.h>
static int i;
foo ()
{
static int i;
}

int main(void)
{
return 0;
}

According to my understanding both the i have local linkage so object having same linkage defined twice. If this is correct then should not the compiler throw error?

The first 'i' has file scope, the second one has block scope associated
with the outermost block of foo(). Because they have different scopes,
they are different variables with the same name. Within foo, after the
second declaration of 'i', all uses of 'i' refer to that one; it's
declaration hides the file scope declaration of 'i'.
 
G

glen herrmannsfeldt

James Kuyper said:
(snip)
The first 'i' has file scope, the second one has block scope associated
with the outermost block of foo(). Because they have different scopes,
they are different variables with the same name. Within foo, after the
second declaration of 'i', all uses of 'i' refer to that one; it's
declaration hides the file scope declaration of 'i'.

There is one case where Java doesn't allow two variables with the
same name, but I forget if C has this restriction:

int i;
for(int i=0;i<10;i++) ;

Even though the second i is local to the loop, you can't have one
if there is one in the outer block. (You can still have class (static)
variables and instance variables with the same name, though.)

-- glen
 
E

Eric Sosman

I am not able to understand why the following program is not throwing error.

#include<stdio.h>
static int i;
foo ()
{
static int i;
}

int main(void)
{
return 0;
}

According to my understanding both the i have local linkage so object having same linkage defined twice. If this is correct then should not the compiler throw error?

Several responders have assured you that the two `i' have
different scopes and are different variables, but I haven't seen
anyone address the matter of linkage. "Linkage" is the mechanism
by which identifiers in distinct scopes denote the same object or
function. Scope is not the be-all and end-all of "identity," as
you can see in this example:

int foo(void) {
extern int x;
return ++x;
}

int bar(void) {
extern int x;
return x--;
}

The two `x' have different scopes, yet they refer to the same
variable because of their linkage. (I don't recommend this style,
by the way, but it's legal.)

Back to your example: The first `i', the one at file scope,
has internal linkage as you say (this is spelled out in 6.2.2p3).
But the `i' at block scope does *not* have internal linkage;
it has "none" linkage (6.2.2p6), and therefore names a variable
that is distinct from all others (6.2.2p2). And that is why you
have not defined the same object twice, and why the compiler is
happy with your code.
 
J

James Kuyper

There is one case where Java doesn't allow two variables with the
same name, but I forget if C has this restriction:

int i;
for(int i=0;i<10;i++) ;

Even though the second i is local to the loop, you can't have one
if there is one in the outer block.

When allowing a declaration in the first part of an if statement was
first proposed, the appropriate scope of that variable was hotly
debated. One option was putting it in the scope of the enclosing block,
which would have prohibited such code. The final decisions was that the
scope of such variables is "the remainder of the declaration and the
entire loop, including the other two expressions;" (6.8.5.3p1) so the
two 'i's have different scope. They are therefore two different
variables, so the declarations do not violate a constraint.
 
G

glen herrmannsfeldt

(snip, I wrote)
When allowing a declaration in the first part of an if statement was
first proposed, the appropriate scope of that variable was hotly
debated. One option was putting it in the scope of the enclosing block,
which would have prohibited such code. The final decisions was that the
scope of such variables is "the remainder of the declaration and the
entire loop, including the other two expressions;" (6.8.5.3p1) so the
two 'i's have different scope. They are therefore two different
variables, so the declarations do not violate a constraint.

As well as I know it, in Java they are different scope, but it still
disallows it.

That is, you can either have i as a local (method) variable, or declare
one on each for loop, but not both. If you need the value after
the loop, then you have to use the outer declaration.

(Where I said i, that is any variable used in a for loop.)

Seems to me that Java tries to fix some of the problems that
C programs can have, without making it too hard for C programmers
to learn and use.

While using the same variable name at file scope and inside a function
can be confusing (and lead to bugs) using the same variable name
in a loop to refer to a different variable is more likely to lead
to bugs.

Another interesting Java change is no comma operator, but instead
it is part of the syntax of the for loop, such that the common C
usage still works.

-- glen
 
S

somenath

Several responders have assured you that the two `i' have

different scopes and are different variables, but I haven't seen

anyone address the matter of linkage. "Linkage" is the mechanism

by which identifiers in distinct scopes denote the same object or

function. Scope is not the be-all and end-all of "identity," as

you can see in this example:



int foo(void) {

extern int x;

return ++x;

}



int bar(void) {

extern int x;

return x--;

}



The two `x' have different scopes, yet they refer to the same

variable because of their linkage. (I don't recommend this style,

by the way, but it's legal.)



Back to your example: The first `i', the one at file scope,

has internal linkage as you say (this is spelled out in 6.2.2p3).

But the `i' at block scope does *not* have internal linkage;

it has "none" linkage (6.2.2p6), and therefore names a variable

that is distinct from all others (6.2.2p2). And that is why you

have not defined the same object twice, and why the compiler is

happy with your code.
So depending upon the scope of the variable does static key word has different meaning?
Then is my following understanding correct ?

1) If it is associated with a variable inside function
i.e the variable has automatic storage duration as below
foo() {
int x;
}
The static provide the variable x static storage duration but it does not provide any linkage to x.

2) If it is associated with a variable outside function that has external linkage
/*file.c/
int x

The keyword static here does not provide static storage duration as the variable x already has static storage duration. Here it provides internal linkage.

So in essence static mainly provide static storage duration who needs it but it provide local linkage who has already static storage duration.

Why C has different meaning for same keyword? is it for minimizing the number of keyword ?
 
S

somenath

So depending upon the scope of the variable does static key word has different meaning?

Then is my following understanding correct ?



1) If it is associated with a variable inside function

i.e the variable has automatic storage duration as below

foo() {

int x;

}

The static provide the variable x static storage duration but it does notprovide any linkage to x.



2) If it is associated with a variable outside function that has externallinkage

/*file.c/

int x



The keyword static here does not provide static storage duration as the variable x already has static storage duration. Here it provides internal linkage.



So in essence static mainly provide static storage duration who needs it but it provide local linkage who has already static storage duration.



Why C has different meaning for same keyword? is it for minimizing the number of keyword ?


Also I do not have a very clear distinction between internal linkage andno linkage.
According to my understanding linkage is a way to identify the connection between identifiers in separate file .
If the situation is as follows
1.c
+++++
#include<stdio.h>
int i;
int main(void)
{
printf("\n value of i = %d\n",i);

return 0;
}
+++++++
2.c
int i =5;
+++++
Now if these two files are compiled and linked the output will be
value of i = 5

So in this case in file 1.c i has the external linkage and which refer to the same i defined in 2.c

Now if I change 1.c as follows

#include<stdio.h>
static int i;
int main(void)
{
printf("\n value of i = %d\n",i);

return 0;
}

the output is
value of i = 0

Here i has internal linkage and also by default in C static variable is initialized so i is initialized to 0 .

Now if I change 1.c as follows
#include<stdio.h>
int main(void)
{
static int i;
printf("\n value of i = %d\n",i);

return 0;
}

Now i has no linkage and initializes to 0. So the output is
value of i = 0
So the output is same for the case of internal and no linkage. My question is what is the significance of internal linkage ? Is it a way of saying that in a particular file if an identifier has internal linkage then that identifier only can be referred in that file . If the identifier has no linkage then if the identifier goes out of scope it can no longer be referred.

So for example
#include<stdio.h>
static int i =15;
int main(void)
{
extern int i;
printf("\n value of i = %d\n",i);

return 0;
}
Here i has internal linkage but it can be referred from the same file. extern int i; is referring to static int i =15;
So here the output will be
value of i = 15

Now in the following case

#include<stdio.h>
static int i =15;
void foo()
{
int x =20;
}
int main(void)
{
extern int i;
printf("\n value of i = %d\n",i);

return 0;
}

i has no linkage in foo() so there is no way it can be referred to from outside foo() . So extern int i; refer to static int i =15; only.

So if this is only difference between no linkage and internal linkage?
 
J

James Kuyper

On 02/17/2014 08:04 PM, somenath wrote:
....
So depending upon the scope of the variable does static key word has
different meaning?
Correct.

Then is my following understanding correct ?

1) If it is associated with a variable inside function
i.e the variable has automatic storage duration as below
foo() {
int x;
}
The static provide the variable x static storage duration but it does not provide any linkage to x.

2) If it is associated with a variable outside function that has external linkage
/*file.c/
int x

The keyword static here does not provide static storage duration as
the variable x already has static storage duration. Here it provides
internal linkage.

So in essence static mainly provide static storage duration who
needs it but it provide local linkage who has already static storage duration.

The parts where you use "who" aren't quite correctly worded - I'm not
sure what you meant, so I'm not sure how to correct them. I'll just
provide my own statement, and you can tell me if it matches your
understanding.

At block scope, 'static' gives "static storage duration". However, at
file scope, all objects already have static storage duration, so
'static' is given an entirely different meaning: "internal linkage".

Why C has different meaning for same keyword? is it for minimizing
the number of keyword ?

Re-using the keyword for unrelated purposes was a bad decision made
early in the development of C, or possibly even in it's predecessor
languages. It cannot be changed now without breaking a lot of existing
code. You'd think the committee had learned from that lesson, but they
added a third, completely unrelated meaning for static in C99:

int func( int array[static 32]);

In this case, 'static' means that it is undefined behavior to call
func() with an argument that does not point at an element of an array
with at least 32 accessible members.
 
E

Eric Sosman

[d

o

u

b

l

e

s

p

a

c

e

d]

So depending upon the scope of the variable does static key word has different meaning?

Yes. See the cited sections of the Standard
Then is my following understanding correct ?

1) If it is associated with a variable inside function
i.e the variable has automatic storage duration as below
foo() {
int x;
}
The static provide the variable x static storage duration but it does not provide any linkage to x.

Right. More precisely, it gives the identifier "none" linkage.
2) If it is associated with a variable outside function that has external linkage

Not possible. If the identifier is declared with `static', it
cannot have external linkage.
int x

The keyword static here does not provide static storage duration as the variable x already has static storage duration. Here it provides internal linkage.

I see no "static here." If the declaration were `static int x;'
at file scope, then yes: It would have static storage duration anyhow
(by virtue of being at file scope), and adding `static' means only
that it has internal rather than external linkage.
Why C has different meaning for same keyword? is it for minimizing the number of keyword ?

I can't find the exact quote, but somebody observed that "It
wouldn't be a new C Standard if it didn't invent a new meaning
for `static'." That is, there are even more uses for `static'
than those you've found thus far ...

(The `static' keyword is hardly the only "overloaded" keyword
in the language. See also `while', `long', `void', ... All of
which have different meanings in different contexts.)
 
J

James Kuyper

Also I do not have a very clear distinction between internal linkage and no linkage.

"In the set of translation units and libraries that constitutes an
entire program, each declaration of a particular identifier with
external linkage denotes the same object or function. Within one
translation unit, each declaration of an identifier with internal
linkage denotes the same object or function. Each declaration of an
identifier with no linkage denotes a unique entity." (6.2.2.p2)

So the key distinction between internal linkage and no linkage is
whether multiple declarations can refer to the same object or function.
According to my understanding linkage is a way to identify the
connection between identifiers in separate file .

It's more precisely about scopes than about files; file scope is one
kind of scope, which is how files enter into it. "An identifier declared
in different scopes or in the same scope more than once can be made to
refer to the same object or function by a process called linkage." (6.2.2p1)
If the situation is as follows
1.c
+++++
#include<stdio.h>
int i;
int main(void)
{
printf("\n value of i = %d\n",i);

return 0;
}
+++++++
2.c
int i =5;
+++++
Now if these two files are compiled and linked the output will be
value of i = 5

So in this case in file 1.c i has the external linkage and which
refer to the same i defined in 2.c

Now if I change 1.c as follows

#include<stdio.h>
static int i;
int main(void)
{
printf("\n value of i = %d\n",i);

return 0;
}

the output is
value of i = 0

Here i has internal linkage and also by default in C static variable
is initialized so i is initialized to 0 .

Now if I change 1.c as follows
#include<stdio.h>
int main(void)
{
static int i;
printf("\n value of i = %d\n",i);

return 0;
}

Now i has no linkage and initializes to 0. So the output is
value of i = 0
So the output is same for the case of internal and no linkage. My
question is what is the significance of internal linkage ?

The following 'i's have no linkage, so each one identifies a different
object. Having multiple declarations is allowed only because each one
has a different scope:

int foo()
{
int i;
{
int i;
}
}
int bar() { int i; }

The following 'i's, declared at file scope, have internal linkage, so
they both identify the same object:

static int i;
static int i=2;

....
int main(void)
{
extern int i;
printf("\n value of i = %d\n",i);

return 0;
}

i has no linkage in foo() so there is no way it can be referred to
from outside foo() . So extern int i; refer to static int i =15; only.

That is another consequence of that distinction.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top