13

I want to have a static function which I declare in my .c file before defining it:

//file a.c version 1
static int foo();
...
static int foo()
{
...
}

However, it seems that I can leave the static keyword out of the function definition and I get no compiler warnings... e.g.

//file a.c version 2
static int foo();
...
int foo()
{
...
}

Am I correct in assuming these two forms are exactly the same?
If so, why is this discrepancy allowed and which form should I use?

jschmier
  • 15,458
  • 6
  • 54
  • 72
Arrakis
  • 576
  • 1
  • 6
  • 12
  • I think he/she is doing exercise, not writing a real big program. My opinion, first google that type question because it is so trivial. –  Mar 10 '11 at 14:51
  • 1
    @fatai: it is quite difficult to google this question. And language lawyers here will provide you with a quote from the Standard. – Alexandre C. Mar 10 '11 at 15:15
  • 1
    Thanks very much Erik and AProgrammer for answering the question!! Why is it be desirable to be able to leave out the static keyword in a future declaration / definition - it seems to me this would be confusing without adding any benefit. – Arrakis Mar 10 '11 at 15:24
  • Please pick one language when posting. You gave C code and got C++ answers. That makes this ill-suited to searching or duplicating/linking to questions for both languages, the worst of both worlds. Sure, the `c++` tag sorts first, and answers are for C++, so we can treat it as effectively C++, but then chances are someone will complain that it was ostensibly asked for C... – underscore_d Nov 18 '18 at 09:59

5 Answers5

12

Yes 7.1.1/6

A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration and provided it is not declared const.

See also the examples of 7.1.1/7

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
4

7.1.1/7:

The linkages implied by successive declarations for a given entity shall agree. That is, within a given scope, each declaration declaring the same object name or the same overloading of a function name shall imply the same linkage.

7.1.1/6: (Thanks Steve - this is also needed for the answer to be clear)

A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration and provided it is not declared const. Objects declared const and not explicitly declared extern have internal linkage.

Yes, those two are the same.

This however is invalid:

int foo();

static int foo() {
  return 0;
}
Erik
  • 88,732
  • 13
  • 198
  • 189
  • 1
    .. and the reason they agree in the questioner's case is 7.1.1/6: "A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration". They disagree in your example for the same reason. – Steve Jessop Mar 10 '11 at 14:56
  • There was something inserted before, the 7th of n3225 is the 6 of C++03. – AProgrammer Mar 10 '11 at 15:00
1

static - in this context - only affects the scope, when you declare a function static it has file scope. So you can easily check if it is the same by trying to access the function from another source.

that way we avoid the discussions about compiler language etc.

AndersK
  • 35,813
  • 6
  • 60
  • 86
0

The static attribute changes the visibility to the compilation unit. This allows to use the same name in different files for different purposes. You should use the static only once. If you have a prototype, you must do here.

When you are asking for C++ you should not use static but anonymous namespace to make the symbold private for the compilation unit:

namespace {
    int foo();
}

void bar()
{
    foo();
}
harper
  • 13,345
  • 8
  • 56
  • 105
0

As a sidenote, C++ provides a superior alternative to static. You can also use unnamed namespace here

Example,

namespace 
{  
   void f()
   {
   }
}

See these:

Superiority of unnamed namespace over static?
Why an unnamed namespace is a "superior" alternative to static?

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • I don't find it (so) superior for functions. It allows more declarations (classes / typedefs), and so using it also for functions and constants make for uniform syntax (and remove some overload of the keyword), but `static` is more terse. – Matthieu M. Mar 10 '11 at 14:59
  • Though of course, you could use *both* namespace *and* static. – Lundin Mar 10 '11 at 15:20
  • The `static` keyword in this context was declared obsolete in some version of the C++0x drafts. Then that decision was revoked and it has been de-obsoleted. In particular for functions some compilers have better diagnostics when declaring functions `static` than when using unnamed namespaces. As a matter of fact, in some compilers the `static` keyword does affect the decisions (optimizer) that the compiler takes with respect to that particular free function that are not taken when the same function is declared in an unnamed namespace. – David Rodríguez - dribeas Mar 10 '11 at 15:41