3

I apologize if this is a beginner's question, but after working in C for a bit, I finally would like a bit of clarification on exactly what kind of files/functions are available to a function.

I understand we can explicitly include other files with the #include macro like so:

#include bar.c

But what about files that are in the same directory? Let's say we have the following file structure:

src-
   |
   a.c
   b.c

And let's say a.c has the function "foo()" and b.c has "bar()"

Would I be able to call bar() within a.c even without explicitly including b.c in the header file?

And what about in sub-directories such as the following:

src-
   |
   a.c
   |
   someFolder-
             |
             b.c

Would I still be able to access bar() in a.c?

Basically, how exactly is the scope of functions (without including them in headers) defined?

fuz
  • 88,405
  • 25
  • 200
  • 352
Victor3y
  • 816
  • 6
  • 11

4 Answers4

2

You are confusing scope with linkage.

The term scope descibes if an identifier is visible to the compiler in a given context. The broadest scope known to the C language is file scope which means that the identifier is visible from the point it is declared to the end of the translation unit after preprocessing. You can make any identifier visible/known by declaring it, but making an identifier visible does not mean that refering to the identifier refers to the thing it refers to in another file.

The term linkage describes how two identifiers refer to the same thing. There are three levels of linkage: with no linkage, each identifier with the name refers to a different thing. With internal linkage, each identifier within the same translation unit refers to the same thing. With external linkage, each identifier in the whol program refers to the same thing. For two identifiers in two translation units to refer to the same thing, you need to declare both of them to have external linkage.

This is independent of how the declaration is obtained. There is no difference in writing int foo() in a common header file to writing the same line in both source files. In either case, all identifiers refer to the same foo() as functions have external linkage unless explicitly declared to have internal linkage with the static type specifier.

It is also independent of how your source code is laid out. As long as all translation units are linked into the same binary, you can call all functions with external linkage in each translation unit.

fuz
  • 88,405
  • 25
  • 200
  • 352
  • Ah, I see now. In my actual use case, I was going through some open-source C code and I became confused because I noticed that some functions were being called from a different file even though they weren't explicitly included. When I actually go through the Makefile, I can now see that the ".o" files are being linked together. Thanks for the thorough explanation – Victor3y Feb 16 '16 at 18:37
  • @Victor3y It's a pleasure to me. – fuz Feb 16 '16 at 18:48
1

Depends on whether you are linking these into one binary or not.

If linking - then yes, functions can be called with implicit declaration.

Common pattern in this case is making a header(s) file with all declarations, including *.c files is usually not preferred, since #include is just textual inclusion of file contents

Vasfed
  • 18,013
  • 10
  • 47
  • 53
1

#include (a preprocessor directive, not a macro, BTW) has a configurable list of directories it searches. If you use the #include "something.h" form (as compared to the angle bracket form for including system headers), the first directory in the list is the directory of the including file.

Although #include does a simple textual inclusion so it is technically possible to include any text file, c files are almost never included.

In C, you usually compile c files separately into object files and link them together, and what you do include is header files which consist of declarations, which represent interfaces of the other object files which your current compilation unit otherwise wouldn't see.

Check out http://www.cs.bu.edu/teaching/c/separate-compilation/ or another article on that topic.

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

The forward slash "/" should work in this case.

If you can include foo.h without problem, this means the directory (say, C:\DIRFOO) is predefined in the "include" directive of the compiler. So, another file (say bar.h) in a sub directory (say, C:\DIRFOO\DIRBAR) can be included via #include <DIRBAR/bar.h>.

ssd
  • 2,340
  • 5
  • 19
  • 37