Reputation: 257
I was working on some C-output questions and found the following code:
In this code , as one can see , inside main , a static variable having same name has been declared. For this I searched on Stack-Overflow and found
How are static variables with the same name in different functions identified by the System?
The answers given for this question suggest different approaches viz.
I wanted to know how are static variables actually implemented in C, as all answers are suggesting something different?
Also to check whether this was only a one-off chance I also ran the code:
but the error:
prog.c:5:21: error: called object ‘GetSize’ is not a function or function pointer
int myvar=GetSize(GetSize);
^
prog.c:4:11: note: declared here
static GetSize;
^
indicates that the compiler found a conflicting declaration / redeclared Getsize.
Upvotes: 0
Views: 1288
Reputation:
There's a clue in the error message: "not a function or function pointer". The compiler can't assume that the name to the left of the (
is a function name, because any expression yielding a function pointer is also allowed there, including a variable declared as a function pointer.
At the parsing stage, there's no type checking to help find the right variable. Here's a program that doesn't work for a similar reason:
int main(void)
{
struct { int x,y; } s = {0,0};
{
int s;
printf("%d\n", s.x);
}
}
The outer s
is capable of fitting into the expression s.x
, but the inner s
is the one that is visible.
And here's a program that works because the outer-scoped function is not preferred over the inner-scoped variable, which happens to be a function pointer capable of being called with itself as an argument:
#include <stdio.h>
#include <stdlib.h>
void func()
{
puts("Everything's fine.");
}
void fp()
{
/* This won't happen. */
abort();
}
int main(void)
{
void (*fp)() = func;
fp(fp);
}
Upvotes: 0
Reputation: 224335
Different entities may have the same identifier if they have different scopes or are in different name spaces1. In the case of int main() { static int main; … }
, the first main
has file scope, and the second main
has block scope.
At any particular point, only one identifier is visible in a name space. In GetSize(GetSize)
, only the static GetSize
is visible. It hides the int GetSize(int)
, so the function GetSize
is not visible. Thus, this code gets an error.
An identifier declared at file scope with static
has internal linkage. An object identifier declared at block scope without extern
(including those that have static
) has no linkage. Because these identifiers do not have external linkage, they never need to be known outside the current translation unit. Therefore, these identifiers do not need to appear in object files: There is no need for them to have names visible to the linker. They are typically accessed by code generated by the compiler during compilation of the translation unit, and this code addresses objects numerically (by location in memory), not by name.
Many C implementations provide debugging facilities. Debuggers generally need to know the names of things even if they have internal or no linkage. In these cases, the C implementation may use any scheme it desires to record information about names.
1 The name spaces of C are: label names; tags of structures, unions and enumerations; members of structures or unions (a separate space for each structure or union); and all other identifiers. The standard also refers to a name space for macro names.
Upvotes: 2
Reputation: 58324
The two cases you are describing have a fundamental difference. In the first case:
int main(){
static main;
int myvar=GetSize(main);
printf("%d",myvar);
return 0;
}
Here, you are inside the function main
and declaring a static integer also called main
. The function main
is called from an external place which knows about main
as a function and calls it as such. Inside the definition of main
above, you have redefined main
as the static integer, then calling GetSize(main)
doesn't cause an error because it complies with the definition of GetSize
.
In the second case:
int GetSize(int);
int main(){
static GetSize;
int myvar=GetSize(GetSize);
printf("%d",myvar);
return 0;
}
Here you've redefined GetSize
to be a static integer, but then attempted to call GetSize
as if it were a function. So you have a direct conflict in terms of the definition (static integer) and how you are using it (a function).
Upvotes: 2