Question

I was working on some C-output questions and found the following code:

http://ideone.com/O0tQnr

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.

  1. The names of static variables are usually included within the debugging symbol table.
  2. some embedded ones (compilers) simply add a number to the end of each duplicate name
  3. They are likely mangled in the table.

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:

http://ideone.com/zpRVCa

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.

Was it helpful?

Solution

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.

OTHER TIPS

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).

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top