Can't we include .c file? - c++

Today I had an interview there they asked me can we include .c file to a source file?
I said yes. Because few years back I saw the same in some project where they have include .c file. But just now I was trying the same.
abc.c
#include<stdio.h>
void abc()
{ printf("From ABC() \n"); }
main.c
#include<stdio.h>
#include "abc.c"
int main()
{ void abc();
return 0;
}
Getting an error:
D:\Embedded\...\abc.c :- multiple definition of 'abc'
Where is it going wrong?
I wrote an abc.h file (the body of abc.h is { extern void abc(void); }),
and included the file in abc.c (commenting out #include abc.c). Worked fine.

Do it as follows:
abc.c:
#include <stdio.h>
void abc()
{printf("From ABC() \n");}
main.c:
#include<stdio.h>
#include "abc.c"
int main()
{
abc();
return 0;
}
(no need for the header file)
Then, to compile, you'd only compile main.c. Do not attempt to compile both abc.c and main.c, because then you'd have the abc() function defined twice.
You need to understand that #include is basically "copy-paste", nothing more. If you tell it #include "abc.c", it will simply take the contents of abc.c, and "paste" them in your main.c file. Therefore, using the above for main.c, after the preprocessor processes it, your main.c will look like this (I'm ignoring the #include <stdio.h>s):
#include<stdio.h>
#include <stdio.h>
void abc()
{printf("From ABC() \n");}
int main()
{
abc();
return 0;
}
which is a valid program.
That said you should generally not do this; you should compile all your .c files separately and only then link them together.

Including C files is perfectly valid as long as you do not try to compile the included C file by itself and then link it together with the object file from the C file which included the other file.
If you do so you'll have the same symbol (usually a function) defined in two files which will result in the errors you posted.
If you have multiple source files you usually do not include them but compile them separately. The linker then merges the object files into a single executable (or library).

You can include file with any extension.
In your program, you had re-defined void abc(); in main (). instead just put statement abc ();

You can include anything you like to, the preprocessor doesn't care about the file extensions. It's only some tradition to name the headers ".h" and the source files ".c" or ".cpp".
You only have to be sure, that after compiling the whole project you don't run into linker problems (e.g. giving both "abc.c" and "main.c" to the compiler would result in multiple definitions of your function).

Related

Static variable redefinition with Visual C++

I have 2 files each containing a static int variable which has the same name :
test-1.cpp:
#include "test-2.cpp"
static int a;
int main() {
}
test-2.cpp:
static int a;
void fonction() {
}
When I compile with cl test-1.cpp on command line, I get this error:
test-1.cpp(3): error C2086: 'int a' : redefinition
Because you include test2.cpp into test-1.cpp the actual code seen by the compiler is this:
static int a;
void fonction() {
}
static int a;
int main() {
}
Hence the redefinition.
The #include preprocessor command includes the file textually.
What you actually want is have both files test-1.cpp and test-2.cpp included into the Visual Studio project.
You want this:
test-1.cpp
#include "test-2.h"
static int a;
int main() {
fonction();
}
test-2.cpp
#include "test-2.h"
static int a;
void fonction() {
}
test-2.h
void fonction();
Of course, you are #including test-2.cpp in test-1.cpp. It's as if you have only one file. If you remove the #include and do this command
cl test-1.cpp test-2.cpp
then it will work.
This whole area is called separate compilation and it's something that newbies struggle with (it's also not often taught very well). Because of separate compilation you should never include one cpp file in another cpp file. Instead you should hand both files to the compiler so they can be compiled separately.
If one cpp file needs to know what's defined in another cpp file, then create a header file with declarations of what's in the second cpp file and include that in the first cpp file.
In this line;
#include "test-2.cpp"
you tell the preprocessor to put the content of test-2.cpp into test-1.cpp. Hence you define static int a; twice. This is not allowed. To fix this, remove the #include.
Note that you need to carefully distinguish between declarations (which can occur many times) and definitions (which can occur only once). Have a look at this thread for more info.

Multiple declaration vs not defined

