NO

Author Topic: Declaring static functions  (Read 3012 times)

Offline PaoloC13

  • Member
  • *
  • Posts: 44
Declaring static functions
« on: March 29, 2018, 04:48:39 AM »
it seems that a function delcared at file scope, in a source file (.c), it is not visible from other tranlsating units, unless it is declared in the interface file (.h). I mean, a function declared as such, behaves like static, even if I do not use the static specifier.

My question is: the compiler treats this function as static by default?
...and: should I use the static specifier anyway as "best particle" in order to have private functions, or can I omit it?

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Declaring static functions
« Reply #1 on: March 29, 2018, 06:28:55 PM »
Hello Paolo,
The ISO C standard specifies that a declaration without the 'static' storage class is by default global.
In effect the compiler respects that, but the problem is much more tricky: when no prototype is supplied the compiler assumes a '__cdecl' calling conventions, when compiling in 32bits, so if you have a program with '-Ze' option enabled, MS compatibility, the function is compiled as '__stdcall', but the call to function expects a '__cdecl', and because the names are different can't locate it.
When compiling for 64bits there is no problem because the calling convention is only one.
You can check declaring as __cdecl the function and recompiling.
Difficult to say if this is a bug or a voluntary choice...
« Last Edit: March 31, 2018, 08:16:24 PM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline PaoloC13

  • Member
  • *
  • Posts: 44
Re: Declaring static functions
« Reply #2 on: March 30, 2018, 11:09:13 AM »
Hello frankie,
I've just compiled a test for 64bits and yes, a function declared without the static specifier behaves like global, complying with the ISO C standard.

So I deduce that it is always advisable to declare with "static", anyhow, to have a private function for a module.

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Declaring static functions
« Reply #3 on: March 31, 2018, 08:16:02 PM »
I've just compiled a test for 64bits and yes, a function declared without the static specifier behaves like global, complying with the ISO C standard.
So I deduce that it is always advisable to declare with "static", anyhow, to have a private function for a module.
Maybe I have not been very clear in my previous post. Let me clarify.
PellesC is perfectly ISO-C compatible, implying that all declarations that are not declared having the 'static' storage class are global.
This means that you are must declare as 'static' file local functions. Moreover consider that the meaning of the storage attribute 'extern' is a little bit tricky. It means that the symbol has an external linkage if the reverse has not been previously specified, but not the reverse. I.e.
Code: [Select]
//The following lines prototyping foo as static then declaring it as extern are legal
//The function foo will be 'static' ('extern doesn't modify linkage).
static int foo(int a);
extern int foo(int a)
{
return a;
}

//The following lines prototyping bar as extern then declaring it as static are illegal
extern int bar(int a);
static bar(int a)
{
return a;
}
Going back to our point let consider that, following MS standard, the compiler applies names decoration to differentiate functions having different calling conventions. I.e. see the following sample:
Code: [Select]
int __cdecl    foo(int a);      //The symbol will be '_foo'
int __stdcall  foo(int a);      //The symbol will be '_foo@4'
int __fastcall foo(int a);      //The symbol will be '@foo@4'
This system avoids that functions with different calling connections can be linked together breaking the execution (you'll surely get a memory violation).
On the other hand when is meet a call to a function for which no prototype has been previously seen, the compiler assumes that the function is a '__cdecl', standard C calling convention, assigning a symbol name just prepended by an underscore (see example above).
If you are compiling for standard call convention the name of the function, decorated in a different mode, doesn't equals the call symbols.
This don't happen when compiling for 64bits because there is just one calling convention so the symbol names are always coincident.
The behavior is correct, no doubt as in my previous post, and the only one acceptable.
« Last Edit: March 31, 2018, 08:51:43 PM by frankie »
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline PaoloC13

  • Member
  • *
  • Posts: 44
Re: Declaring static functions
« Reply #4 on: April 03, 2018, 02:47:18 PM »
Don't worry, you were clear enough the first time. Now I understand the matter concerning the calling convention, but I was getting used (wrongly, i think) to writing local functions without declaring them as static.