ld returned 1 exit status when moving function from one .cpp to another

Hello !
I am working on a project and I try to organize it in a different way.
I mean, before, I put everything into classes and then it was okay, I understood it. But it seems it's not a good way to do it, so I'm trying to avoid classes when I don't need them (sometimes I created a player class to implement only one player, without inheritance, just useless encapsulation).

So I tried to write functions and variables into a namespace, to avoid global variables. But I ended up with a main.cpp file with 400+ lines and a main.h which stores everything. So I decided to break this code into multiple files which describes what the functions are supposed to do.

At first, I tried to create "Initialization.h" and "Initialization.cpp" files, moving all functions that I call to initialize the program into it. But it failed, with ld returned 1 exit status.

I then thought it was a problem in my .h, so I chose to let the declarations into the main.h file, and create a "Initialization.cpp" file with all the functions implemented. Of course, I include "main.h" firs,t but then the problem occurs again. ld returned 1 exit status.

I know it's a problem with linking, I had it before and solved it (I don't remember how, it was a while ago)... and now I have no clue about why it is happening.
I think there is no need to post code, but if you think I should, then I'll gladly post it. I just don't want to create a 500+ lines post :D (I'm joking).

Thanks for help !
If you don't even say the errors you're getting then there's no way to help.

But that aside, it sounds like you switched from a nice, compartmentalized design to some horrid procedural abomination for no good reason. Why is it "not a good way to do it" to organize related code and data into classes? Just because a class is instantiated only once, it doesn't follow that that class is unnecessary.
The only error I get is "ld returned 1 exit status", there's no compilation error, only this linking error.

I've read on StackOverflow that it was a bad design to put everything into classes, so I try to use them a little bit less.
And in what creating functions and variables outside classes inside namespaces is a "horrid procedural abomination" ? There are more designs than the "all in classes" design... I guess.
There's usually another accompanying message, For example this code:
1
2
3
4
5
6
void fred();

int main()
{
    fred();
}

Gives the following messages:

/tmp/ccUOXOZX.o: In function `main':
 :(.text.startup+0x5): undefined reference to `fred()'
 collect2: error: ld returned 1 exit status


Here, the messages state that something went wrong within function main() when trying to call function fred().
What are you using to build? An IDE, a command line compiler?

And in what creating functions and variables outside classes inside namespaces is a "horrid procedural abomination" ?
If you're going to be doing exactly the same you would have done with classes but with namespaces, then the design is objectively worse. E.g.:
1
2
3
4
5
6
7
8
9
class PlayerCharacter{
    int x, y;
    bool alive;
public:
    void Move(int x, int y){
        this->x = x;
        this->y = y;
    }
};
turning into
1
2
3
4
5
6
7
8
9
namespace PlayerCharacter{
    int x, y;
    bool alive;

    void Move(int x_param, int y_param){
        x = x_param;
        y = y_param;
    }
}
The namespace version is objectively worse, because it's much less flexible. For example, a PlayerCharacter class could be instantiated several times (for whatever reason), it could be created on the stack or in dynamic memory, it could be put in a container, etc. The variables in the PlayerCharacter namespace can exist only in one place.

A procedural design can work, but this is not the way to do it.
Last edited on
So I tried to write functions and variables into a namespace, to avoid global variables.
That doesn't make sense. Variables in a namespace is actually a global variable. You have linker problem if you include a global variable more than once.

encapsulation is usually a good thing. But sometimes it makes sense to extend the functionality with a free function. A class makes sense if you have at least one variable where you want to apply one or more functions.

sometimes I created a player class to implement only one player, without inheritance, just useless encapsulation
The number of instances of a class has nothing to do with the class itself.

I have no clue about why it is happening.
This is the best sign for bad design.
> But it seems it's not a good way to do it, so I'm trying to avoid classes when I don't need them
> (sometimes I created a player class to implement only one player, without inheritance, just
> useless encapsulation).

This is fundamentally a sound idea; avoid classes if you don't need them. If your game will have only one player, and that player exists for the duration of the game, it should be a namespace, not a class. It is not an accident that std::this_thread is a namespace, not a class.

And by the way, strong encapsulation (insulation) is a lot simpler when namespaces are used instead of classes.

See Chervil's post above; there would be diagnostic information about why ld returned 1 exit status. Once you recognise what the problem is, the fix is usually trivial.
Okay, are you trolling? You can't be serious.

If your game will have only one player, and that player exists for the duration of the game, it should be a namespace, not a class.
Let's suppose that this is true, and you never actually need to support more than a single instance of a Player.
What if at one point it becomes desirable for Player to share state or code with other namespaces? Or if you want to support different subtypes of a Player? Are you going to implement inheritance on top of a namespace? That's going to be fun.

It is not an accident that std::this_thread is a namespace, not a class.
std::this_thread doesn't contain any state, so it's not really comparable. There is also only one stdout per process, and yet std::cout is an object, not a namespace.
> std::this_thread doesn't contain any state

It does; every thread has a unique id. look up std::thread::id std::this_thread::get_id();


> There is also only one stdout per process, and yet std::cout is an object, not a namespace.

There are two different objects (initially) associated with stdout; one is std::cout and the other is std::wcout. There could be many more, as the program starts running.
every thread has a unique id
std::this_thread::get_id() is not state, it's context information. Also, it's information that's not contained in the std::this_thread namespace. The implementation of std::this_thread::get_id() just queries the OS for the value.

There are two different objects (initially) associated with stdout
The point stands. There's two different objects not two different namespaces, or even two different sets of functions in the same namespace.
> The implementation of std::this_thread::get_id() just queries the OS for the value.

No.

The implementation of std::thread::native_handle_type std::thread::native_handle() typically queries the OS for the value.

Both are state; std::thread::id is typically intrinsic state,
while std::thread::native_handle_type is typically extrinsic state.


> The point stands. There's two different objects not two different namespaces,

The point does not stand; it is absurd to the point of being asinine.

Repeat: If your game will have only one player, it should be a namespace, not a class.
Both are state; std::thread::id is typically intrinsic state,
So can you write to it?

The implementation of std::thread::native_handle_type std::thread::native_handle() typically queries the OS for the value.
That's an implementation detail. My implementation queries the system directly. What I'm getting at is that it's not a variable that's held by std::this_thread.

Reiteration does not constitute an argument. I did give an argument, which you have yet to respond to:
Let's suppose that this is true, and you never actually need to support more than a single instance of a Player.
What if at one point it becomes desirable for Player to share state or code with other namespaces? Or if you want to support different subtypes of a Player? Are you going to implement inheritance on top of a namespace? That's going to be fun.
Are you going to respond to that, or have you said everything you had to say?
> So can you write to it?

Just as there can be intrinsic state, extrinsic state, shared state, computed state,
there can also be mutable state and immutable state.

1
2
3
4
5
6
7
8
struct person 
{
    // ...
    const std::string name ; // intrinsic, immutable state.
    int age_in_years() const ; // computed, immutable state
    private:const  std::tm time_of_birth ;
   // ...
};


If your notion of state is limited to 'something that can be written into', you have a very long way to travel.


> What if at one point it becomes desirable for Player to share state or code with other namespaces?

You need to read up on namespace composition; and while you are at it you might as well also learn about namespace selection, intelligently combining composition with selection, and namespace versioning.

Recommended: Chapter 14 of Stroustrup's 'The C++ Programming Language (Fourth Edition)'
It is only about thirty pages or so, and well worth careful study.


> Or if you want to support different subtypes of a Player?

Right.
And what if you want to implement many different kinds of sorts (which to you would necessarily have to be different subtypes of std::sort)? And the only way that you can think of doing it by trying to implement inheritance on top of the namespace std?

If you need a hierarchical arrangement of different player types, if you need a type player which has overloaded operators, if you can't live without taking the memory address of the player ... and so on and so forth ...

In short, if you need an instance of an object of the type player, a class is required.
So, your (extremely valid, I may add) proposition is: if a class is required, then a class is required.
What else is new?
I've said it before, but cut out the condescension, matey. You're not impressing anyone.

[immutable state]
Alright, fair enough. The value returned by std::this_thread::get_id() is still not state contained by std::this_thread, though.

If you need a hierarchical arrangement of different player types, if you need a type player which has overloaded operators, if you can't live without taking the memory address of the player ... and so on and so forth ...
There's no need to make it sound contrived. Something as basic as dynamic dispatch would be a chore, not to mention error-prone.
1
2
3
4
5
6
7
8
9
10
11
12
13
namespace Mammal{
    void speak(){
        switch (type){
            case Type::Dog:
                Dog::speak();
                return;
            case Type::Cat:
                Cat::speak();
                return;
            //etc.
        }
    }
}


So, your (extremely valid, I may add) proposition is: if a class is required, then a class is required.
No, what I'm saying is that
1. You may not know ahead of time that a class will never be required.
2. If a class is eventually required, the refactor may not be trivial, if at all possible.
3. Using a namespace over a class offers no advantages.
Well, okay, I did not mean to receive that amount of answers :o but thanks for the debate though, it's quite interesting.

There's usually another accompanying message
Yeah, I know. I hope there was one, but there is nothing though.
Here's a screenshot, but I don't think I'm missing anything important. Maybe am I in the wrong tab ? http://hpics.li/e800f1b

What are you using to build? An IDE, a command line compiler?
Code::Blocks, and I'm under Linux.

Variables in a namespace is actually a global variable.
Oh, I did not know that. Thanks for the information, I guess I have to rethink of how to organize my code then.

But sometimes it makes sense to extend the functionality with a free function.
Okay, that's what I don't understand. When does it make sense to extend the functionality with such a thing, and what advantages does it offer that a member function would not offer ?

The number of instances of a class has nothing to do with the class itself.
Okay, I just thought that a class was meant to be reused a few times in the code. That proves how newbie I am.

This is the best sign for bad design.
Ok, ok, I get it. I guess I'm going to rewrite the entire thing, after all, classes were more understandable.

Thank you for all your answers !
Last edited on
That link doesn't work for me.
The image basically shows Code-blocks IDE, Build messages tab, with the following text:
=== Build: Debug in Map Editor (compiler: GNU GCC Compiler) ===
error: ld retuned 1 exit status
=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===
Last edited on
> Code-blocks IDE, Build messages tab

The Build Log tab may contain additional information.

Ideally, turn on full compiler logging.
menu -> Settings -> Compiler -> Global compiler settings -> Other Settings -> Compiler logging
Choose 'Full Command Line'
It's okay, I'll find another way to organize my code and there'll be probably no more problem.
It's unsatisfactory to reorganise things and hope that the problem goes away. You might after all post your full code, or post the code elsewhere and link to it (e.g. pastebin etc.).
Topic archived. No new replies allowed.