I'm trying to import variables from a file that are used in a class in other file and ultimately import that to yet another file and compile.
Let me show what the reproduction of the problem looks like:
arrayFile.hpp
int arr[] = {
1,2,6,5,4,3
};
classFile.hpp
#include <iostream>
using namespace std;
#include "arrayFile.hpp"
class MyClass{
private:
int v1;
public:
MyClass();
void setV(int v);
int getV();
int funcM();
};
classFile.cpp
#include <iostream>
using namespace std;
#include "classFile.hpp"
MyClass::MyClass(){};
void MyClass::setV(int v){
v1 = v;
}
int MyClass::getV(){
return v1;
}
int MyClass::funcM(){
return v1*arr[0];
}
mainfile.cpp
#include <iostream>
using namespace std;
#include "classFolder/classFile.hpp"
// #include "classFolder/arrayFile.hpp"
// should i include this?
int main(){
MyClass c;
c.setV(3);
cout<<c.funcM()<<endl;
cout<<arr[0]<<'*'<<c.getV()<<endl;
}
The objective is to acess the array from both the classFile.cpp and mainfile.cpp, but I'm not managing to do this.
If I don't include arrayFile.cpp in mainfile.cpp:
/tmp/cce4ZHbp.o:(.data+0x0): multiple definition of `arr'
/tmp/ccmsYdmt.o:(.data+0x0): first defined here
If I do:
In file included from mainfile.cpp:5:0:
classFolder/arrayFile.hpp:1:9: error: redefinition of ‘int arr []’
int arr[] = {
^
In file included from classFolder/classFile.hpp:3:0,
from mainfile.cpp:4:
classFolder/arrayFile.hpp:1:5: note: ‘int arr [6]’ previously defined here
int arr[] = {
^
I've was able to get the compiler to tell me arr[] was undefined too, but am unable to reproduce this error.
What am I doing wrong?
The real issue I'm facing requires me to import an array and a struct to a class, and this class is imported to yet another bigger class, this last class is finally used by main. This is my best at reproducing it. I don't know how to fix this.
You should not include arrayFile.hpp inside your classFile.hpp. Include it only in classFile.cpp. Also, in mainfile.cpp (before main function) add line
extern int arr[];
This line tells the compiles that array of type int called "arr" will be defined in some other cpp file that will be linked together with mainfile.cpp.
Compile your program like this:
g++ -std=c++11 -c main.cpp classFile.cpp
g++ -std=c++11 main.o classFile.o
./a.out
First line compiles your files individually (creating main.o and classFile.o files)
Second line links them together creating one executable file (a.out)
Third line runs the executable file
Since adding new files makes this compilation process complicated, I suggest using a Makefile.
Broadly, it is not a good idea to define variables in a header file - assuming said header file will be included by multiple source files.
When you compile your project, the preprocessor handles "#include" statements by literally placing the content of the included header file in the file including it.
E.g.:
// foo.h
#ifndef FOO_H
#define FOO_H
typedef int myInt;
#endif
.
// main.cpp
#include "foo.h"
int main( int argc, char* argv[] )
{
return 0;
}
.
// preprocessor output
typedef int myInt;
int main( int argc, char* argv[] )
{
return 0;
}
This is a simplification - but good enough for illustrative purpose.
So what's happening in your example?
arrayFile.hpp is included by classFile.hpp which is included by classFile.cpp and mainfile.cpp. It may be helpful to consider the include-tree:
arrayFile.hpp
|
classFile.hpp
/ \
classFile.cpp mainfile.cpp
Think about what I said RE: replacing includes with the included file content and see if you don't agree when I say that classFile.cpp and mainfile.cpp both end up with a definition of your arr array.
What happens next when you're compiling your project? The compiler compiles your source code - specifically, the preprocessor output - to object files. E.g. the preprocessed classFile.cpp becomes classFile.o and the preprocessed mainfile.cpp becomes mainfile.o.
Finally, object files (or the libraries they are archived into) are linked to form your executable.
When the linker tries to link classFile.o and mainfile.o it will discover that both have arr defined in them. Thus you get your multiple definition linker error - not a compiler error.
So: if a header file is included - directly or indirectly - by multiple source files, you'll run into linker errors if the header file defines variables. This is why, it is standard practice to declare variables in header files and define them in one source file.
Hope that helps.

How to define function in other source file:C++ CodeBlocks

I am trying to separate my functions in another source file. But i am getting error that multiple definition on add function.
Main source file
Main.cpp
#include<iostream>
#include "myHeader.h"
using namespace std;
int main()
{
int result = add(1,2);
}
Header file "myHeader.h"
#include "calc.cpp"
int add(int, int);
Other Source file "calc.cpp"
int add(int a, int b)
{
return a+b;
}
What you need is:
"myHeader.h"
#ifndef MY_HEADER
#define MY_HEADER
int add(int, int);
#endif
calc.cpp
#include "myHeader.h"
int add(int a, int b)
{
return a+b;
}
main.cpp
#include "myHeader.h"
int main()
{
int result = add(1,2);
return 0;
}
You don't include the .cpp into the .h . The header file is used to tell the compiler the existence of a function with the specified prototype, but the liker will be tke care of matching up the call to a function with the implementation of that function.
Also, it's usually a good idea to give you header file and .cpp the same name, so calc.h and calc.cpp rather than myHeader.h.
Don't include calc.cpp from myHeader.h. Except for that one line, your example is right as far as headers go. (main() should return a value).
calc.cpp and main.cpp are two different "compilation units" which will be compiled separately into object files. The two object files are then combined into one executable by a linker.
You problem is that you include a Code File (cpp) into a header. You should do the inverse. Include your header "myHeader.h" into calc.cpp. And to be coherent, you should name your header the same name as your Code file, so calc.h for the header and calc.cpp for you code.
This is pretty simple. Do not Include your "calc.cpp" file in "MyHeader.h" file.
Take also a look at C/C++ IncludeGuard here
This is a fundamental of C/C++ programming. You will need to use it many times.
Protect your "myHeader.h"
#ifndef ADD_HEADER
#define ADD_HEADER
int add(int, int);
#endif // ADD_HEADER
#include "calc.cpp"
Don't do that - it includes the function definition in any translation unit that includes the header, so you'll end up with multiple definitions.
Without that, your code should be fine if you build a program from both source files. main.cpp will include a declaration, so that it knows that function exists; the definition from the other source file will be included in the program by the linker.
Do not include calc.cpp . This is causing the redefinition
you can include myHeader.h in calc.cpp

LNK2005, LNK1169 errors, "int __cdecl g(void)" (?g##YAHXZ) already defined

I have 3 files in a Visual Studio project: test.cpp, date.cpp and main.cpp -
test.cpp:
int g() { return 0; }
date.cpp:
/*totally empty*/
main.cpp:
#include "test.cpp"
#include "date.cpp"
int main() { return g(); }
I understand that defining functions in a header file leads to violation of One-Definition Rule if header file is called multiple times. But here, I am calling it only once from only one file/translation unit. Why is it still throwing LNK2005?
You should not include test.cpp and date.cpp. Instead, you should write test.h and date.h, and include it:
test.h
int g();
date.h
// Contains prototypes for functions inside date.cpp
main.cpp
#include "test.h"
#include "date.h"
int main() { return g(); }
You are including "test.cpp" in "main.cpp" - this is most likely wrong, as Visual Studio will ALSO compile "test.cpp" as a separate file, and then link "test.obj" with "main.obj" (those are the files generated by the compiler) into "main.exe". When it then finds "g()" in both "test.obj" and "main.obj", it says "Huh? Why have you got two of these" (or, in linker terms "multiple defined symbols").
The solution is to have a "test.h" that declared void g(); and then use that to include into "main.cpp".
Since test.cpp is in the VS Project, it will be compiled and lined in along with main.cpp causing the multiple definitions - unless you take special measure to prevent that from happening, like removing test.cpp from the project or setting it to be "Excluded from Build".
If you rename temp.cpp to test.h you get two benefits:
VS will not automatically compile a .h when it's in a project, since it assumes that the file is intended to be included from other files instead of being stand-alone compiled.
it will be less confusing to programmers about the intended use of the files

C: Using functions from files within in the same project

My question does not link to a direct example, but is more of a question as a whole. When I was coding with C++, I found (after looking through some threads) that in order to use functions from different files that are in the same project, I would either need a header file. So, for example, if I have the main function in a file called "main.cpp" and I wanted to use a function, "prob1()" in another file called "problem1.cpp", I would need to use a header file.
What is confusing me is why I do not have to worry about this for programming in C? When I was programming in C, in order to use functions from different files, I could call the function directly.
Any help/explanation is appreciated. Thanks!
Your C compiler can implicitly declare the function, but you should be doing so yourself. If you turn up the warnings, you'll see something like:
file1.c: warning: implicit declaration of function ‘func_from_f2’
When file1.c is being compiled, this implicit declaration will be used to create an object file and then when linking you have to just hope that the function actually does exist and the declaration is correct so that the object files can be linked together successfully.
If not, the linker will give you an error somewhere along the lines of:
undefined reference to `func_from_f2'
You also don't necessarily need a header file, you can simply include the declaration/prototype of the function in your source file (the #include directive essentially does this for you). ie. the below will work fine without warnings:
file1.c
void func_from_f2(void);
int main(void)
{
func_from_f2();
return 0;
}
file2.c
#include <stdio.h>
void func_from_f2(void)
{
puts("hello");
}
However, it's usually best practice that you do use a header file:
file1.c
#include "file2.h"
int main(void)
{
func_from_f2();
return 0;
}
file2.h
#ifndef FILE2_H
#define FILE2_H
void func_from_f2(void);
#endif
file2.c
#include <stdio.h>
#include "file2.h"
void func_from_f2(void)
{
puts("hello");
}
In C, the compiler will guess the correct prototype if you haven't provided one. It very often guesses wrong, and then your program breaks.
Whether C or C++, it's always a good idea to put forward declarations in a header file that also gets #included into the implementation file, where the compiler can check for mismatch.