Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Running code in a different folder without redefinition errors.

21 views
Skip to first unread message

Paul

unread,
Dec 23, 2018, 1:05:14 PM12/23/18
to
I have code in one folder which looks like this.
// TestLinker.h file
#ifndef HEADER_GUARD
#define HEADER_GUARD
void f();
#endif

// TestLinker.cpp file
#include<iostream>
#include "TestLinker.h"
void f()
{
std::cout << "as expected";
}

// main.cpp file
#include <iostream>
#include "TestLinker.h"

int main()
{
f();
std::cout << "fine";
return 0;
}

So far, everything works perfectly in line with my expectations.

My aim is to have one folder structure for implementing my code
and another folder structure for testing.

Assuming f() is a highly complex function which genuinely needs testing, I want
to create a framework for testing the implementation of f() without simply
copy-pasting the code. I want to decouple the implementation process from
the testing process.

My problems occur when I try to call f() from a different folder and different
project without simply copy-pasting.

In a different project and different folder I have

//main.cpp
#include <iostream>
#include "../../WIPCode/LinkerIssues/TestLinker.h" // Same TestLinker.h as above
int main()
{
f();
return 0;
}

This compiles but doesn't link because f(); gives an undefined reference error.
This error is not at all surprising because the definition of f() is in the
cpp file not the .h file. I could simply put the definition of f() in the
.h file but I am practising for the case where f() is complex enough that
it should be in a cpp file rather than a header.

One way, which does indeed give the desired result, is to include the cpp instead
of the .h file but that is considered bad practice.

I am looking for a way to test f() in a different folder which is good
practice (and therefore avoids an #include "TestLinker.cpp").

Any suggestions? This forum has always been fantastic in response to my queries.

Many thanks,

Paul

Melzzzzz

unread,
Dec 23, 2018, 1:18:43 PM12/23/18
to
That depends on your build environment. You usually make library place
it somewhere and link it. How that is done completely depends on build
system...


--
press any key to continue or any other to quit...

Manfred

unread,
Dec 23, 2018, 2:56:33 PM12/23/18
to
IDEs can provide tools for this, but in the end it resolves to proper
usage of the compiler and linker.
For example, you can instruct the compiler to look for header files in
some folder (-I/some/folder) so that you don't need to specify the full
path in the #include statement.
Similarly, you can instruct the compiler where to put the object files,
and instruct the linker where to pick them, and where to generate the
executable.

Paavo Helde

unread,
Dec 24, 2018, 3:46:33 PM12/24/18
to
On 23.12.2018 20:05, Paul wrote:

> In a different project and different folder I have
>
> //main.cpp
> #include <iostream>
> #include "../../WIPCode/LinkerIssues/TestLinker.h" // Same TestLinker.h as above
> int main()
> {
> f();
> return 0;
> }
>
> This compiles but doesn't link because f(); gives an undefined reference error.
> This error is not at all surprising because the definition of f() is in the
> cpp file not the .h file.

The simplest solution is to include the missing .cpp file(s) into your
test project. All C++ build systems can include source files from
different folders.

Another question is if that is the best way. A "cleaner" way might be to
compile the common source files into a library and include the library
both in the main program and in the test program, as suggested by
others. But this might be an overkill if there is no other reason to
have a separate library.

Melzzzzz

unread,
Dec 24, 2018, 4:07:01 PM12/24/18
to
He can produce just object file then and link with that...
We don't know what he uses IDE, or command line...

ViralTaco

unread,
Dec 26, 2018, 3:19:19 PM12/26/18
to
Alright the problem here is that `f()` might be undefined.
Here is how I would do it:
```(header.hpp)

#pragma once

namespace { // Global namespace in this case.
void f();
}
```
```(header.cpp)
#pragma once
#include "header.hpp"
#include <iostream>

void f() {
std::cout << "fine";
}
```
```(main.cpp)
#include "header.cpp"

int main() {
f();
} // This returns 0
```


Alternatively just one header:
```(header.hpp)
#pragma once
#include <iostream>

namespace { // Global namespace
void f() {
std::cout << "fine";
}
}
```
```(main.cpp)
#include "header.hpp"

int main {
f();
}
```

Hope that helps.
0 new messages