is the purpose of header files in C only warning to users?











up vote
-1
down vote

favorite












I'm a beginner into Linking, sorry if my questions are too basic. lets say I have two .c files



file1.c is



int main(int argc, char *argv) 
{
int a = function2();
return 0;
}


file2.c is



int function2() 
{
return 2018;
}


I know the norm is, create a file2.h and include it in file1.c, and I have some questions:



Q1. #include in file1.c doesn't make too much difference or improve much to me, I can still compile file1.c without file2.h correctly, the compiler will just warn me 'implicit declaration of function 'function2', but does this warning help a lot? Programmers might know that function2 is defined in other .c file(if you use function2 but don't define it, you certainly know the definition is somewhere else) and linker will do its job to produce the final executable file? so the only purpose of include file2,c to me is, don't show any warning during compilation, is my understanding correct.



Q2. Image this scenario, a programmer define function2 in file1.c, he doesn't know that his function2 in conflict with the one in file2.c until the linker throws the error(obvious he can compile his file1.c alone correctly. But if we want him to know his mistake when he compiles his file1.c, adding file2.h still don't help, so what's the purpose of adding header file?



Q3. What should we add to let the programmer know he should choose a different name for function2 rather then be informed the error by linker in the final stage.










share|improve this question




















  • 2




    Suppose the function is double function2(char *str) now what do you think the compiler will do with an "implicit" function which assumes (or used to assume) int arguments and return value? One purpose of the header file is to make a function prototype available.
    – Weather Vane
    Nov 11 at 23:33










  • in that case, the compiler will throw an error for sure, but even the programmer use the correct prototype if he defined his own function2, then linker will throw an error, how do we stop this or throw an error when he compile so the problem can be identified in the early stage?
    – amjad
    Nov 11 at 23:50










  • What's wrong with letting the linker inform you of the duplication? Why do you expect the compiler to look in all the other C source files when compiling one module? It is not as though this is going to happen on every compile/link cycle, or that a massive amount of time will be saved.
    – Weather Vane
    Nov 11 at 23:50












  • @amjad the compiler will throw an error for sure no, it will warn you, that implicit function declaration is used.
    – Kamil Cuk
    Nov 12 at 0:39










  • @KamilCuk no, the compiler will throw an error for sure, you can try gcc -s to see
    – amjad
    Nov 12 at 1:28















up vote
-1
down vote

favorite












I'm a beginner into Linking, sorry if my questions are too basic. lets say I have two .c files



file1.c is



int main(int argc, char *argv) 
{
int a = function2();
return 0;
}


file2.c is



int function2() 
{
return 2018;
}


I know the norm is, create a file2.h and include it in file1.c, and I have some questions:



Q1. #include in file1.c doesn't make too much difference or improve much to me, I can still compile file1.c without file2.h correctly, the compiler will just warn me 'implicit declaration of function 'function2', but does this warning help a lot? Programmers might know that function2 is defined in other .c file(if you use function2 but don't define it, you certainly know the definition is somewhere else) and linker will do its job to produce the final executable file? so the only purpose of include file2,c to me is, don't show any warning during compilation, is my understanding correct.



Q2. Image this scenario, a programmer define function2 in file1.c, he doesn't know that his function2 in conflict with the one in file2.c until the linker throws the error(obvious he can compile his file1.c alone correctly. But if we want him to know his mistake when he compiles his file1.c, adding file2.h still don't help, so what's the purpose of adding header file?



Q3. What should we add to let the programmer know he should choose a different name for function2 rather then be informed the error by linker in the final stage.










share|improve this question




















  • 2




    Suppose the function is double function2(char *str) now what do you think the compiler will do with an "implicit" function which assumes (or used to assume) int arguments and return value? One purpose of the header file is to make a function prototype available.
    – Weather Vane
    Nov 11 at 23:33










  • in that case, the compiler will throw an error for sure, but even the programmer use the correct prototype if he defined his own function2, then linker will throw an error, how do we stop this or throw an error when he compile so the problem can be identified in the early stage?
    – amjad
    Nov 11 at 23:50










  • What's wrong with letting the linker inform you of the duplication? Why do you expect the compiler to look in all the other C source files when compiling one module? It is not as though this is going to happen on every compile/link cycle, or that a massive amount of time will be saved.
    – Weather Vane
    Nov 11 at 23:50












  • @amjad the compiler will throw an error for sure no, it will warn you, that implicit function declaration is used.
    – Kamil Cuk
    Nov 12 at 0:39










  • @KamilCuk no, the compiler will throw an error for sure, you can try gcc -s to see
    – amjad
    Nov 12 at 1:28













up vote
-1
down vote

favorite









up vote
-1
down vote

favorite











I'm a beginner into Linking, sorry if my questions are too basic. lets say I have two .c files



file1.c is



int main(int argc, char *argv) 
{
int a = function2();
return 0;
}


file2.c is



int function2() 
{
return 2018;
}


I know the norm is, create a file2.h and include it in file1.c, and I have some questions:



Q1. #include in file1.c doesn't make too much difference or improve much to me, I can still compile file1.c without file2.h correctly, the compiler will just warn me 'implicit declaration of function 'function2', but does this warning help a lot? Programmers might know that function2 is defined in other .c file(if you use function2 but don't define it, you certainly know the definition is somewhere else) and linker will do its job to produce the final executable file? so the only purpose of include file2,c to me is, don't show any warning during compilation, is my understanding correct.



Q2. Image this scenario, a programmer define function2 in file1.c, he doesn't know that his function2 in conflict with the one in file2.c until the linker throws the error(obvious he can compile his file1.c alone correctly. But if we want him to know his mistake when he compiles his file1.c, adding file2.h still don't help, so what's the purpose of adding header file?



Q3. What should we add to let the programmer know he should choose a different name for function2 rather then be informed the error by linker in the final stage.










share|improve this question















I'm a beginner into Linking, sorry if my questions are too basic. lets say I have two .c files



file1.c is



int main(int argc, char *argv) 
{
int a = function2();
return 0;
}


file2.c is



int function2() 
{
return 2018;
}


I know the norm is, create a file2.h and include it in file1.c, and I have some questions:



Q1. #include in file1.c doesn't make too much difference or improve much to me, I can still compile file1.c without file2.h correctly, the compiler will just warn me 'implicit declaration of function 'function2', but does this warning help a lot? Programmers might know that function2 is defined in other .c file(if you use function2 but don't define it, you certainly know the definition is somewhere else) and linker will do its job to produce the final executable file? so the only purpose of include file2,c to me is, don't show any warning during compilation, is my understanding correct.



Q2. Image this scenario, a programmer define function2 in file1.c, he doesn't know that his function2 in conflict with the one in file2.c until the linker throws the error(obvious he can compile his file1.c alone correctly. But if we want him to know his mistake when he compiles his file1.c, adding file2.h still don't help, so what's the purpose of adding header file?



Q3. What should we add to let the programmer know he should choose a different name for function2 rather then be informed the error by linker in the final stage.







