In: Computer Science
Question about user defined function.(language:c++)
If I were to make function, for example,
bool Function(char i){
If(i=='a')
return true;
return false;
}
In this situation, I want to use this function for main1.cpp, main2.cpp, and main3.cpp. To do that, I want to use this function as a header file to save time.
In Funtion.h file, I write bool Function(char i); between #ifndef,#define and #endif. (1)
In Function.cpp file, I write the body of Function(char i) after I put #Function.h (2)
In main1.cpp, main2.cpp, and main3.cpp files, I can use Function freely as long as I include #Function.h (3)
Here is the question,
1.Did the #ifndef and # define actually define the Function.h when the preprocessor read #Function.h in Function.cpp?
2.If so, in case that defined header file, Function.h is used in either main1.cpp, main2.cpp or mian3.cpp, Function.h will not be redefined because of the #ifndef,#define. It will just remian as it was first defined. Am I correct?
3.if 1,2 are correct, why computer defined Function.h using Function.cpp first though there were #include "Function.h" in both main1.cpp, main2.cpp mian3.cpp files and Function.cpp
4. Is there any particular rule for naming this? when it comes, for example, #ifndef FUNCTION_H ,#define FUNCTION_H. is this just a customary thing to do(using header file's name with all uppercase and underscore H)?
5.Can you explain the overall mechanism of this user-defined function with header file?
I'm new to c++, so sorry if my questions are kind of weird...
Please correct me if any of those questions is wrong.
1. The compiler does all the "reading" of files. The preprocessor does not "read" anything, it is a technique for preventing multiple definitions of files in the final program. So, to answer your first question, no, the preprocessor did not define the function.h file. Rather, the compiler saw the #include "function.h" in function.cpp and just copied and pasted all the contents in the .h file into one single text file, performed syntax checks, and compiled the .cpp file into an object file.
2. Again, nothing is being defined anywhere exactly, instead, you're making the compiler copy paste code from one file to another. Since each .cpp file is compiled into an object file separately, the copying of function.h will take place in every .cpp file as and when the .cpp file will be compiled. This will become more evident as you read the final answer.
3. The compiler compiles function.cpp first because it was probably told to do so by the programmer himself/herself. When you compile multiple files into object files, you usually use the commands:
g++ -c main1.cpp
g++ -c main2.cpp
g++ -c main3.cpp
g++ -c function.cpp
The compiler will compile the files in the order in which the commands were given. Here, the main.cpp file will be compiled first, followed by main2 and main3, and finally function.cpp. If the order of these commands were changed, the order of compilation would change too, although the final output file generated will be the same.
4. This is just a convention of naming, you could use any name in any case(uppercase/lowercase) after the #ifndef, its just a convention to use the name of the file in uppercase followed by an _H, just like it is a convention to give sensible variable names, although it is syntactically correct to give variables any name you want.
5. So, let us assume that there are three .cpp files, main1.cpp, main2.cpp and function.cpp, and one header file, function.h
Suppose the compilation commands you gave are as follows:
g++ -c function.cpp
g++ -c main1.cpp
g++ -c main2.cpp
Here, the compiler comes into play.
The compiler takes the function.cpp file, looks for all #includes (here, we have #include "function.h") in the file and copies and pastes these files (here it copies the function.cpp and function.h contents) into a single text file to perform syntax checks. Once these checks are passed, an object file is created called function.o and the next command is executed (g++ -c main1.cpp).
Similarly, the compiler takes the main1.cpp file, looks for all #includes (here, we have #include "function.h") in the file and copies and pastes these files (here it copies the main1.cpp and function.h contents) into a single text file to perform syntax checks and creates the main1.o object file. The same thing happens with main2.cpp
To produce the final executable, a linker is invoked to link the object files together. For any unresolved external variables or functions, the compiler will places a mark where the access happens. The linker will takes this mark and look for the code or variable in another listed object file, and if it's found, it combines the code from the two object files into an output file and replaces the mark with the final location of the function or variable.
So, where do the header guards come into play. It is clear that once the .cpp files are converted to object files, it doesn't matter if there have been any duplicate includes in multiple files.
Lets assume that function.h had #include <iostream> in its definition.
It is likely that main1.cpp and main2.cpp would also have #include <iostream> in its definition. Note that iostream is also a file which has header guards defined in itself. When compiling main1.cpp, the compiler copies the contents of the file iostream from the #include <iostream> inside main1.cpp, then it tries to copy the contents inside function.h. But function.h also has #include <iostream> defined inside it. Thus, this is where the head3er guard of iostream prevents the re-copying of the contents of iostream for the final text file of main1.cpp where the syntax checking would take place. It is here that header guards prevent the rise of any redefinition errors.