🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Size doesn't really matters...right?

Started by
54 comments, last by JoeJ 6 years, 9 months ago
9 hours ago, MarcusAseth said:

This seems wrong to me (unless your return type is a reference), the returned type from a function cannot be assigned to because it not a modifiable lvalue, regardless wether it has const or not.

That example still won't compile when trying to assign without const in the return type

Give it a try in http://cpp.sh/:


struct Vector2 {
    
  Vector2(float x, float y)
        : m_x(x), m_y(y) {}
    
    float m_x, m_y;
};

Vector2 operator*(const Vector2 &v1, const Vector2 &v2) noexcept {
    return Vector2(v1.m_x + v2.m_x, v1.m_y + v2.m_y);
}
    
int main() {
  const Vector2 a(1.0f, 2.0f);
  const Vector2 b(3.0f, 4.0f);
  const Vector2 c(5.0f, 6.0f);
  (a*b) = c;
}

and here you have a snippet which has an if test that will pass:


#include <iostream>

struct Vector2 {
    Vector2(float x, float y)
        : m_x(x), m_y(y) {}
    
    operator bool() const noexcept { 
        return m_x != 0.0f && m_y != 0.0f; 
    } 
    
    float m_x, m_y;
};
Vector2 operator*(const Vector2 &v1, const Vector2 &v2) noexcept {
    return Vector2(v1.m_x + v2.m_x, v1.m_y + v2.m_y);
}
    

int main()
{
  const Vector2 a(1.0f, 2.0f);
  const Vector2 b(3.0f, 4.0f);
  const Vector2 c(5.0f, 6.0f);
  if ((a*b) = c) {
      std::cout << "Hello!";
  }
}

And for std::string:


#include <iostream>
#include <string>

std::string f() {
   return std::string("b");
}

int main() {
  const std::string a = "a";
  f() = a;
}

std::string does not provide implicit casting to bools

🧙

Advertisement
8 hours ago, MarcusAseth said:

the returned type from a function cannot be assigned to because it not a modifiable lvalue

Type != Value.

The returned value is a mutable rvalue. You'll pass it as a reference to the mutable rvalue  to the function (who sees that parameter as an lvalue).

🧙

What about this example? 


int f(int& n)
{
	n += 99;
	return n;
}

int main() {
	int a = 5;
	int b = 4;
	
	f(a) = b; //Won't Compile
}

Aren't you cherry picking examples?! :D

1 hour ago, MarcusAseth said:

Aren't you cherry picking examples?! :D

I quote myself:

So as a rule of thumb, always use const for returning by value of non-primitive, non-enum types. The latter are immutable by definition, so adding a const results in no added value.

The connection between the latter sentences is not clear. "The latter" refers to primitive and enum types as opposed to non-primitive, non-enum types (the opposite).

 

But in another quote of myself :D :

That is basically the only example I found so far (and returned pointers, references, primitives and enum values which are all in fact primitives).

With regard to the primitives: int, long, float, etc. Does are all immutable. You cannot do things like 5 = b; or f(a) = 5; in your example above. 

 

🧙

Ah, my bad :P

Why primitive types behaves in a different way though?! o_O

3 minutes ago, MarcusAseth said:

Why primitive types behaves in a different way though?! o_O

They are immutable. I can't think of a programming language where this is not the case. 

You cannot do things like 5 = b; or f(a) = 5; in your example above. If this was possible what would the result be? Changing the value of 5? If you really want to do this, you could use a macro, but that only guarantees one change at compile-time. You cannot perform such changes at run-time.

🧙

1 minute ago, matt77hias said:

They are immutable. I can't think of a programming language where this is not the case. You cannot do things like 5 = b; or f(a) = 5; in your example above. 

I still don't understand why though, is not the same as 5= b, since in my example is a named variable with an address...

7 minutes ago, MarcusAseth said:

since in my example is a named variable with an address...

No it is a value without an address (rvalue). It will be very similar to 5 = b with another value.

Will not be assignable:

int f(int& n)
{
    n += 99;
    return n;
}

Will be assignable:

int &f(int& n)
{
    n += 99;
    return n;
}

 

🧙

I still don't get it. How can the address refer to a local variable if the variable enter the function by reference and lives outside of the function? =_=
I mean, I still don't see the difference with the string example or the vector example.

2 minutes ago, MarcusAseth said:

I still don't get it. How can the address refer to a local variable if the variable enter the function by reference and lives outside of the function? =_=

I was too fast. You indeed return your input argument by reference. So it still lives and is assignable:

int &f(int& n)
{
    n += 99;
    return n;
}

This on the other hand return a copy of n which is not assignable:

int f(int& n)
{
    n += 99;
    return n; // copies the value referred to by n
}

 

🧙

This topic is closed to new replies.

Advertisement