Swap out generally used functions in C++ - c++

Hey there,
I have a big code file currently in C++ with many functions which I often use in different versions of my program so I thought about swapping out the generally used functions: E.g. I have:
void doSomething(mxArray *in)
{
mexPrintf("Hello Matlab");
}
whereas mxArray and mexPrintf are defined in another file which comes from matlab (mex.h). In the mainfile I have now:
#include "mex.h"
#include "_general.h"
and I wonder that I didn't get any compiler errors when not including mex.h in _general.cpp also because the file itself NEEDs it obviously. Would you better do the include or doesn't it matgter in this case it is included AFTER mex.h has already been included in the mainfile?
Thanks!

C++ (unlike C) will refuse to make dubious assumptions about the signature of functions for which it hasn't seen a declaration, and compilation will fail with an error message. If you don't get an error, then some header is picking up a declaration for that function. If you can't find it, then try running only the preprocessor stage (e.g. for GCC you'd use g++ -E) and inspecting the output to see the declaration... your compiler may leave comments about which file has included bits of code which can be helpful in understanding the situation.
For example, if _general.cpp includes _general.h which includes mex.h then that's workable, and there's no need to include it directly from _general.cpp. But, if it can be removed from _general.h as it's only needed in the implementation of "general", then that's much better again.
If some other code, say "libraryX" uses mex.h for it's internal needs without exposing mex-related functionality through its public API, then it's better NOT to assume it will continue to include mex.h for you and include it yourself.

As Tamás pointed out, #include directive literally includes the header file into your source code. You can check this using the pre-processor (part of gcc)
$ cat a.cpp
#include "b.h"
int main() {
return b();
}
$ cat b.h
#ifndef _B_H
#define _B_H
int b()
{
return 0;
}
#endif
$ cpp a.cpp
# 1 "a.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.cpp"
# 1 "b.h" 1
int b()
{
return 0;
}
# 2 "a.cpp" 2
int main() {
return b();
}
$
As you can see, if you include the same file twice (which is frequently the case in any moderately complex program involving multiple source files), you run into the problem of having the same function defined twice. To solve this problem, the standard way is to use the 'include guards' (#ifndef, #define and #endif in b.h). That way, whenever you include b.h, a constant is defined. When you include b.h again, pre-processor checks this constant and decides not to include it again.
Of course, care should be taken in choosing the name of the constant :)
If you follow this rule, you can ideally include any header file anywhere. It is generally good idea to include the header file where it is absolutely necessary and without which compilation will fail. Also, a good practice is to include standard header files before custom header files.
HTH!

Related

Is there a good reason to use include guards in h files instead of cpp files?

For example, from my basic understanding of C++ and clang++, I don't understand why the following setup wouldn't be preferable:
It seems like using the variation with headers would produce more output, needs a more specific compiler setup, and needs duplicity in declaration of functions.
clang++ --std=c++2a Start.cpp -o Start.o; ./Start.o
Start.cpp
#include "A.cpp"
#include "B.cpp"
int main (
int argc,
char** argv
) {
A();
B();
return 0;
}
A.cpp
#ifndef A_H
#define A_H
#include <stdio.h>
#include "C.cpp"
void A() {
printf("A\n");
C();
}
#endif
B.cpp
#ifndef B_H
#define B_H
#include <stdio.h>
#include "C.cpp"
void B() {
printf("B\n");
C();
}
#endif
C.cpp
#ifndef C_H
#define C_H
#include <stdio.h>
void C() {
printf("C\n");
}
#endif
If you link that object file with another one that has included one of the cpp files, the program would violate One Definition Rule because those files contain definitions of non-inline functions.
Also, it is conventional to compile cpp files and link them together. If you both compile any of those cpp files, while also including it into another translation unit, you will encounter that ODR violating scenario.
To solve this problem, if you include a file into other files, then you generally should ensure that the included file (i.e. header file) doesn't contain anything that would violate ODR when included into multiple translation units.
Also, it is a best practice to conform to a commonly used naming scheme. Using cpp extension for header files is contrary to all common naming schemes.
Is there a good reason to use include guards in h files instead of cpp files?
You should always use include guard in all header files, regardless of how you name the header files. (although technically the header guards are not needed in some headers, but it is easier to simply use a header guard than keep track of whether you need it or not).
Now, if you were wondering whether you could put all your function definitions into a single translation unit: Yes, you can. This has advantages and disadvantages:
Advantage of single TU: Faster compilation time from scratch due to no repetition of compiling templates and other inline functions. Also better optimisation because there are no translation unit boundaries that would prevent optimisation - this advantage is diminished by link time optimisation which works across TU boundaries.
Disadvantage: Any change to a program only causes recompilation of the modified translation units. When there is only one translation unit that is the entire program, then any change, no matter how small, will require recompilation of the entire program. This is highly undesirable. This disadvantage is diminished by link time optimisation which can cause linking to be so slow that time saved from reused translation units can become insignificant.

