Going through the K&R ansi C programming language book (second version), on page 82 an example is given for a programming files/folders layout.
What I don't understand is, while calc.h gets included in main (use of functions), getop.c (definition of getop) and stack.c (definition of push and pop), it does not get included into getch.c, even though getch and ungetch are defined there.
Although it's a good idea to include the header file it's not required as getch.c doesn't actually use the function declared in calc.h, it could even get by if it only used those already defined in getch.c.
The reason it's a good idea to include the header file anyway is because it would provide some safety if you use modern style prototypes and definitions. The compiler should namely complain if for example getop isn't defined in getop.c with the same signature as in calc.h.
calc.h contains the declaration of getch() and ungetch(). It is included by files that want to use these functions (and, therefore, need their signature).
getch.c, instead, contains the definition of getch() and ungetch(). Therefore, there is no need of including their declaration (which is implicitly defined in the definition).
The omission you have so aptly discovered can be a source of a real problem. In order to benefit fully from C's static type checking across a multi-translation-unit program (which is almost anything nontrivial), we must ensure that the site which defines an external name (such as a function) as well as all the sites which refer to the name, have the same declaration in scope, ideally from a single source: one header file where that name is declared.
If the definition doesn't have the declaration in scope, then it is possible to change the definition so that it no longer matches the declaration. The program will still translate and link, resulting in undefined behavior when the function is called or the object is used.
If you use the GNU compiler, you can guard against this problem using -Wmissing-prototypes. Straight from the gcc manual page:
-Wmissing-prototypes (C and Objective-C only)
Warn if a global function is defined without a previous prototype
declaration. This warning is issued even if the definition itself
provides a prototype. The aim is to detect global functions that
fail to be declared in header files.
Without diagnosis, this kind of thing, such as forgetting a header file, can happen to the best of us.
One possible reason why the header was forgotten is that the example project uses the "one big common header" convention. The "one big common header" approach lets the programmer forget all about headers. Everything just sees everything else and the #include "calc.h" which makes it work is just a tiny footnote that can get swallowed up in the amnesia. :)
The other aspect is that the authors had spent a lot of time programming in pre-ANSI "Classic" C without prototype declarations. In Classic C, header files are mainly for common type declarations and macros. The habit is that if a source file doesn't need some type or macros that are defined in some header, then it doesn't need to include that header. A resurgence of that habit could be what is going on here.
Related
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.
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.
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("%d\n",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.
you misunderstand usage of header files and function prototypes.
header files are needed to share common information between multiple code files. such information includes macro definition, data types, and, possibly, function prototypes.
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.
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.
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.
I know that it's poor practice to not include function prototypes, but if you don't, then the compiler will infer a prototype based on what you pass into the function when you call it (according to this answer). My question is why does the compiler infer the prototype from what you pass into the function rather than the definition of the function itself? I can imagine some kind of preprocessing step where all declared functions are identified and checked to see if a prototype exists for each one. If one doesn't have a prototype, the first line of the function is copied and stuck under the existing prototypes. Why isn't this done?
Because the C compiler was designed as a single pass compiler, where any given file does not know about the other source files that make up the project.
Although compilers have gotten more sophisticated, and may do multiple passes, the general outline of the compilation process framework remains as it was in K&R's day:
Pre-process each source file(macro text replacement only).
Compile the processed source into an object file.
Link the objects into an executable or library.
Inferring prototypes would have to happen in the first step, but the compiler does not know about the existence of any other objects which may contain the function definition at that time.
It might be possible to make a compiler which did what you suggest, but not without breaking the existing rules for how to infer prototypes. A change with such big consequences would make the language no longer C.
The major use for prototypes is to declare a function and inform the compiler about the number and type of arguments in cases where the definition is not visible. Since C was originally compiled single-pass, the definition is not visible when it occurs later in the translation unit, but the more important case from a modern perspective is when the definition is not visible at all, due to lying in a separate translation unit, possibly even in a library file that exists only in compiled form and where no information about the function's type is recorded.
When I am going through a code snippet I have seen some functions like
#include <stdio.h>
int main() {
printf( "Upper case of a is %c\n", toupper('a'));
printf( "Upper case of 9 is %c\n", toupper('9'));
printf( "Upper case of g is %c\n", toupper('g'));
return 0;
}
being used in the source file without any header file being included.
So is there any default header file that gets added to source when compiling. I am using GNU C.
Please don't mind if the syntax of the function is wrong as that is not the important point.
No, there are no implicit #include directives.
What you're probably running into is that, prior to the 1999 ISO C standard, C permitted functions to be called with no visible declaration. The compiler would assume that the called function returns int and takes arguments compatible with the (promoted) arguments passed in the call.
gcc by default supports the 1990 ISO C standard plus GNU-specific extensions.
If you compile with something like gcc -std=c99 -pedantic, you'll get warnings about calls to functions with no visible declarations. (Use -std=gnu99 if you need GNU-specific extensions as well.)
Calling undeclared functions was a bad idea even before the 1999 standard. You should correct your code so there's a visible declaration (probably via a #include for the appropriate header) for each function you call or otherwise refer to.
Your original question asked about toUppercase, which is not a standard function; it may or may not be defined somewhere else.
Your revised question uses toupper, which is a standard C function declared in <ctype.h> and defined in the standard C library.
It's not surprising that you can get away with calling toupper with no visible declaration -- but you should still add
#include <ctype.h>
to the top of your source file.
Before you do that, try compiling with gcc -std=c99; you should get a warning.
One more thing: It's important to keep in mind that headers and libraries are two different things.
Headers, like <stdio.h> and <stdlib.h> are generally text files containing just declarations of functions and other entities specified by the C standard library.
Libraries, which have system-specific names like, for example, libc.so, contain the actual executable code that implements those functions.
Headers are handled by the compiler; libraries are handled by the linker.
There are generally no default headers; every header you use has to be explicitly #included, either directly or indirectly. libc.so (or whatever it's called) is typically linked by default; you don't have to specify it. (Though for the functions declared in <math.h>, you often have to specify -lm to link the corresponding library.)
As forum people are asking not to discuss in comments so i have no other option than replying to " Keith Thompson" last post. I am not sure what you meant by c standard library. look here
C standard library
It clearly says 27 header files are part of standard library and stdlib.h is one of them. See my point is not to argue with you. I am trying to have clarity in mind. You are saying something like libc.so as standard library but the wikipedia clearly states something else and now i am totally confused.
When I create a simple C program in Visual Studio 2010,
http://debugmode.net/2012/02/06/how-to-write-and-run-a-c-program-in-visual-studio-2010/
I remove the "#include < stdio.h > ",
My program still runs successfully, I could not understand how is it possible?
Any help is appreciated.
Regards,
The stdio.h header isn't strictly required unless you use functions declared in it, such as the following:
http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.12.html
Further looking at the code I believe the default behaviour when you don't have a prototype is to assume an int return type and to derive the types of parameters from the types of arguments which will work in this particular case. But it's generally a bad practice and should be avoided.
If that passed through the compiler / linker without any warnings you may want to check your environment settings. It's easy to forget to include an header and it can cause a lot of unintended and hard to track down side effects if you don't notice it.
The primary purpose of including standard header files is to include the declarations of standard functions into your source file.
However, the original standard C language (C89/90) did not require functions to be declared before they are called (aside from variadic functions, which have to be pre-declared with prototype to avoid undefined behavior). For this reason, as long as we are talking about non-variadic function calls, it is perfectly possible to write a correct program without pre-declaring standard functions, i.e. without including standard header files.
For example, calling strcmp function with two char * arguments is perfectly legal in C89/90 without pre-declaring strcmp. Meanwhile, printf has to be pre-declared with prototype, if you want your program to remain a valid C program with defined behavior.
This header file provides prototypes for a number of common functions and macros.
If you don't call any of those functions or macros, then you don't need it. If you do call them, it can still work as long as you are linking with the right libraries. But you could get some compiler errors or warnings if the compiler doesn't have those definitions.
#include < stdio.h >
It is a header file known as standard input output file. The input,output funcation are written in this file. funcations like printf,scanf etc.
Refere this http://computer.howstuffworks.com/c2.htm
I'm creating a large program that's supposed to be simulating a MIPS pipeline. I'm trying to modularize my code as much as possible to keep things simple, but I'm having trouble compiling.
Currently my program contains the files:
pipe.c --- Containing main
IF.h
ID.h
EX.h
MEM.h
WB.h
global.h --- containing global #define functions
reg.h
ALU.h
control.h
dMem.h
fBuffer.h
parser.h
bin.h
I'm new to C programming but I have protected myself against multiple includes using #ifndef, #define, #endif in every header file. My problem is that when I compile I get errors claiming: "previous implicit declaration of..."
Many of the header files are used by multiple files, so I'm not sure if this is the issue. Is there some sort of big thing that I'm missing?
an implicit declaration means that there was something that wasn't declared in a header (instead, the compiler simply found the function). a previous implicit declaration means that it's come across the declaration later, after assuming an implicit declaration for a "raw" function (or, i guess, as Doug suggests in the comments, another function with the same name).
there are a number of ways this can occur:
maybe you didn't include the header in the associated file. so IF.c doesn't include IF.h. the compiler will read IF.c and create the implicit definition. later, when it reads IF.h somewhere else, it will give this error.
maybe you use a function in a file that doesn't include the relevant header. so maybe IF.h defines myfunction(), but you use myfunction() in dMem.c and don't include IF.h there. so the compiler sees the use of myfunction() in dMem.c before it sees the definition in IF.h when included in IF.c.
without header files at all, you can get this with mutually recursive functions. see How to sort functions in C? "previous implicit declaration of a function was here" error
as Doug suggested, you define two functions with the same name (and don't have a definition in a header).
basically, somewhere, somehow, the compiler got to a function before it got to the header with the associated declaration. when it did find the header it realised things were messed up and generated the error.
(one classic source of header errors is cut+paste the "ifdefs" from one file to another and forget to change the name...)
[reading your question again i assumed you'd only listed the header files. but now i see that is all the files you have. why do you have so many more headers than source files? typically each source file is associated with one or two headers that contain the declarations for the functions it defines (although it will likely import others that it needs for support). this is unrelated to your compiler error, but it sounds like maybe you need to split your source up. it also suggests that either i have misunderstood you, or you are misunderstanding how headers are typically used.]