Issue
I have a header which defines some functions I need. I include them in two files which are themselves included in main.cpp, but I get the multiple definitions of function error, despite the fact that I put
#ifndef MYFUNCTION_H
#define MYFUNCTION_H
//code
#endif
in my code. So what did I do wrong? Here is my header:
#ifndef EXTRASFMLFUNCTIONS_H
#define EXTRASFMLFUNCTIONS_H
#include <SFML/System/Vector2.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/Text.hpp>
inline void setCenterPos(sf::Sprite &entity, const sf::Vector2f& position)
{
entity.setPosition(sf::Vector2f{(position.x - entity.getGlobalBounds().width / 2), position.y - (entity.getGlobalBounds().height / 2)});
}
inline void setCenterPos(sf::Text &entity, const sf::Vector2f& position)
{
entity.setPosition(sf::Vector2f{(position.x - entity.getGlobalBounds().width / 2), position.y - (entity.getGlobalBounds().height / 2)});
}
inline sf::Vector2f getCenter(const sf::Sprite& entity)
{
return sf::Vector2f{entity.getGlobalBounds().width / 2, entity.getGlobalBounds().height / 2} + entity.getPosition();
}
inline void scaleTo(sf::Sprite& entity, const sf::Vector2f& size)
{
entity.scale(size.x / entity.getGlobalBounds().width, size.y / entity.getGlobalBounds().height);
return;
}
inline void scaleToWidth(sf::Sprite& entity, const float &width)
{
entity.scale(width / entity.getGlobalBounds().width, width / entity.getGlobalBounds().width);
return;
}
inline void scaleToHeight(sf::Sprite& entity, const float &height)
{
entity.scale(height / entity.getGlobalBounds().height, height / entity.getGlobalBounds().height);
return;
}
#endif
Edit: it works with the inline keyword
Solution
In C++, the One Definition Rule (ODR) states that objects and non-inline functions cannot have more than one definition in the entire program and template and types cannot have more than one definition by translation unit. As cppreference states under One Definition Rule:
One and only one definition of every non-inline function or variable that is odr-used (see below) is required to appear in the entire program (including any standard and user-defined libraries). The compiler is not required to diagnose this violation, but the behavior of the program that violates it is undefined.
That's why you get multiple definition link errors when you do not inline the functions. The functions are included (literally copied) into the implementation files. The header guards do not prevent this since the files are included separately. So you violate ODR because the same function with external linkage is defined multiple times.
When you inline the functions, then each translation unit (implementation file + all its include files) gets its own copy of the function. This will not be considered a violation of the ODR because of the inline
keyword when the linker links the object files. That's what's special about inline
: it tells the linker that multiple definitions of the same function are not an error.
You have two options:
- inline the functions like you have done;
- put the function declarations in a header file and put the definitions in one cpp file
I would go with the first option since the functions are short and not so complicated.
Answered By - jignatius Answer Checked By - Candace Johnson (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.