c header-files compiler-warnings






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 11 at 23:38

























asked Nov 11 at 23:28









amjad

3298




3298








  • 2




    Suppose the function is double function2(char *str) now what do you think the compiler will do with an "implicit" function which assumes (or used to assume) int arguments and return value? One purpose of the header file is to make a function prototype available.
    – Weather Vane
    Nov 11 at 23:33










  • in that case, the compiler will throw an error for sure, but even the programmer use the correct prototype if he defined his own function2, then linker will throw an error, how do we stop this or throw an error when he compile so the problem can be identified in the early stage?
    – amjad
    Nov 11 at 23:50










  • What's wrong with letting the linker inform you of the duplication? Why do you expect the compiler to look in all the other C source files when compiling one module? It is not as though this is going to happen on every compile/link cycle, or that a massive amount of time will be saved.
    – Weather Vane
    Nov 11 at 23:50












  • @amjad the compiler will throw an error for sure no, it will warn you, that implicit function declaration is used.
    – Kamil Cuk
    Nov 12 at 0:39










  • @KamilCuk no, the compiler will throw an error for sure, you can try gcc -s to see
    – amjad
    Nov 12 at 1:28














  • 2




    Suppose the function is double function2(char *str) now what do you think the compiler will do with an "implicit" function which assumes (or used to assume) int arguments and return value? One purpose of the header file is to make a function prototype available.
    – Weather Vane
    Nov 11 at 23:33










  • in that case, the compiler will throw an error for sure, but even the programmer use the correct prototype if he defined his own function2, then linker will throw an error, how do we stop this or throw an error when he compile so the problem can be identified in the early stage?
    – amjad
    Nov 11 at 23:50










  • What's wrong with letting the linker inform you of the duplication? Why do you expect the compiler to look in all the other C source files when compiling one module? It is not as though this is going to happen on every compile/link cycle, or that a massive amount of time will be saved.
    – Weather Vane
    Nov 11 at 23:50












  • @amjad the compiler will throw an error for sure no, it will warn you, that implicit function declaration is used.
    – Kamil Cuk
    Nov 12 at 0:39










  • @KamilCuk no, the compiler will throw an error for sure, you can try gcc -s to see
    – amjad
    Nov 12 at 1:28








2




2




Suppose the function is double function2(char *str) now what do you think the compiler will do with an "implicit" function which assumes (or used to assume) int arguments and return value? One purpose of the header file is to make a function prototype available.
– Weather Vane
Nov 11 at 23:33




Suppose the function is double function2(char *str) now what do you think the compiler will do with an "implicit" function which assumes (or used to assume) int arguments and return value? One purpose of the header file is to make a function prototype available.
– Weather Vane
Nov 11 at 23:33












in that case, the compiler will throw an error for sure, but even the programmer use the correct prototype if he defined his own function2, then linker will throw an error, how do we stop this or throw an error when he compile so the problem can be identified in the early stage?
– amjad
Nov 11 at 23:50




in that case, the compiler will throw an error for sure, but even the programmer use the correct prototype if he defined his own function2, then linker will throw an error, how do we stop this or throw an error when he compile so the problem can be identified in the early stage?
– amjad
Nov 11 at 23:50












What's wrong with letting the linker inform you of the duplication? Why do you expect the compiler to look in all the other C source files when compiling one module? It is not as though this is going to happen on every compile/link cycle, or that a massive amount of time will be saved.
– Weather Vane
Nov 11 at 23:50






What's wrong with letting the linker inform you of the duplication? Why do you expect the compiler to look in all the other C source files when compiling one module? It is not as though this is going to happen on every compile/link cycle, or that a massive amount of time will be saved.
– Weather Vane
Nov 11 at 23:50














@amjad the compiler will throw an error for sure no, it will warn you, that implicit function declaration is used.
– Kamil Cuk
Nov 12 at 0:39




@amjad the compiler will throw an error for sure no, it will warn you, that implicit function declaration is used.
– Kamil Cuk
Nov 12 at 0:39












@KamilCuk no, the compiler will throw an error for sure, you can try gcc -s to see
– amjad
Nov 12 at 1:28




@KamilCuk no, the compiler will throw an error for sure, you can try gcc -s to see
– amjad
Nov 12 at 1:28












4 Answers
4






active

oldest

votes

















up vote
1
down vote













Per C89 3.3.2.2 Function calls emphasis mine:




If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration



    extern int  identifier();


appeared




Now, remember, empty parameter list (declared with nothing inside the () braces) declares a function that takes unspecified type and number of arguments. Type void inside braces to declare that a function takes no arguments, like int func(void).



Q1:




does this warning help a lot?




Yes and no. This is a subjective question. It helps those, who use it. As a personal note, always make this warning an error. Using gcc compiler use -Werror=implicit-function-declaration. But you can also ignore this warning and make the simplest main() { printf("hello world!n"); } program.




linker will do its job to produce the final executable file? so the only purpose of include file2,c to me is, don't show any warning during compilation, is my understanding correct.




No. In cases the function is called using different/not-compatible pointer type. It invokes undefined behavior. If the function is declared as void (*function2(void))(int a); then calling ((int(*)())function2)() is UB as is calling function2() without previous declaration. Per Annex J.2 (informative):




The behavior is undefined in the following circumstances:



A pointer is used to call a function whose type is not compatible with the pointed-to type (6.3.2.3).




and per C11 6.3.2.3p8:




A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.




So in your lucky case int function2() indeed this works. It also works for example for atoi() function. But calling atol() will invoke undefined behavior.



Q2:




the linker throws the error




This should happen, but is really linker dependent. If you compile all sources using a single stage with the gcc compiler it will throw an error. But if you create static libraries and then link them using gcc compiler without -Wl,-whole-archive then it will pick the first declaration is sees, see this thread.




what's the purpose of adding header file?




I guess simplicity and order. It is a convenient and standard way to share data structures (enum, struct, typedefs) and declarations (function and variable types) between developers and libraries. Also to share preprocessor directives. Image you are writing a big library with over 1000+ files that will work with over 100+ other libraries. In the beginning of each file would you write struct mydata_s { int member1; int member2; ... }; int printf(const char*, ...); int scanf(const char *, ...); etc. or just #include "mydata.h" and #include <stdio.h>? If you would need to change mydata_s structure, you would need to change all files in your project and all the other developers which use your library would need to change the definition too. I don't say you can't do it, but it would be more work to do it and no one will use your library.



Q3:




What should we add to let the programmer know he should choose a different name for function2 rather then be informed the error by linker in the final stage.




In case of name clashes you will by informed (hopefully) by the linker that it found two identifiers with the same name. You would need to create a tool to check your sources exactly for that. I don't know why the need for this, the linker is specifically made to resolve symbols so it naturally handles the cases when two symbols with the same identifier exists.






share|improve this answer






























    up vote
    1
    down vote













    Short answer:



    Take away: the earlier the compiler alert the better.



    Q1: meaning of .h: consistency and early alerts. Alerting early on common ways of going wrong improves reliability of code and adds up to less debugging and production crashes.



    Q2: Clashing Names bring early alerts to developers, which are usually easier to fix.



    Q3: Early duplicate definition alerts are not baked into the C standard.



    Exercises:
    1. Define a function in one file that printf("%dn",i) an int argument then call that function in another file with a float of 42.0.
    2. Call with (double)42.0.
    3. Define function with char *str argument printed under %.s then call with int argument.



    Longer answers:



    Popular convention: in typical use the name of the .h file is derived from the .c file, or files, it is associated with. file.h and file.c. For .h files with many definitions, say string.h, derive the file name from a hither perspective of what's within (as in the str... functions).



    My big rule: it’s always better to structure your code so compilers can immediately alert on bugs at compile time rather than letting them slide through to debug or run time where they depend on code actually running in just the right way to find. Run time errors can be very difficult to diagnose, especially if they hit long after the program is in production, and expensive in maintenance and brings down your customer experience. See "yoda notation".



    Q1: meaning of .h: consistency and early alerts and improved reliability of code.



    C .h files allow developers of .c files compiled at different times to share common declarations. No duplicate code. .h files also allow functions to be consistently called from all files while identifying improper argument signatures (argument counts, bad clashes, etc.). Having.c files defining functions also #include the .h file helps assure the arguments in the definition are consistent with the calls; this may sound elementary, but without it all the human errors of signature clashes can sneak through.



    Omitting .h files only works if the argument signatures of all callers perfectly match those in the definitions. This is often not the case so without .h files any clashing signatures would produce bad numbers unless you also had parallel externs in the calling file (bad bad bad). Things like int vs float can produce spectacularly wrong argument values. Bad pointers can produce segment faults and other total crashes.



    Advantage: with externs in .h files compilers can correctly cast mismatching arguments to the correct type, assuring better calls. While you can still botch arguments it’s much less likely. It also helps avoid conditions where the mismatches work on one implementation but not another.



    Implicit declaration warnings are hugely helpful to me as they usually indicate I’ve forgotten a .h file or spelled the name an external name wrong.



    Q2: Clashing Names. Early alerts.



    Clashing names are bad and it is the developers responsibility to avoid problems. C++ solves the issue with name spaces, which C, being a lower level language, does not have.



    Use of .h files can allow can let compiler diagnostics alert developers where clashes care are early in the game. If compiler diagnostics don’t do this hopefully linkers will do so on multidefined symbol errors, but this is not guaranteed by the standard.



    A common way to fake name spaces is by starting all potentially clashing definitions in a .h with some prefix (extern int filex_function1(int arg, char *string) or #define FILEX_DEF 42).



    What to do if two different external libraries being used share the same names is beyond the scope of this answer.



    Q3: early duplicate alerts. Sorry… early alerts are implementation dependent.



    This would be difficult for the C standard to define. As C is an old language there are many creative different ways C programs are written and stored.
    Hunting for clashing names before using them is up to the developer. Tools like cross reference programs can help. Even something stupid like ctags associated with vim or emacs can help.






    share|improve this answer






























      up vote
      1
      down vote













      you misunderstand usage of header files and function prototypes.




      1. header files are needed to share common information between multiple code files. such information includes macro definition, data types, and, possibly, function prototypes.


      2. function protoypes are needed for the compiler to correctly handle return data types and to give you early warnings of misuse of function return types and arguments.


      3. function prototypes can be declared in header files or can be declared in the files which use them (more typing).



      you have a very simple example, with just 2 files. Now imagine a project with hudreds of files and thousands of functions. You will be lost in linker errors.



      'c' allows you to use an undeclared function due to legacy reasons. In this situation it assumes that the function has a return type of 'int'. However, modern data types has a bigger veriety than in early days. The function can return pointers, 64-bit data, structures. To express that you must use prototypes or nothing will work. The compiler has to know how to handle function returns correctly.



      Also, it can give you warnings about incorrect use of argument types. Due to leagacy, those are still warnings, but they got addressed in early c++ and converted to errors.



      Those warnings give you early debugging capabilities. Type mismatch warnings can save you days of debugging in some cases.



      So, in your example you do not need the header file. You can prototype the function in the 'main' file using the 'extern' syntax. You can even do without prototyping. However, in real modern programming world you cannot allow the latter. In particular when you work in a team or want your program to be maintainable.



      It is a good idea to store you funcion protypes in header files. This would be a good documentation source, in particular with good comments. BTW, function names must make sense to be maintainable.






      share|improve this answer




























        up vote
        -1
        down vote













        Q1. Yes. C is a low level language, and was historically used to bind low level constructs into higher level concepts. For example, traditionally the label _end is at the last address in a program. The label is typeless but you can declare it as any type that is convenient to you. A "properly typed" language would make this sort of abuse difficult.



        Q2. By convention, both file1.c and file2.c would include file2.h; one as consumer, the other as producer. Following this simple idiom will catch declaration vs definition errors; although again, the "warning" is not necessarily enforced.



        Q3. Many software organizations take a "warnings are errors" rule to socially control their programmers.






        share|improve this answer





















          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254290%2fis-the-purpose-of-header-files-in-c-only-warning-to-users%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          4 Answers
          4






          active

          oldest

          votes








          4 Answers
          4






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          1
          down vote













          Per C89 3.3.2.2 Function calls emphasis mine:




          If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration



              extern int  identifier();


          appeared




          Now, remember, empty parameter list (declared with nothing inside the () braces) declares a function that takes unspecified type and number of arguments. Type void inside braces to declare that a function takes no arguments, like int func(void).



          Q1:




          does this warning help a lot?




          Yes and no. This is a subjective question. It helps those, who use it. As a personal note, always make this warning an error. Using gcc compiler use -Werror=implicit-function-declaration. But you can also ignore this warning and make the simplest main() { printf("hello world!n"); } program.




          linker will do its job to produce the final executable file? so the only purpose of include file2,c to me is, don't show any warning during compilation, is my understanding correct.




          No. In cases the function is called using different/not-compatible pointer type. It invokes undefined behavior. If the function is declared as void (*function2(void))(int a); then calling ((int(*)())function2)() is UB as is calling function2() without previous declaration. Per Annex J.2 (informative):




          The behavior is undefined in the following circumstances:



          A pointer is used to call a function whose type is not compatible with the pointed-to type (6.3.2.3).




          and per C11 6.3.2.3p8:




          A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.




          So in your lucky case int function2() indeed this works. It also works for example for atoi() function. But calling atol() will invoke undefined behavior.



          Q2:




          the linker throws the error




          This should happen, but is really linker dependent. If you compile all sources using a single stage with the gcc compiler it will throw an error. But if you create static libraries and then link them using gcc compiler without -Wl,-whole-archive then it will pick the first declaration is sees, see this thread.




          what's the purpose of adding header file?




          I guess simplicity and order. It is a convenient and standard way to share data structures (enum, struct, typedefs) and declarations (function and variable types) between developers and libraries. Also to share preprocessor directives. Image you are writing a big library with over 1000+ files that will work with over 100+ other libraries. In the beginning of each file would you write struct mydata_s { int member1; int member2; ... }; int printf(const char*, ...); int scanf(const char *, ...); etc. or just #include "mydata.h" and #include <stdio.h>? If you would need to change mydata_s structure, you would need to change all files in your project and all the other developers which use your library would need to change the definition too. I don't say you can't do it, but it would be more work to do it and no one will use your library.



          Q3:




          What should we add to let the programmer know he should choose a different name for function2 rather then be informed the error by linker in the final stage.




          In case of name clashes you will by informed (hopefully) by the linker that it found two identifiers with the same name. You would need to create a tool to check your sources exactly for that. I don't know why the need for this, the linker is specifically made to resolve symbols so it naturally handles the cases when two symbols with the same identifier exists.






          share|improve this answer



























            up vote
            1
            down vote













            Per C89 3.3.2.2 Function calls emphasis mine:




            If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration



                extern int  identifier();


            appeared




            Now, remember, empty parameter list (declared with nothing inside the () braces) declares a function that takes unspecified type and number of arguments. Type void inside braces to declare that a function takes no arguments, like int func(void).



            Q1:




            does this warning help a lot?




            Yes and no. This is a subjective question. It helps those, who use it. As a personal note, always make this warning an error. Using gcc compiler use -Werror=implicit-function-declaration. But you can also ignore this warning and make the simplest main() { printf("hello world!n"); } program.




            linker will do its job to produce the final executable file? so the only purpose of include file2,c to me is, don't show any warning during compilation, is my understanding correct.




            No. In cases the function is called using different/not-compatible pointer type. It invokes undefined behavior. If the function is declared as void (*function2(void))(int a); then calling ((int(*)())function2)() is UB as is calling function2() without previous declaration. Per Annex J.2 (informative):




            The behavior is undefined in the following circumstances:



            A pointer is used to call a function whose type is not compatible with the pointed-to type (6.3.2.3).




            and per C11 6.3.2.3p8:




            A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.




            So in your lucky case int function2() indeed this works. It also works for example for atoi() function. But calling atol() will invoke undefined behavior.



            Q2:




            the linker throws the error




            This should happen, but is really linker dependent. If you compile all sources using a single stage with the gcc compiler it will throw an error. But if you create static libraries and then link them using gcc compiler without -Wl,-whole-archive then it will pick the first declaration is sees, see this thread.




            what's the purpose of adding header file?




            I guess simplicity and order. It is a convenient and standard way to share data structures (enum, struct, typedefs) and declarations (function and variable types) between developers and libraries. Also to share preprocessor directives. Image you are writing a big library with over 1000+ files that will work with over 100+ other libraries. In the beginning of each file would you write struct mydata_s { int member1; int member2; ... }; int printf(const char*, ...); int scanf(const char *, ...); etc. or just #include "mydata.h" and #include <stdio.h>? If you would need to change mydata_s structure, you would need to change all files in your project and all the other developers which use your library would need to change the definition too. I don't say you can't do it, but it would be more work to do it and no one will use your library.



            Q3:




            What should we add to let the programmer know he should choose a different name for function2 rather then be informed the error by linker in the final stage.




            In case of name clashes you will by informed (hopefully) by the linker that it found two identifiers with the same name. You would need to create a tool to check your sources exactly for that. I don't know why the need for this, the linker is specifically made to resolve symbols so it naturally handles the cases when two symbols with the same identifier exists.






            share|improve this answer

























              up vote
              1
              down vote










              up vote
              1
              down vote









              Per C89 3.3.2.2 Function calls emphasis mine:




              If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration



                  extern int  identifier();


              appeared




              Now, remember, empty parameter list (declared with nothing inside the () braces) declares a function that takes unspecified type and number of arguments. Type void inside braces to declare that a function takes no arguments, like int func(void).



              Q1:




              does this warning help a lot?




              Yes and no. This is a subjective question. It helps those, who use it. As a personal note, always make this warning an error. Using gcc compiler use -Werror=implicit-function-declaration. But you can also ignore this warning and make the simplest main() { printf("hello world!n"); } program.




              linker will do its job to produce the final executable file? so the only purpose of include file2,c to me is, don't show any warning during compilation, is my understanding correct.




              No. In cases the function is called using different/not-compatible pointer type. It invokes undefined behavior. If the function is declared as void (*function2(void))(int a); then calling ((int(*)())function2)() is UB as is calling function2() without previous declaration. Per Annex J.2 (informative):




              The behavior is undefined in the following circumstances:



              A pointer is used to call a function whose type is not compatible with the pointed-to type (6.3.2.3).




              and per C11 6.3.2.3p8:




              A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.




              So in your lucky case int function2() indeed this works. It also works for example for atoi() function. But calling atol() will invoke undefined behavior.



              Q2:




              the linker throws the error




              This should happen, but is really linker dependent. If you compile all sources using a single stage with the gcc compiler it will throw an error. But if you create static libraries and then link them using gcc compiler without -Wl,-whole-archive then it will pick the first declaration is sees, see this thread.




              what's the purpose of adding header file?




              I guess simplicity and order. It is a convenient and standard way to share data structures (enum, struct, typedefs) and declarations (function and variable types) between developers and libraries. Also to share preprocessor directives. Image you are writing a big library with over 1000+ files that will work with over 100+ other libraries. In the beginning of each file would you write struct mydata_s { int member1; int member2; ... }; int printf(const char*, ...); int scanf(const char *, ...); etc. or just #include "mydata.h" and #include <stdio.h>? If you would need to change mydata_s structure, you would need to change all files in your project and all the other developers which use your library would need to change the definition too. I don't say you can't do it, but it would be more work to do it and no one will use your library.



              Q3:




              What should we add to let the programmer know he should choose a different name for function2 rather then be informed the error by linker in the final stage.




              In case of name clashes you will by informed (hopefully) by the linker that it found two identifiers with the same name. You would need to create a tool to check your sources exactly for that. I don't know why the need for this, the linker is specifically made to resolve symbols so it naturally handles the cases when two symbols with the same identifier exists.






              share|improve this answer














              Per C89 3.3.2.2 Function calls emphasis mine:




              If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration



                  extern int  identifier();


              appeared




              Now, remember, empty parameter list (declared with nothing inside the () braces) declares a function that takes unspecified type and number of arguments. Type void inside braces to declare that a function takes no arguments, like int func(void).



              Q1:




              does this warning help a lot?




              Yes and no. This is a subjective question. It helps those, who use it. As a personal note, always make this warning an error. Using gcc compiler use -Werror=implicit-function-declaration. But you can also ignore this warning and make the simplest main() { printf("hello world!n"); } program.




              linker will do its job to produce the final executable file? so the only purpose of include file2,c to me is, don't show any warning during compilation, is my understanding correct.




              No. In cases the function is called using different/not-compatible pointer type. It invokes undefined behavior. If the function is declared as void (*function2(void))(int a); then calling ((int(*)())function2)() is UB as is calling function2() without previous declaration. Per Annex J.2 (informative):




              The behavior is undefined in the following circumstances:



              A pointer is used to call a function whose type is not compatible with the pointed-to type (6.3.2.3).




              and per C11 6.3.2.3p8:




              A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.




              So in your lucky case int function2() indeed this works. It also works for example for atoi() function. But calling atol() will invoke undefined behavior.



              Q2:




              the linker throws the error




              This should happen, but is really linker dependent. If you compile all sources using a single stage with the gcc compiler it will throw an error. But if you create static libraries and then link them using gcc compiler without -Wl,-whole-archive then it will pick the first declaration is sees, see this thread.




              what's the purpose of adding header file?




              I guess simplicity and order. It is a convenient and standard way to share data structures (enum, struct, typedefs) and declarations (function and variable types) between developers and libraries. Also to share preprocessor directives. Image you are writing a big library with over 1000+ files that will work with over 100+ other libraries. In the beginning of each file would you write struct mydata_s { int member1; int member2; ... }; int printf(const char*, ...); int scanf(const char *, ...); etc. or just #include "mydata.h" and #include <stdio.h>? If you would need to change mydata_s structure, you would need to change all files in your project and all the other developers which use your library would need to change the definition too. I don't say you can't do it, but it would be more work to do it and no one will use your library.



              Q3:




              What should we add to let the programmer know he should choose a different name for function2 rather then be informed the error by linker in the final stage.




              In case of name clashes you will by informed (hopefully) by the linker that it found two identifiers with the same name. You would need to create a tool to check your sources exactly for that. I don't know why the need for this, the linker is specifically made to resolve symbols so it naturally handles the cases when two symbols with the same identifier exists.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Nov 12 at 1:34

























              answered Nov 12 at 1:27









              Kamil Cuk

              8,2261422




              8,2261422
























                  up vote
                  1
                  down vote













                  Short answer:



                  Take away: the earlier the compiler alert the better.



                  Q1: meaning of .h: consistency and early alerts. Alerting early on common ways of going wrong improves reliability of code and adds up to less debugging and production crashes.



                  Q2: Clashing Names bring early alerts to developers, which are usually easier to fix.



                  Q3: Early duplicate definition alerts are not baked into the C standard.



                  Exercises:
                  1. Define a function in one file that printf("%dn",i) an int argument then call that function in another file with a float of 42.0.
                  2. Call with (double)42.0.
                  3. Define function with char *str argument printed under %.s then call with int argument.



                  Longer answers:



                  Popular convention: in typical use the name of the .h file is derived from the .c file, or files, it is associated with. file.h and file.c. For .h files with many definitions, say string.h, derive the file name from a hither perspective of what's within (as in the str... functions).



                  My big rule: it’s always better to structure your code so compilers can immediately alert on bugs at compile time rather than letting them slide through to debug or run time where they depend on code actually running in just the right way to find. Run time errors can be very difficult to diagnose, especially if they hit long after the program is in production, and expensive in maintenance and brings down your customer experience. See "yoda notation".



                  Q1: meaning of .h: consistency and early alerts and improved reliability of code.



                  C .h files allow developers of .c files compiled at different times to share common declarations. No duplicate code. .h files also allow functions to be consistently called from all files while identifying improper argument signatures (argument counts, bad clashes, etc.). Having.c files defining functions also #include the .h file helps assure the arguments in the definition are consistent with the calls; this may sound elementary, but without it all the human errors of signature clashes can sneak through.



                  Omitting .h files only works if the argument signatures of all callers perfectly match those in the definitions. This is often not the case so without .h files any clashing signatures would produce bad numbers unless you also had parallel externs in the calling file (bad bad bad). Things like int vs float can produce spectacularly wrong argument values. Bad pointers can produce segment faults and other total crashes.



                  Advantage: with externs in .h files compilers can correctly cast mismatching arguments to the correct type, assuring better calls. While you can still botch arguments it’s much less likely. It also helps avoid conditions where the mismatches work on one implementation but not another.



                  Implicit declaration warnings are hugely helpful to me as they usually indicate I’ve forgotten a .h file or spelled the name an external name wrong.



                  Q2: Clashing Names. Early alerts.



                  Clashing names are bad and it is the developers responsibility to avoid problems. C++ solves the issue with name spaces, which C, being a lower level language, does not have.



                  Use of .h files can allow can let compiler diagnostics alert developers where clashes care are early in the game. If compiler diagnostics don’t do this hopefully linkers will do so on multidefined symbol errors, but this is not guaranteed by the standard.



                  A common way to fake name spaces is by starting all potentially clashing definitions in a .h with some prefix (extern int filex_function1(int arg, char *string) or #define FILEX_DEF 42).



                  What to do if two different external libraries being used share the same names is beyond the scope of this answer.



                  Q3: early duplicate alerts. Sorry… early alerts are implementation dependent.



                  This would be difficult for the C standard to define. As C is an old language there are many creative different ways C programs are written and stored.
                  Hunting for clashing names before using them is up to the developer. Tools like cross reference programs can help. Even something stupid like ctags associated with vim or emacs can help.






                  share|improve this answer



























                    up vote
                    1
                    down vote













                    Short answer:



                    Take away: the earlier the compiler alert the better.



                    Q1: meaning of .h: consistency and early alerts. Alerting early on common ways of going wrong improves reliability of code and adds up to less debugging and production crashes.



                    Q2: Clashing Names bring early alerts to developers, which are usually easier to fix.



                    Q3: Early duplicate definition alerts are not baked into the C standard.



                    Exercises:
                    1. Define a function in one file that printf("%dn",i) an int argument then call that function in another file with a float of 42.0.
                    2. Call with (double)42.0.
                    3. Define function with char *str argument printed under %.s then call with int argument.



                    Longer answers:



                    Popular convention: in typical use the name of the .h file is derived from the .c file, or files, it is associated with. file.h and file.c. For .h files with many definitions, say string.h, derive the file name from a hither perspective of what's within (as in the str... functions).



                    My big rule: it’s always better to structure your code so compilers can immediately alert on bugs at compile time rather than letting them slide through to debug or run time where they depend on code actually running in just the right way to find. Run time errors can be very difficult to diagnose, especially if they hit long after the program is in production, and expensive in maintenance and brings down your customer experience. See "yoda notation".



                    Q1: meaning of .h: consistency and early alerts and improved reliability of code.



                    C .h files allow developers of .c files compiled at different times to share common declarations. No duplicate code. .h files also allow functions to be consistently called from all files while identifying improper argument signatures (argument counts, bad clashes, etc.). Having.c files defining functions also #include the .h file helps assure the arguments in the definition are consistent with the calls; this may sound elementary, but without it all the human errors of signature clashes can sneak through.



                    Omitting .h files only works if the argument signatures of all callers perfectly match those in the definitions. This is often not the case so without .h files any clashing signatures would produce bad numbers unless you also had parallel externs in the calling file (bad bad bad). Things like int vs float can produce spectacularly wrong argument values. Bad pointers can produce segment faults and other total crashes.



                    Advantage: with externs in .h files compilers can correctly cast mismatching arguments to the correct type, assuring better calls. While you can still botch arguments it’s much less likely. It also helps avoid conditions where the mismatches work on one implementation but not another.



                    Implicit declaration warnings are hugely helpful to me as they usually indicate I’ve forgotten a .h file or spelled the name an external name wrong.



                    Q2: Clashing Names. Early alerts.



                    Clashing names are bad and it is the developers responsibility to avoid problems. C++ solves the issue with name spaces, which C, being a lower level language, does not have.



                    Use of .h files can allow can let compiler diagnostics alert developers where clashes care are early in the game. If compiler diagnostics don’t do this hopefully linkers will do so on multidefined symbol errors, but this is not guaranteed by the standard.



                    A common way to fake name spaces is by starting all potentially clashing definitions in a .h with some prefix (extern int filex_function1(int arg, char *string) or #define FILEX_DEF 42).



                    What to do if two different external libraries being used share the same names is beyond the scope of this answer.



                    Q3: early duplicate alerts. Sorry… early alerts are implementation dependent.



                    This would be difficult for the C standard to define. As C is an old language there are many creative different ways C programs are written and stored.
                    Hunting for clashing names before using them is up to the developer. Tools like cross reference programs can help. Even something stupid like ctags associated with vim or emacs can help.






                    share|improve this answer

























                      up vote
                      1
                      down vote










                      up vote
                      1
                      down vote









                      Short answer:



                      Take away: the earlier the compiler alert the better.



                      Q1: meaning of .h: consistency and early alerts. Alerting early on common ways of going wrong improves reliability of code and adds up to less debugging and production crashes.



                      Q2: Clashing Names bring early alerts to developers, which are usually easier to fix.



                      Q3: Early duplicate definition alerts are not baked into the C standard.



                      Exercises:
                      1. Define a function in one file that printf("%dn",i) an int argument then call that function in another file with a float of 42.0.
                      2. Call with (double)42.0.
                      3. Define function with char *str argument printed under %.s then call with int argument.



                      Longer answers:



                      Popular convention: in typical use the name of the .h file is derived from the .c file, or files, it is associated with. file.h and file.c. For .h files with many definitions, say string.h, derive the file name from a hither perspective of what's within (as in the str... functions).



                      My big rule: it’s always better to structure your code so compilers can immediately alert on bugs at compile time rather than letting them slide through to debug or run time where they depend on code actually running in just the right way to find. Run time errors can be very difficult to diagnose, especially if they hit long after the program is in production, and expensive in maintenance and brings down your customer experience. See "yoda notation".



                      Q1: meaning of .h: consistency and early alerts and improved reliability of code.



                      C .h files allow developers of .c files compiled at different times to share common declarations. No duplicate code. .h files also allow functions to be consistently called from all files while identifying improper argument signatures (argument counts, bad clashes, etc.). Having.c files defining functions also #include the .h file helps assure the arguments in the definition are consistent with the calls; this may sound elementary, but without it all the human errors of signature clashes can sneak through.



                      Omitting .h files only works if the argument signatures of all callers perfectly match those in the definitions. This is often not the case so without .h files any clashing signatures would produce bad numbers unless you also had parallel externs in the calling file (bad bad bad). Things like int vs float can produce spectacularly wrong argument values. Bad pointers can produce segment faults and other total crashes.



                      Advantage: with externs in .h files compilers can correctly cast mismatching arguments to the correct type, assuring better calls. While you can still botch arguments it’s much less likely. It also helps avoid conditions where the mismatches work on one implementation but not another.



                      Implicit declaration warnings are hugely helpful to me as they usually indicate I’ve forgotten a .h file or spelled the name an external name wrong.



                      Q2: Clashing Names. Early alerts.



                      Clashing names are bad and it is the developers responsibility to avoid problems. C++ solves the issue with name spaces, which C, being a lower level language, does not have.



                      Use of .h files can allow can let compiler diagnostics alert developers where clashes care are early in the game. If compiler diagnostics don’t do this hopefully linkers will do so on multidefined symbol errors, but this is not guaranteed by the standard.



                      A common way to fake name spaces is by starting all potentially clashing definitions in a .h with some prefix (extern int filex_function1(int arg, char *string) or #define FILEX_DEF 42).



                      What to do if two different external libraries being used share the same names is beyond the scope of this answer.



                      Q3: early duplicate alerts. Sorry… early alerts are implementation dependent.



                      This would be difficult for the C standard to define. As C is an old language there are many creative different ways C programs are written and stored.
                      Hunting for clashing names before using them is up to the developer. Tools like cross reference programs can help. Even something stupid like ctags associated with vim or emacs can help.






                      share|improve this answer














                      Short answer:



                      Take away: the earlier the compiler alert the better.



                      Q1: meaning of .h: consistency and early alerts. Alerting early on common ways of going wrong improves reliability of code and adds up to less debugging and production crashes.



                      Q2: Clashing Names bring early alerts to developers, which are usually easier to fix.



                      Q3: Early duplicate definition alerts are not baked into the C standard.



                      Exercises:
                      1. Define a function in one file that printf("%dn",i) an int argument then call that function in another file with a float of 42.0.
                      2. Call with (double)42.0.
                      3. Define function with char *str argument printed under %.s then call with int argument.



                      Longer answers:



                      Popular convention: in typical use the name of the .h file is derived from the .c file, or files, it is associated with. file.h and file.c. For .h files with many definitions, say string.h, derive the file name from a hither perspective of what's within (as in the str... functions).



                      My big rule: it’s always better to structure your code so compilers can immediately alert on bugs at compile time rather than letting them slide through to debug or run time where they depend on code actually running in just the right way to find. Run time errors can be very difficult to diagnose, especially if they hit long after the program is in production, and expensive in maintenance and brings down your customer experience. See "yoda notation".



                      Q1: meaning of .h: consistency and early alerts and improved reliability of code.



                      C .h files allow developers of .c files compiled at different times to share common declarations. No duplicate code. .h files also allow functions to be consistently called from all files while identifying improper argument signatures (argument counts, bad clashes, etc.). Having.c files defining functions also #include the .h file helps assure the arguments in the definition are consistent with the calls; this may sound elementary, but without it all the human errors of signature clashes can sneak through.



                      Omitting .h files only works if the argument signatures of all callers perfectly match those in the definitions. This is often not the case so without .h files any clashing signatures would produce bad numbers unless you also had parallel externs in the calling file (bad bad bad). Things like int vs float can produce spectacularly wrong argument values. Bad pointers can produce segment faults and other total crashes.



                      Advantage: with externs in .h files compilers can correctly cast mismatching arguments to the correct type, assuring better calls. While you can still botch arguments it’s much less likely. It also helps avoid conditions where the mismatches work on one implementation but not another.



                      Implicit declaration warnings are hugely helpful to me as they usually indicate I’ve forgotten a .h file or spelled the name an external name wrong.



                      Q2: Clashing Names. Early alerts.



                      Clashing names are bad and it is the developers responsibility to avoid problems. C++ solves the issue with name spaces, which C, being a lower level language, does not have.



                      Use of .h files can allow can let compiler diagnostics alert developers where clashes care are early in the game. If compiler diagnostics don’t do this hopefully linkers will do so on multidefined symbol errors, but this is not guaranteed by the standard.



                      A common way to fake name spaces is by starting all potentially clashing definitions in a .h with some prefix (extern int filex_function1(int arg, char *string) or #define FILEX_DEF 42).



                      What to do if two different external libraries being used share the same names is beyond the scope of this answer.



                      Q3: early duplicate alerts. Sorry… early alerts are implementation dependent.



                      This would be difficult for the C standard to define. As C is an old language there are many creative different ways C programs are written and stored.
                      Hunting for clashing names before using them is up to the developer. Tools like cross reference programs can help. Even something stupid like ctags associated with vim or emacs can help.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 12 at 2:58

























                      answered Nov 12 at 2:27









                      Gilbert

                      2,7441012




                      2,7441012






















                          up vote
                          1
                          down vote













                          you misunderstand usage of header files and function prototypes.




                          1. header files are needed to share common information between multiple code files. such information includes macro definition, data types, and, possibly, function prototypes.


                          2. function protoypes are needed for the compiler to correctly handle return data types and to give you early warnings of misuse of function return types and arguments.


                          3. function prototypes can be declared in header files or can be declared in the files which use them (more typing).



                          you have a very simple example, with just 2 files. Now imagine a project with hudreds of files and thousands of functions. You will be lost in linker errors.



                          'c' allows you to use an undeclared function due to legacy reasons. In this situation it assumes that the function has a return type of 'int'. However, modern data types has a bigger veriety than in early days. The function can return pointers, 64-bit data, structures. To express that you must use prototypes or nothing will work. The compiler has to know how to handle function returns correctly.



                          Also, it can give you warnings about incorrect use of argument types. Due to leagacy, those are still warnings, but they got addressed in early c++ and converted to errors.



                          Those warnings give you early debugging capabilities. Type mismatch warnings can save you days of debugging in some cases.



                          So, in your example you do not need the header file. You can prototype the function in the 'main' file using the 'extern' syntax. You can even do without prototyping. However, in real modern programming world you cannot allow the latter. In particular when you work in a team or want your program to be maintainable.



                          It is a good idea to store you funcion protypes in header files. This would be a good documentation source, in particular with good comments. BTW, function names must make sense to be maintainable.






                          share|improve this answer

























                            up vote
                            1
                            down vote













                            you misunderstand usage of header files and function prototypes.




                            1. header files are needed to share common information between multiple code files. such information includes macro definition, data types, and, possibly, function prototypes.


                            2. function protoypes are needed for the compiler to correctly handle return data types and to give you early warnings of misuse of function return types and arguments.


                            3. function prototypes can be declared in header files or can be declared in the files which use them (more typing).



                            you have a very simple example, with just 2 files. Now imagine a project with hudreds of files and thousands of functions. You will be lost in linker errors.



                            'c' allows you to use an undeclared function due to legacy reasons. In this situation it assumes that the function has a return type of 'int'. However, modern data types has a bigger veriety than in early days. The function can return pointers, 64-bit data, structures. To express that you must use prototypes or nothing will work. The compiler has to know how to handle function returns correctly.



                            Also, it can give you warnings about incorrect use of argument types. Due to leagacy, those are still warnings, but they got addressed in early c++ and converted to errors.



                            Those warnings give you early debugging capabilities. Type mismatch warnings can save you days of debugging in some cases.



                            So, in your example you do not need the header file. You can prototype the function in the 'main' file using the 'extern' syntax. You can even do without prototyping. However, in real modern programming world you cannot allow the latter. In particular when you work in a team or want your program to be maintainable.



                            It is a good idea to store you funcion protypes in header files. This would be a good documentation source, in particular with good comments. BTW, function names must make sense to be maintainable.






                            share|improve this answer























                              up vote
                              1
                              down vote










                              up vote
                              1
                              down vote









                              you misunderstand usage of header files and function prototypes.




                              1. header files are needed to share common information between multiple code files. such information includes macro definition, data types, and, possibly, function prototypes.


                              2. function protoypes are needed for the compiler to correctly handle return data types and to give you early warnings of misuse of function return types and arguments.


                              3. function prototypes can be declared in header files or can be declared in the files which use them (more typing).



                              you have a very simple example, with just 2 files. Now imagine a project with hudreds of files and thousands of functions. You will be lost in linker errors.



                              'c' allows you to use an undeclared function due to legacy reasons. In this situation it assumes that the function has a return type of 'int'. However, modern data types has a bigger veriety than in early days. The function can return pointers, 64-bit data, structures. To express that you must use prototypes or nothing will work. The compiler has to know how to handle function returns correctly.



                              Also, it can give you warnings about incorrect use of argument types. Due to leagacy, those are still warnings, but they got addressed in early c++ and converted to errors.



                              Those warnings give you early debugging capabilities. Type mismatch warnings can save you days of debugging in some cases.



                              So, in your example you do not need the header file. You can prototype the function in the 'main' file using the 'extern' syntax. You can even do without prototyping. However, in real modern programming world you cannot allow the latter. In particular when you work in a team or want your program to be maintainable.



                              It is a good idea to store you funcion protypes in header files. This would be a good documentation source, in particular with good comments. BTW, function names must make sense to be maintainable.






                              share|improve this answer












                              you misunderstand usage of header files and function prototypes.




                              1. header files are needed to share common information between multiple code files. such information includes macro definition, data types, and, possibly, function prototypes.


                              2. function protoypes are needed for the compiler to correctly handle return data types and to give you early warnings of misuse of function return types and arguments.


                              3. function prototypes can be declared in header files or can be declared in the files which use them (more typing).



                              you have a very simple example, with just 2 files. Now imagine a project with hudreds of files and thousands of functions. You will be lost in linker errors.



                              'c' allows you to use an undeclared function due to legacy reasons. In this situation it assumes that the function has a return type of 'int'. However, modern data types has a bigger veriety than in early days. The function can return pointers, 64-bit data, structures. To express that you must use prototypes or nothing will work. The compiler has to know how to handle function returns correctly.



                              Also, it can give you warnings about incorrect use of argument types. Due to leagacy, those are still warnings, but they got addressed in early c++ and converted to errors.



                              Those warnings give you early debugging capabilities. Type mismatch warnings can save you days of debugging in some cases.



                              So, in your example you do not need the header file. You can prototype the function in the 'main' file using the 'extern' syntax. You can even do without prototyping. However, in real modern programming world you cannot allow the latter. In particular when you work in a team or want your program to be maintainable.



                              It is a good idea to store you funcion protypes in header files. This would be a good documentation source, in particular with good comments. BTW, function names must make sense to be maintainable.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 12 at 3:18









                              Serge

                              3,3732914




                              3,3732914






















                                  up vote
                                  -1
                                  down vote













                                  Q1. Yes. C is a low level language, and was historically used to bind low level constructs into higher level concepts. For example, traditionally the label _end is at the last address in a program. The label is typeless but you can declare it as any type that is convenient to you. A "properly typed" language would make this sort of abuse difficult.



                                  Q2. By convention, both file1.c and file2.c would include file2.h; one as consumer, the other as producer. Following this simple idiom will catch declaration vs definition errors; although again, the "warning" is not necessarily enforced.



                                  Q3. Many software organizations take a "warnings are errors" rule to socially control their programmers.






                                  share|improve this answer

























                                    up vote
                                    -1
                                    down vote













                                    Q1. Yes. C is a low level language, and was historically used to bind low level constructs into higher level concepts. For example, traditionally the label _end is at the last address in a program. The label is typeless but you can declare it as any type that is convenient to you. A "properly typed" language would make this sort of abuse difficult.



                                    Q2. By convention, both file1.c and file2.c would include file2.h; one as consumer, the other as producer. Following this simple idiom will catch declaration vs definition errors; although again, the "warning" is not necessarily enforced.



                                    Q3. Many software organizations take a "warnings are errors" rule to socially control their programmers.






                                    share|improve this answer























                                      up vote
                                      -1
                                      down vote










                                      up vote
                                      -1
                                      down vote









                                      Q1. Yes. C is a low level language, and was historically used to bind low level constructs into higher level concepts. For example, traditionally the label _end is at the last address in a program. The label is typeless but you can declare it as any type that is convenient to you. A "properly typed" language would make this sort of abuse difficult.



                                      Q2. By convention, both file1.c and file2.c would include file2.h; one as consumer, the other as producer. Following this simple idiom will catch declaration vs definition errors; although again, the "warning" is not necessarily enforced.



                                      Q3. Many software organizations take a "warnings are errors" rule to socially control their programmers.






                                      share|improve this answer












                                      Q1. Yes. C is a low level language, and was historically used to bind low level constructs into higher level concepts. For example, traditionally the label _end is at the last address in a program. The label is typeless but you can declare it as any type that is convenient to you. A "properly typed" language would make this sort of abuse difficult.



                                      Q2. By convention, both file1.c and file2.c would include file2.h; one as consumer, the other as producer. Following this simple idiom will catch declaration vs definition errors; although again, the "warning" is not necessarily enforced.



                                      Q3. Many software organizations take a "warnings are errors" rule to socially control their programmers.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Nov 12 at 0:11









                                      mevets

                                      1,880616




                                      1,880616






























                                          draft saved

                                          draft discarded




















































                                          Thanks for contributing an answer to Stack Overflow!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.





                                          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                          Please pay close attention to the following guidance:


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254290%2fis-the-purpose-of-header-files-in-c-only-warning-to-users%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          鏡平學校

                                          ꓛꓣだゔៀៅຸ໢ທຮ໕໒ ,ໂ'໥໓າ໼ឨឲ៵៭ៈゎゔit''䖳𥁄卿' ☨₤₨こゎもょの;ꜹꟚꞖꞵꟅꞛေၦေɯ,ɨɡ𛃵𛁹ޝ޳ޠ޾,ޤޒޯ޾𫝒𫠁သ𛅤チョ'サノބޘދ𛁐ᶿᶇᶀᶋᶠ㨑㽹⻮ꧬ꧹؍۩وَؠ㇕㇃㇪ ㇦㇋㇋ṜẰᵡᴠ 軌ᵕ搜۳ٰޗޮ޷ސޯ𫖾𫅀ल, ꙭ꙰ꚅꙁꚊꞻꝔ꟠Ꝭㄤﺟޱސꧨꧼ꧴ꧯꧽ꧲ꧯ'⽹⽭⾁⿞⼳⽋២៩ញណើꩯꩤ꩸ꩮᶻᶺᶧᶂ𫳲𫪭𬸄𫵰𬖩𬫣𬊉ၲ𛅬㕦䬺𫝌𫝼,,𫟖𫞽ហៅ஫㆔ాఆఅꙒꚞꙍ,Ꙟ꙱エ ,ポテ,フࢰࢯ𫟠𫞶 𫝤𫟠ﺕﹱﻜﻣ𪵕𪭸𪻆𪾩𫔷ġ,ŧآꞪ꟥,ꞔꝻ♚☹⛵𛀌ꬷꭞȄƁƪƬșƦǙǗdžƝǯǧⱦⱰꓕꓢႋ神 ဴ၀க௭எ௫ឫោ ' េㇷㇴㇼ神ㇸㇲㇽㇴㇼㇻㇸ'ㇸㇿㇸㇹㇰㆣꓚꓤ₡₧ ㄨㄟ㄂ㄖㄎ໗ツڒذ₶।ऩछएोञयूटक़कयँृी,冬'𛅢𛅥ㇱㇵㇶ𥄥𦒽𠣧𠊓𧢖𥞘𩔋цѰㄠſtʯʭɿʆʗʍʩɷɛ,əʏダヵㄐㄘR{gỚṖḺờṠṫảḙḭᴮᵏᴘᵀᵷᵕᴜᴏᵾq﮲ﲿﴽﭙ軌ﰬﶚﶧ﫲Ҝжюїкӈㇴffצּ﬘﭅﬈軌'ffistfflſtffतभफɳɰʊɲʎ𛁱𛁖𛁮𛀉 𛂯𛀞నఋŀŲ 𫟲𫠖𫞺ຆຆ ໹້໕໗ๆทԊꧢꧠ꧰ꓱ⿝⼑ŎḬẃẖỐẅ ,ờỰỈỗﮊDžȩꭏꭎꬻ꭮ꬿꭖꭥꭅ㇭神 ⾈ꓵꓑ⺄㄄ㄪㄙㄅㄇstA۵䞽ॶ𫞑𫝄㇉㇇゜軌𩜛𩳠Jﻺ‚Üမ႕ႌႊၐၸဓၞၞၡ៸wyvtᶎᶪᶹစဎ꣡꣰꣢꣤ٗ؋لㇳㇾㇻㇱ㆐㆔,,㆟Ⱶヤマފ޼ޝަݿݞݠݷݐ',ݘ,ݪݙݵ𬝉𬜁𫝨𫞘くせぉて¼óû×ó£…𛅑הㄙくԗԀ5606神45,神796'𪤻𫞧ꓐ㄁ㄘɥɺꓵꓲ3''7034׉ⱦⱠˆ“𫝋ȍ,ꩲ軌꩷ꩶꩧꩫఞ۔فڱێظペサ神ナᴦᵑ47 9238їﻂ䐊䔉㠸﬎ffiﬣ,לּᴷᴦᵛᵽ,ᴨᵤ ᵸᵥᴗᵈꚏꚉꚟ⻆rtǟƴ𬎎

                                          Why https connections are so slow when debugging (stepping over) in Java?