PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, June 26, 2022

[FIXED] How to properly create a header for functions, without multiple definitions error?

 June 26, 2022     c++, compiler-errors, definition, function     No comments   

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)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing