Jump to content
  • Advertisement
Sign in to follow this  
noatom

How is this a pass by value?!

This topic is 1570 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

// maximum of two C-strings (call-by-value) 
inline char const* max (char const* a, char const* b) 
{ 
    return std::strcmp(a,b) < 0 ? b : a; 
} 

// maximum of three values of any type (call-by-reference) 
template <typename T> 
inline T const& max (T const& a, T const& b, T const& c) 
{ 
    return max (max(a,b), c); // error, because max(a,b) uses call-by-value 
} 

int main () 
{ 
    

    const char* s1 = "frederic"; 
    const char* s2 = "anica"; 
    const char* s3 = "lucas"; 
    ::max(s1, s2, s3); // ERROR 

} 

So when the 3 parameter function is called, it takes a constant reference to the listed pointers. So basically inside the function, a would be a constant reference to a constant pointer.

 

Then the 2 parameter max function is called, which takes a constant char pointer(WHY IS IT THEN CONSIDERED BY VALUE, when clearly we see it takes pointers, and not values!)

 

Its kinda late here, maybe I'm interpreting this in a very stupid way, can someone clear it up for me?

Edited by noatom

Share this post


Link to post
Share on other sites
Advertisement

Your code generates no errors for me, only a warning about returning a reference to a local variable. What exactly is the purpose of this code and why have you written it this way with templates and references?

Edited by Chris_F

Share this post


Link to post
Share on other sites

The following works for me:

 

#include <iostream>
#include <algorithm>
#include <cstring>

template<class T>
constexpr const T& max(const T& a, const T& b, const T& c)
{
    return std::max(std::max(a, b), c);
}

inline const char* max(const char* a, const char* b)
{
    return std::strcmp(a,b) < 0 ? b : a;
}

int main ()
{
    const char* s1 = "frederic";
    const char* s2 = "anica";
    const char* s3 = "lucas";
    std::cout << max(s1, s2, s3);
}

Share this post


Link to post
Share on other sites

Its from a template book, more exactly: Adison Wesley's C++ Templates The Complete Guide.

 

In the chapter he's showing template functions and overloading, and he gave this example. He was trying to show how writing too many overloads can cause a headache and make mistakes in code, aka returning a reference to a local.

 

But the problem is, he says in the commented code that the two arg function is a call by value, which is not! I'll give you the full code.

// maximum of two values of any type (call-by-reference) 
template <typename T> 
inline T const& max (T const& a, T const& b) 
{ 
    return a < b ? b : a; 
} 

// maximum of two C-strings (call-by-value) 
inline char const* max (char const* a, char const* b) 
{ 
    return std::strcmp(a,b) < 0 ? b : a; 
} 

// maximum of three values of any type (call-by-reference) 
template <typename T> 
inline T const& max (T const& a, T const& b, T const& c) 
{ 
    return max (max(a,b), c); // error, if max(a,b) uses call-by-value 
} 

int main () 
{ 
    ::max(7, 42, 68); // OK 

    const char* s1 = "frederic"; 
    const char* s2 = "anica"; 
    const char* s3 = "lucas"; 
    ::max(s1, s2, s3); // ERROR 

} 

But I just noticed another thing: Why wouldn't the 3 parameter function call the first function, which takes its parameters by reference?! the 3 parameter function itself has its parameters by reference, so it would only make sense to call the first function, and not the second.

 

 

 

I know the code works, the problem is I can't get the: "error, if max(a,b) uses call-by-value" how would it be called by value when we can clearly see it takes pointers and not values?!

Edited by noatom

Share this post


Link to post
Share on other sites

I know the code works, the problem is I can't get the: "error, if max(a,b) uses call-by-value" how would it be called by value when we can clearly see it takes pointers and not values?!

You are confused about what is actually passed to the function. In your max-function that is overloaded for char const *, the pointers a and b are not references to the pointers you pass to it, but value-copied of the original pointers. If you are confused about pointers and pass-by-value, it is easier to hide the pointer behind a typedef.

typedef char const *cstring;

cstring max (cstring a, cstring b)
{ ... }

Now compare with passing int, or float, or double, or char, and you'll see that the cstring object, which is a char const *, is actually passed by value.

Share this post


Link to post
Share on other sites
In your max-function that is overloaded for char const *, the pointers a and b are not references to the pointers you pass to it

I never said they are references, I was trying to say that I'm basically passing a pointer to a function which requires pointers, so why would there be values involved at all?!

Wasn't pointer assignment supposed to only copy the address?

Edited by noatom

Share this post


Link to post
Share on other sites

The pointers are passed by value to the function, and returned by value from the function. That's the problem here; the pointer that is returned from the max function is then returned from a function that returns a reference to the pointer. Since the return value is local to the function, the reference is thus a reference to a local value.

 

As I said, replace your char const * types with my cstring typedef and see where the values and references to local values comes into the picture. Pointers are not treated differently that any other int, float or double value.

Share this post


Link to post
Share on other sites

But how do you pass a pointer by value, since a pointer's value is an address?! If a and b are pointers, and b points to something, doing a = b, doesn't create another object, is just makes a point to the very same object that b points to.

Edited by noatom

Share this post


Link to post
Share on other sites

Step away from your nested max functions a bit and examine this program.

void set(char const *value)
{
    value = "bar";
}

void set(int value)
{
    value = 42;
}

int main ()
{
    int ivalue = 0;
    char const *svalue = "foo";

    set(ivalue);
    set(svalue);

    std::cout << ivalue << " " << svalue << std::endl;
}

Now answer these two questions, and understand why the answer is what it is.

  1. Is the value of ivalue 0 or 42?
  2. Does the pointer svalue point to the string "foo" or "bar"?

This is what is the core of the problem with your max functions.

Edited by Brother Bob

Share this post


Link to post
Share on other sites


But how do you pass a pointer by value, since a pointer's value is an address?
Copy the value of that address. The value of the pointer (an address as you said) is stored somewhere, when you call that function, its value gets copied and handed over to the function. The function uses that value to see where the pointer pointed to. Passing the pointer by its value.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!