1

I have heard that functions in are called "extern" by default. So, according to this the scope of functions should be inside, entire the project, isn't it? I believe haven't seen this. I just like to know that is it really visible across the project files by default?

The article link: https://www.geeksforgeeks.org/understanding-extern-keyword-in-c/

It says:

" First, Let’s consider the use of extern in functions. It turns out that when a function is declared or defined, the extern keyword is implicitly assumed. When we write.

int foo(int arg1, char arg2);

The compiler treats it as: extern int foo(int arg1, char arg2);

Since the extern keyword extends the function’s visibility to the whole program, the function can be used (called) anywhere in any of the files of the whole program, provided those files contain a declaration of the function. (With the declaration of the function in place, the compiler knows the definition of the function exists somewhere else and it goes ahead and compiles the file). So that’s all about extern and functions. "

Naasif
  • 495
  • 2
  • 6
  • 13
  • There's a recent interesting discussion of the implications of `extern` in this post: https://stackoverflow.com/questions/64059468/using-extern-function-instead-of-including-a-header-defining-that-function/64060259#64060259 – Kevin Boone Sep 27 '20 at 11:43

4 Answers4

2

You can find this in section "6.2.2 Linkages of identifiers" of the C11 standard draft N1570.

It says:

If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
2

The use of the extern modifier is optional for function definitions. However, many C developers use it as a matter of style, to indicate to somebody reading the source that there's no point looking for the definition of the function in the same file.

Kevin Boone
  • 4,092
  • 1
  • 11
  • 15
1

Yes all functions (if there is no other modifier) are implicitly extern. You may alter it with static modifier, which makes the function visible only for the file it is written in. Another quite common use is extern inline which makes inline functions visible for another files, not just the module they are defined in.

  • Thank you. Would you mind explaining it, "not just the module they are defined in." and "exteren inline "? – Naasif Sep 27 '20 at 08:05
  • 1
    Sure, inline is a function specifier that "hints" compiler that it may work with function similarly like with a macro (but it may ignore it). It is not visible for other files (because of "inline" definiton in standard) unless specified extern. (I found this source, it explains it quite well: https://www.greenend.org.uk/rjk/tech/inline.html). – Daniel Kříž Sep 27 '20 at 09:37
1

Yes, C defaults to global visibility for new named objects in filescope unless they're declared static.

Note that extern does not mean global visibility. It means previously declared visiblity OR (if there was no such previous declaration) global visibility.

extern optional on non-static functions (with some special meanings for the new (C>=C11) inline functions) but for filescope variable declarations it is sometimes needed to differentiate between a declaration and a tentative definition.

Examples:

void globalFunc(void);
void globalFunc(void){ }

static void fileLocalFunc(void);
void fileLocalFunc(void){ } //ok, file-local because the previous declaration was file-local

static void another_fileLocalFunc(void);
extern void another_fileLocalFunc(void){ } //extern is optional for functions

static int fileLocal_variable;
extern int fileLocal_variable; //ok, file-local, because the previous declaration was file-local

//some noncompiling stuff:
#if 0 || CONFLICTING_FUNC_DECLARATIONS0
extern void conflictingFuncDeclarations0(void);
static void conflictingFuncDeclarations0(void);
#endif
#if 0 || CONFLICTING_FUNC_DECLARATIONS1
void conflictingFuncDeclarations1(void);
static void conflictingFuncDeclarations1(void);
#endif

#if 0 || CONFLICTING_VAR_DECLARATIONS0
int conflictingVarDeclarations0;
static int conflictingVarDeclarations0;
#endif

If you're on a POSIX system, you can compile a translation unit into an object (*.o) file and then use the nm utility on it to see which names it exports (or attempts to import).

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142