Is there a real need to use keyword static with functions?

D

Dave Vandervies

The recommendation from the group would probably be to ditch HS's book
- he's not regarded in great esteem round here...

"Ditch" is a bit weak. Try "Burn it and post videos".


dave
 
C

CBFalconer

.... snip ...

Well... it's time to study a little more. I have a copy of HS's book
somewhere. :) Perhaps I've missed something the first time I read it.

To get maximum value, find the book and put it to good use as
kindling for the wood stove. DO NOT open it. Then buy something
written by someone who knows his subject.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
B

Bill Pursell

Functions should always be made static if they are not intended as end-
user available routines.

Not quite true: if you have are building a library, you may have
functions in different translation units that you want to be
accessible from all functions within the library, but not
visible outside the library. Declaring such functions
static would limit their scope to the containing translation
unit. In this case, you need to use other "linker magic"
to hide the symbols.
 
C

CBFalconer

Bill said:
.... snip ...

Not quite true: if you have are building a library, you may have
functions in different translation units that you want to be
accessible from all functions within the library, but not visible
outside the library. Declaring such functions static would limit
their scope to the containing translation unit. In this case,
you need to use other "linker magic" to hide the symbols.

Very simple:

/* file a.c */
#include "a.h"
#include "alocals.h"
int foo(void) { /* foocode */ }
int bar(void) { /* barcode */ }

/* file a.h */
int foo(void);

/* file alocals.h */
int bar(void);

/* file library.h */
#include "a.h"

The linker doesn't matter.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
O

Old Wolf

Hi everyone

Is there a real need to use keyword static with functions, if we
simply don't declare their prototypes in .h file?

Another benefit of marking the function 'static' is that the
compiler can optimise it, since it knows exactly when and how
it is being called. For example it can leave out unused code
branches, use more registers, or even inline the entire
function body.
 
F

Flash Gordon

CBFalconer wrote, On 06/03/07 22:42:
Bill Pursell wrote:
... snip ...

Very simple:

/* file a.c */
#include "a.h"
#include "alocals.h"
int foo(void) { /* foocode */ }
int bar(void) { /* barcode */ }

/* file a.h */
int foo(void);

/* file alocals.h */
int bar(void);

/* file library.h */
#include "a.h"

The linker doesn't matter.

That does not fully hide it. If the user declares a function or variable
with external linkage named bar it still invokes undefined behaviour and
can cause problems, or the user could find out via some other means that
bar exists, write a prototype for it (or not) and call it.

The linker does still matter.
 
K

Keith Thompson

Although it's clear for me now that "staticizing" functions avoids
exporting uncessessary symbols to linker, it's quite unlikely that one
can possibly duplicate a name of a temporary function.
Specially if one give good names for them, with a prefix in a way
similar to Gtk package and similars.

You're asking the wrong question. The question isn't "Why should I
use static?"; it's "Why *shouldn't* I use static?'.

If I were designing the language from scratch today, "static" would be
the default; function names would not be exported beyond file scope
unless you specifically asked for it, probably with an additional
keyword. (Or maybe I'd use some other encapsulation mechanism.)

Declare functions as static unless there's a specific reason not to do
so. ("main" is an odd case; it's usual not to declare it as static.)
 
S

Stephen Sprunk

Old Wolf said:
Another benefit of marking the function 'static' is that the
compiler can optimise it, since it knows exactly when and how
it is being called. For example it can leave out unused code
branches, use more registers, or even inline the entire
function body.

Some compilers may do those things anyways, though if the function is _not_
static then they must still generate the "normal" code in case the function
is called from another translation unit (unless the compiler has what is
often termed "whole-program optimization" and can prove that doesn't occur).

S
 
I

Ian Collins

Keith said:
Declare functions as static unless there's a specific reason not to do
so. ("main" is an odd case; it's usual not to declare it as static.)
I would be interesting trying to build an application if it were!
 
B

Bill Pursell

Bill Pursell wrote:

... snip ...


Very simple:

/* file a.c */
#include "a.h"
#include "alocals.h"
int foo(void) { /* foocode */ }
int bar(void) { /* barcode */ }

/* file a.h */
int foo(void);

/* file alocals.h */
int bar(void);

/* file library.h */
#include "a.h"

The linker doesn't matter.

In this case, unless I'm misunderstanding your
post, you have exactly one translation unit which
contains definitions for the functions foo() and
bar(), so this doesn't quite address the situation
I'm describing, which is:

/* file a.c */
int foo(int) __attribute__((hidden)); (1)
int foo(int x) { /* foo code calls bar*/ }

/* file b.c */
int bar(int) __attribute__((hidden));
int bar(int x) { /* bar code calls foo*/ }

build library libfoobar.so from a.c and b.c
/* file c.c */
int main(void) { /* can't call foo. */ }

The intention is for foo and bar to only
be visible from functions within the library,
but not be restrained to the translation unit
in which they are defined. Declaring them
static would make foo invisible to bar.

(1) I have no idea how portable the
"__attribute__((hidden))" is--it works with gcc
 
M

matevzb

In this case, unless I'm misunderstanding your
post, you have exactly one translation unit which
contains definitions for the functions foo() and
bar(), so this doesn't quite address the situation
I'm describing, which is:

/* file a.c */
int foo(int) __attribute__((hidden)); (1)
int foo(int x) { /* foo code calls bar*/ }

/* file b.c */
int bar(int) __attribute__((hidden));
int bar(int x) { /* bar code calls foo*/ }

build library libfoobar.so from a.c and b.c
/* file c.c */
int main(void) { /* can't call foo. */ }

The intention is for foo and bar to only
be visible from functions within the library,
but not be restrained to the translation unit
in which they are defined. Declaring them
static would make foo invisible to bar.
There's always the (blasphemous) possibility of #include-ing a .c
file, so in your case b.c would #include a.c containing a "static int
foo()". It should work (at least in simple cases as yours above), but
it's ugly and comes with a myriad of problems so I probably shouldn't
have mentioned it in the first place.
 
B

Bill Pursell

There's always the (blasphemous) possibility of #include-ing a .c
file, so in your case b.c would #include a.c containing a "static int
foo()". It should work (at least in simple cases as yours above), but
it's ugly and comes with a myriad of problems so I probably shouldn't
have mentioned it in the first place.

That's great, but if you #include a file then you have a
single translation unit. Unless I'm using a different
definition that everyone else:

"a single source file submitted to the compiler along with all files
included by the compilation of that single source file (technically,
the output of the preprocessor)."

If you can't build a seperate .o, then it's not a seperate
translation unit.
 
B

Ben Pfaff

Bill Pursell said:
That's great, but if you #include a file then you have a
single translation unit. Unless I'm using a different
definition that everyone else:

"a single source file submitted to the compiler along with all files
included by the compilation of that single source file (technically,
the output of the preprocessor)."

That's the right definition. Here's exactly what C99 says, for
the record:

A source file together with all the headers and source files
included via the preprocessing directive #include is known
as a preprocessing translation unit. After preprocessing, a
preprocessing translation unit is called a translation unit.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top