Thread: Scope issue with header file used as interface

  1. #1
    Registered User
    Join Date
    Feb 2012
    Posts
    10

    Scope issue with header file used as interface

    Hello!

    I am new to C programming and am having a bit of trouble understanding scope and how it relates to header files.

    I have a single C file "foo.c" that has probably on the order of 30 different functions that do many different things, but only certain functions are needed within other C files that I am integrating my code with. I also have "definitions.h" and "structs.h" that declare the vast majority of the functions, and those are included in "foo.c". Obviously I don't want to have to include every single function in every single subsequent C file so I can save some resources and make the implementation cleaner overall. Therefore I have written an "Interface.h" file to be included elsewhere (also #included in "foo.c") in the code as an easy way to limit the alterations of other peoples code, but to still give access to my own additions. For example, a function declared in Interface.h could be "RunBoot()" that is defined in foo.c; this function will then run 5 other functions located in foo.c that are invisible to the program that originally called "RunBoot()". Pretty simple right?

    Well I then proceeded to whip up a quick test script example.c that has my main() function, and #include's Interface.h. I create an infinite loop that at certain increments will call different functions from interface.h, thereby using other, would-be invisible functions in foo.c; this works just fine. In the advent of seeing what the compiler was actually doing, I threw in a function that was NOT declared in Interface.h and waited for an error of "what the heck is this function, example.c can't see that!" Lo and behold that error did not happen, and it ran the function not defined in Interface.h without a problem??? Then I decided, ok, what happens if I remove the #include Interface.h from example.c? I did that, and every single method I called in example.c ran without a problem with NONE of my header files included in it. Why does example.c seem to have access to everything I've written? I don't want it to, I want it to only be able to see what I manually #include there (interface.h); essentially the only way foo.c and example.c should be allowed to communicate is through functions defined in interface.h, everything else being invisible.

    Just what the heck is going on here?

    Let me put this into code...


    Code:
    //foo.c
    #include definitions.h
    #include structs.h
    #include interface.h
    
    void RunBoot() {...} //declared in interface.h
    void BootSelected() {...} //declared in definitions.h
    
    // ...
    Now onto example.c ...

    Code:
    //example.c
    //include none of the previous header files
    
    int main()
    {
         while(1)
         {
              RunBoot(); //Should fail due to lack of #include interface.h, but doesn't?
    
              //... delay
    
             BootSelected(); //Should fail due to lack of #include definitions.h, but doesn't either?
    
         }
    }

  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    FYI: The compiler should issue warning because of the lack of the headers. It need not error out.
    The linker is likely to get a undefined error; but might not.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    If your code calls a function that has not been declared, then the compiler assumes that function returns int and has a variable argument list.

    That is a deprecated feature of the C language (i.e. slated for removal from a future version of the C standard). It is also considered good practice to avoid relying on it (i.e. declare all functions in a header file, as you are doing, and then ensure that every source file which uses your functions #include that header).

    In practice, if you call a non-existent function (one that is not defined anywhere) then the code will compile, but will typically result in a linker error.

    The more sinister concern is that, if you forget to #include the header, and call a function declared in it, that the code results in undefined behaviour unless the assumption made by the compiler when calling it (returns int, variable argument list) matches the function declaration. So code that can compile and link can still function incorrectly, because you forget to #include a header with declarations where needed. That is just one of the reasons that the "feature" of the language is deprecated.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  4. #4
    Registered User
    Join Date
    Feb 2012
    Posts
    10
    You are right, my bad. The compiler does issue a warning, for each function called, stating that the function is "implicitly called", and how it was "previously declared to return int". Then when I go back and #include Interface.h, the warnings are gone.

    I think what I'm trying to understand is how to translate 'public' and 'private' concepts from other OOP languages like C#. In C#, if you try and access a private member from outside the function or class in which its defined, the compiler tells you so and crashes. Its pretty intuitive and sort of forces you to conform to a standard that seems to keep peoples hands out of other peoples cookie jars. I want other programs to have limited access to what I've written, hence Interface.h... is there no way to limit the scope of the other functions I have written in foo.c, and anything from anywhere can access them (probably incorrectly) and make things go haywire? Or am I doing everything in my power and just have to come to terms with the fact that all these .c files will be sort of inherently linked together? I suppose if that's the case then my work is done

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    If the function definition declares a function static (and you don't declare that function in a header file) then those functions are only accessible from the source file where they are defined.

    You can use some tricks such as opaque handles. For example, pass a void pointer around rather than a pointer to SomeStruct. Any code which wants to do anything with the handle directly will either need to call your functions, or somehow convert the handle into a pointer of some type they can legitimately use (and carry the risk if they convert to something else). That doesn't stop a determined programmer from breaking things, but does prevent accidental abuses (which is really all that private and protected attributes do too).

    There is no way, in C, of declaring particular members of a struct private or protected: all are implicitly public. C is not designed to support such concepts.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Header File Issue CodeBlocks
    By mathguy in forum C Programming
    Replies: 8
    Last Post: 11-18-2011, 04:57 PM
  2. Basic scope issue
    By Dondrei in forum C++ Programming
    Replies: 4
    Last Post: 07-06-2008, 06:36 AM
  3. Replies: 30
    Last Post: 06-19-2006, 12:35 AM
  4. Replies: 4
    Last Post: 12-14-2005, 02:21 PM

Tags for this Thread