5

While developing a library using C, what are your recommendations about variable and function scoping?

In C++, OOP and namespaces made the whole thing a lot easier. But how to do that with plain C? Specially how to use the keywords static and extern in headers and code files to manage scoping?

gnat
  • 21,442
  • 29
  • 112
  • 288
Gulshan
  • 9,402
  • 10
  • 58
  • 89

1 Answers1

13

On extern: As a rule, don't. The only thing that should be shared between files are definitions, via headers: function declarations (in C files) link externally without scope keywords. (Global variables are bad enough by themselves: linking them into other files just exacerbates the problem.)

You should use static in the (C file) definition of any file-local functions that you aren't exposing (via headers) to other files (it omits the function from external linking, keeping the global namespace unpolluted). (You could make any global variables in a file static for the same reasons, but you're better off just not having global variables.)

As for namespacing, your library should agree on a common prefix for all function / macro / struct / constant names (Lua uses lua_ for core API stuff (LUA_ for constants), luaL_ for auxiliary stuff, and various other 'lua-plus-a-letter-and-underscore' prefixes for internal stuff).

As for actual inner-function-scopes like this:

void example()
{
  char* msg = "Hello world!";
  msg[1]='a';
  msg[3]='d';
  {
    FILE * fOutput;
    fOutput = fopen ("out.txt","w");
    if (fOutput)
    {
      fputs (msg,fOutput);
      fclose (fOutput);
    }
  }
}

I personally love them and feel they're a great solution to ANSI C's "must declare all variables before any other statements" restriction, but most people tend to just keep their variable scopes flat at the root of the function.

  • 1
    All good. I'll add another one: make sure you #include into every C file its corresponding H file. The compiler does more work for you this way in checking your "exported" functions [via the prototype in the header] against the actual. – quickly_now May 30 '11 at 08:34
  • 3
    Saying "Dont use globals" (particualrly in C) is just like telling your 16 daugther not to have sex, then wondering why she got pregent. Use globals VERY spareingly. Use static when the scope of a variable is limited to the compile unit. Use extern on exposed globals in the header file definition, and declare them it the same named C file. – mattnz May 30 '11 at 10:08
  • 7
    @mattnz Daughter, have sex very sparingly? – Max May 30 '11 at 11:10
  • 3
    Or perhaps the other way around: I'd rather you didn't *use global variables* but if you do be sure to use a condom. – Matt Ellen Jun 13 '11 at 12:41
  • 1
    +1 for everything, except maybe the remark about ANSI C's "must declare all variables before any other statements" (non-)restriction. It is actually a GOOD THING (TM) if you maintain small feature-centric functions. Their scope should be minimal anyways, and the normal block scoping will be more than enough for your needs. In the case of your example, I really don't see much point in doing what you did with the first sub-block. That's personal, though. Do what floats your boat (but doesn't annoy your co-workers). – haylem Jun 14 '11 at 18:24
  • 1
    +1 for namespace recommendation, and the advice to use static for all functions that are not meant to be exposed. – Jay Elston Jun 14 '11 at 23:12