0

I have the following code:

#ifndef VECTOR_H
#define VECTOR_H

#include <SFML/Graphics.hpp>
#include <cmath>

template<typename T>
inline constexpr T &&dot(const sf::Vector2<T> &v1, const sf::Vector2<T> &v2)
{
    return v1.x * v2.x + v1.y * v2.y;
}

template<typename T>
inline constexpr T &&abs(const sf::Vector2<T> &v)
{
    return sqrt(dot(v, v));
}

template<typename T>
inline constexpr sf::Vector2<T> &&norm(const sf::Vector2<T> &v)
{
    return v/abs(v);
}


#endif // VECTOR_H

calling norm(sf::Vector2<float>{1, 0}) produces a Segmentation fault, on the line return sqrt(dot(v, v)); I'm unsure what is causing this, however I have verified its related to the passing/returning of the values in the functions

as the following runs with out error:

#ifndef VECTOR_H
#define VECTOR_H

#include <SFML/Graphics.hpp>
#include <cmath>

template<typename T>
inline constexpr T dot(const sf::Vector2<T> v1, const sf::Vector2<T> v2)
{
    return v1.x * v2.x + v1.y * v2.y;
}

template<typename T>
inline constexpr T abs(const sf::Vector2<T> v)
{
    return sqrt(dot(v, v));
}

template<typename T>
inline constexpr sf::Vector2<T> norm(const sf::Vector2<T> v)
{
    return v/abs(v);
}


#endif // VECTOR_H

Clearly I'm missing some rule about the new syntax, however I'm not sure what it is.

Henri Menke
  • 10,705
  • 1
  • 24
  • 42
Glen Fletcher
  • 644
  • 5
  • 21
  • 2
    returning an rvalue reference ≠ move return value – Henri Menke Dec 27 '17 at 04:31
  • I'm generally using these function for inline math, and to set variables, my understanding is the move return is more efficient in this case, is there a way I can maintain this efficient and avoid the segmentation fault problem? – Glen Fletcher Dec 27 '17 at 04:34
  • Or do you mean because I'm not using local variables that I shouldn't be using the move return value?? i.e. I should only use it to return a local variable? – Glen Fletcher Dec 27 '17 at 04:35
  • 1
    Move will be done by the compiler if the return type has a move constructor. You are trying to return a reference to a temporary. This is just invalid (no matter whether it's rvalue or lvalue reference). – Henri Menke Dec 27 '17 at 04:36
  • 1
    Possible duplicate of [return by rvalue reference](https://stackoverflow.com/questions/13430831/return-by-rvalue-reference) – Henri Menke Dec 27 '17 at 04:37
  • 2
    You compiler should have actually warned you about this. Using Clang on a similar piece of code I immediately get `warning: returning reference to local temporary object` (even without any warnings enabled) or [see it live on Wandbox](https://wandbox.org/permlink/iKracAMeZs3GTAyZ). – Henri Menke Dec 27 '17 at 04:43
  • @glenflet As others mentioned, you should not return a reference to a temporary. However you should accept by const reference if you are not modifying the argument. So you should add `&` to the argument of all the functions: `inline constexpr T abs(const sf::Vector2& v)` – balki Dec 27 '17 at 20:04

0 Answers0