Conditional compilation confusion and failure

I want to compile different files with a common *.c file. Like I want to compile A.c common.c xor B.c common.c but I can't figure out how to achieve that.
Can you please tell me how do I make common.c use different headers without using my text editor to change the headers list every time I want to compile
So let's say I have 3 files: A.c, B.c and common.c.
A.h and B.h define an enum enum {Mon, Tues, Wed...} in different ways. And that enum is used in common.c. So I can't just do in common.c:
#include "A.h"
#include "B.h"
What I thought of doing is to use preprocessor directives:
In common.h
#define A 1
#define B 2
In A.c
#define COMPILE_HEADER A
And in common.c
#if COMPILE_HEADER == A
#include A.h
#end
This doesn't work, of course, because the compiler didn't visit the A.c file to find #define COMPILE_HEADER A
So can you please tell me how do I make common.c use different headers without using my text editor to change the headers list every time I want to compile?
It's pretty complicated to explain, but I'll give it a try.
Explaination
The compiler, for example gcc, gets the input files provided, includes (literally just copy-pastes) the header files into their respective places (where the #include directive is located) in the *.c file, then compiles the file to the object (*.o) file. No executable is created. Here comes the linker, which is included in gcc. It takes the *.o files and links them into one executable.
The problem is, that the files are compiled independently, and then linked together. I mean, that predefinition like int func(int param); is like saying to compiler "Hey man, don't worry about any usage of func in the code, the linker will care". Compiler then just saves this usage as external symbol in the corresponding *.o file, and when linker is doing his job, he firstly finds the location of the symbol definition (the function implementation) and then just points to it whenever the func is called.
Try to include function definition in header file, then include it in 2 or more files from same project (compiled/linked together). Compiler will say it's ok, since the code is correct and the generated code is valid. Then, the linker will try to link it into one executable and he would have to decide which version of the same name-param function should it link to. Since most developer tools are not really good at making the right choices, he will just yell at you saying "hey man, you gave me two definitions of same function, what to do now?". This results with an error like this:
obj\Release\b.o:b.cpp:(.text+0x0): multiple definition of 'func(int)'
obj\Release\a.o:a.cpp:(.text+0xc): first defined here
What about having two main in one project?
obj\Release\b.o:b.cpp:(.text.startup+0x0): multiple definition of 'main'
obj\Release\a.o:a.cpp:(.text.startup+0x0): first defined here
Both files compile, but they cannot be linked together.
The header files are meant to contain class definitions and function predefinitions to allow you to write them only once, and then share between all files that want to use them. You can always just type class definitions for each file separately (as long as they stay same) and use them just like you would use them in .h file, same applies for function predefinitions.
There comes your problem. You have to compile only one file, not include only one. You can do this by using the preprocessor trick, but I wouldn't reccomend as solution, since it can be solved much easier (I'll tell you how in a moment).
TL;DR; (The actual answer without explaination)
You can #ifdef / #ifndef both files, then in another *.c define (or not define) some value. For example:
A.cpp
#include "t.h"
#ifdef USE_A
int func(int a)
{
return a + 5;
}
#endif
B.cpp
#include "t.h"
#ifndef USE_A
int func(int a)
{
return a * 10;
}
#endif
T.h
#ifndef T_H
#define T_H
//Or comment to use B
#define USE_A
int func(int a);
#endif // T_H
main.cpp
#include <iostream>
#include "t.h"
using namespace std;
int main()
{
cout << func(3);
}
Notice that the #ifdef/#ifndef are after the #include, so the preprocessor knows which one to compile. Also, it's not possible (at least I can't think of any way) to make the definition in any .c file, because they are compiled separately (as described above). You could use the -D switch, but that involves messing with build configurations in environments and if you want to do that it's better to try the second solution presented bellow.
Better answer
You should choose one file to compile with each version. It hardly depends on your needs, but basically instead of using g++ main.cpp a.cpp b.cpp you should compile either a.cpp or b.cpp. If you are using integrated environment like Visual Studio or Code Blocks, the configuration managers allow you to decide which file to include. I mean, those Debug/Release dropdowns can contain your own entries, which will customize your project. Then, switching between the A.cpp and B.cpp is just a question of choosing appropiate option in the always-visible bar in your environment.
If you want a more detailed tutorial on how to manage configurations on Code::Blocks or Visual Studio create appropiate question on stackoverflow and it will be answered in no time :)

Include hierarchy confusion

I have a confusion with the way #include directives work in C/C++. My first question is:
If header A includes header B first and then header C, is everything defined in header B immediately available in header C ? e.g:
/* FILE: header A */
#include "B.h"
#include "C.h" //are stuff from B.h available INSIDE C.h now?
My second question is (somewhat related to above) is this inclusion behavior different in C and C++?
Lastly, I am trying to compile freeglut with a C++ compiler and freeglut's header has the following:
#ifndef __FREEGLUT_H__
#define __FREEGLUT_H__
#include "freeglut_std.h"
#include "freeglut_ext.h"
#endif /* __FREEGLUT_H__ */
Problem is that, under compilation as C, everything is fine but switching to C++ in Visual Studio suddenly makes freeglut_ext.h to be unaware of everything defined in freeglut_std.h. Is this an issue limited to MSVC?
#include in both C and C++ is pure textual inclusion, so yes to your first question and no to your second one. I don't know freeglut so I can't tell what #ifdef __cplusplus (or other) games its headers may be playing -- not knowing what error messages you're getting to convince you that the second file is "unaware" of the first makes it unfeasible to help with your stated problem, though the answers to your stated questions are easy:-)
This is just an answer to the first part of your question.
C++ compilation happens with each .cpp file being compiled separately. Headers separately are not part of the compilation process unless you explicitly include them into a .cpp file. #include directive basically copies all the contents of the header into the .cpp in which it has been included.
So there is no question of something defined in one header being available in another header.
But in your case, if there are names defined in B.h which are referred in C.h then inclusion order has to be B.h first and then C.h

difference in including header in .cpp and .h

I have a code in which I #include<linux/videodev2.h>. There are three files:
one header file- includes: stdint.h and stdlib.h. Defines a couple of functions, a struct, say abc, and some #define macros. One of the functions is
int func(int, uint32_t, size_t, abc*);
one cpp file with a lot of methods, including definition of the functions in the .h file.
one main.cpp which has main() which has a function call to the method in the .h file (complete file below). This file is only for testing purposes.
#include "head.h"
int main() {
func(5, (uint32_t)5, (size_t)5, 0);
return 0;
}
What is see is a curious case:
If I include linux/videodev2.h only in .h file, uint32_t and other things defined in this header are not accessible by the .cpp files. (erros I get are: uint32_t was not declared in this scope, and uint32_t does not name a type, among others). This happens even if the first line of the .h file is #include<linux/videodev2.h>
If I include the videodev2 header in both the cpp files, it works only if I import it (videodev2) before the .h file.
If I use func(5, (uint32_t)5, (size_t)5, (abc*)0); in the main.cpp file, I get the error that abc is not declared in this scope.
I am compiling using the command: g++ main.cpp head.cpp
I am unable to figure out why is this. I would like to include the videodev2 header in the .h file since, it is almost certain that the code using the .h file will be dependent on it. But it seems that including it in .h file has no effect at all.
I must be honest here. This was C code which I had to convert to C++. I know that I am not conforming to the best practices and standards. But why is this behaviour seen?
Remember that the #include directive indicates to the preprocessor the contents of the specified file should be treated as if they appeared directly in the source file in place of the directive (paraphrased from MSDN).
With that in mind, it seems like you are encountering improper order of #includes and also missing #includes. My guess would be that you are not including your own header file in your .cpp files. This would explain cases one and three. Consider the following files:
// header.h
// #include <linux/videodev2.h> <-- Option 1
class A {
void func(uint32_t var);
};
// header.cpp
void A::func(uint32_t var) {
// implementation
}
// main.cpp
// #include <linux/videodev2.h> <-- Option 2
#include "header.h"
// #include <linux/videodev2.h> <-- Option 3
int main() {
// implementation; something creates an instance of A and calls func
}
Now, Option 1 is not exactly desirable; it's good practice to avoid #includes in header files because they can increase build times and create unwanted dependencies. However, it will ensure that the types header.h requires are there for it to use. The essential bit is that the contents of linux/videodev2.h have to appear before the contents of header.h, anywhere that header.h is #included.
This brings me to Option 2. Option 2 will also compile correctly, because linux/videodev2.h is included before your header, and your header relies on types defined in it. Also important is that both main.cpp and header.cpp must #include "header.h", because they reference symbols declared in it.
If you were to go with Option 3, you would get compilation errors that the type uint32_t is not defined, and the compiler would point to your header file. This is because the contents of the header file appear before the contents of linux/videodev2.h, and so the compiler does not yet understand what the type uint32_t is when it encounters it.
So, given all that, you have choices: include `linux/videodev2.h' before each include of your own header file, or include it directly in your header file. I mentioned earlier that the latter is not good practice, but for your particular case, it might be the better option of the two, in case your header file needs to be included in many .cpps.
I think this would be a good opportunity to dive into precompiled headers, but I'm not as well-versed in them, so I'd leave it to someone who has more experience to explain them.
Hope this helps :)
Found the answer. There was .h.gch file in the directory. I didn't know about precompiled header. Thanks ktodisco for the insight. I still have no idea why that file was there in the first place.

C/C++ - Conditional header file inclusion not working

I have three files in my project.
a.c
b.c
test.h
test.h declares a
namespace test_namespace {
int i;
void f1();
};
test.h is also surrounded by
#ifndef __x
#define __x
...
#endif
now, a.c includes test.h and b.c also includes test.h .
a.c has the main() function, and b.c has the implementation of test_namespace::f1()
However, on compiling this, I get a linking error -
"test_namespace::i is already defined in <b.c's object file mapping in /tmp>"
If I've taken care to include conditional compilation preprocessor directives in test.h, why is it being included in both files a.c and b.c ?
Also is noteworthy that if I compile b.c separately as a shared library and then use it as a shared library while linking a.c's object file, i don't get this error.
Can someone please explain the above error to me, specially in the face of the conditional compilation directives ?
You cannot declare variables inside a headerfile.
The symbol test_namespace::i becomes exported by both a.c and b.c. The linker find's both and doesn't know which one to use.
What you want to do in test.h is:
namespace test_namespace {
extern int i;
void f1();
}
and then declare test_namespace::i in eather a.c or b.c:
namespace test_namespace {
int i;
}
Conditional inclusion is used to prevent headers from being included twice for the same source file not for the whole project. Suppose you have headersa.h and b.h, and b.h #includes a.h. Then if c.c needs things from both headers, it #include both of them. Since the C preprocessor using literal text substitution, when it includes b.h, there will now be two #include "a.h" directives in your file, wreaking the havoc of multiple declarations. (Edit: clarify why you run into problems in this case.)
Include guards are there to protect multiple header inclusions in the build of a compilation unit. They aren't necessary for cases when you have two separate code files and one header, like your example.
(So think more when test.c uses a.h and b.h, in those cases where b.h needs to #include a.h.)
But that's a note about what the include guard convention does and how it isn't buying you anything in this case. The specific technical issue you hit (as others have pointed out) is that you're basically defining the same variable in two different object files, and when the linker goes to pull everything together it doesn't know if you want the variable from a.o or b.o.
( Note: While compilers can generally be set to override things and build C++ code using features like namespace even if the extension is .c - you probably should be using something else, like .cpp: C++ code file extension? .cc vs .cpp )
You're defining test_namespace::i in the header. What you probably
want is extern int i; in the header, and a definition in one of the
source files.
What's happening is that when you say
int i;
this actually does two things:
1) Declares the symbol i
2) Reserves some space and a symbol for i in the object file
The trick is that (1) should only be done once per file (actually you can repeat it in this case) -- which is why you have the conditional include, which you have done correctly -- but (2) should only be done once per program
The solution is to have the header do
// Only declare -- don't create a symbol
extern int i;
And in the *.c file do
int i;
The header guards (#ifndef .. #define .. #endif) are working as they should. Both a.c and b.c include test.h, so they both get a copy of that header. (When you compile a program, what #include does is to literally copy-paste the contents of the header inside the source file.)
Since they both have a copy of the header, they both define the variable test_namespace::i. When the linker tries to link the code generated from a.c with the code generated from b.c it finds that they both define that variable. It doesn't know what to do, so it doesn't complete and outputs an error.