CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 28 of 28

Thread: passing smart pointer

  1. #16
    Join Date
    Oct 2008
    Posts
    1,456

    Re: passing smart pointer

    speaking of sterile back and forth arguments ...

    Quote Originally Posted by razzle View Post
    This terminology is upheld both by Stroustrup in The C++ Programming Language and by the C++ standard
    nowhere in the standard the expression "pass by reference" is used, probably because it's a rather useless and ambiguous terminology on its own; actually, the expression "reference semantics" is (rarely) used meaning exactly what predicatenormative meant, that is the contract of a type ( be it a reference, pointer, proxy, ... ) of "referencing" some other object.

    Indeed, nothing would have prevented the language designers to define a special pointer modeling a "T*const" with the same stronger aliasing guarantees of references and, conversely, nothing prevents the definition of more "object-like" references ( indeed, the standard does define a copy-assignable reference wrapper exactly to implement reference semantics for some STL algos ). Basing an "established terminology" on a syntactical accident does not make much sense to me.

    Strictly speaking, for every function "f(T y){...}" the expression "f(x)" is equivalent to "{T y = x; ...}" wrt parameter initialization, that is there's only one "parameter passing mechanism" in c++, namely so called copy-initialization of the parameters, whatever their types are. The semantics of the parameter is more important IMO and it's conveyed by the type ( or by the context if the type is not sufficiently well-purposed, as monarch_dodra said ).

    Quote Originally Posted by razzle View Post
    The purpose of the established terminology is to make a distinction strictly limited to the actual parameter passing.
    either you're wrong and the meaning is more semantical than syntactical ( this is how I've always read it BTW ) or you're right and that terminology has poor conceptual and practical utlity. I don't know ...
    Last edited by superbonzo; August 21st, 2014 at 02:57 AM.

  2. #17
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: passing smart pointer

    Quote Originally Posted by razzle View Post
    We're dealing with an established terminology used for parameter passing to functions. The basic distinction is between pass by value and pass by reference. Only those. There's is no by pointer, no by array, no by address, no by air or what have you. This terminology is upheld both by Stroustrup in The C++ Programming Language and by the C++ standard, and that's a pretty strong reason not to insist on conflicting usage.

    The purpose of the established terminology is to make a distinction strictly limited to the actual parameter passing. The focus is on the parameter itself and not on what it represents in a wider context. So if the parameter is a pointer (or smart pointer for that matter) you're not passing what it points to, you're passing the pointer and you can do that either by value or by reference as you can any parameter.

    As you noted, arguing takes time and I think I've said what I wanted on this topic now so I drop it here.
    Agreed, however, outside of the context of Stroustrup and the C++ standard (neither of which by the way give any formal definition of the term reference semantics, though both do make statements that would exclude pointers from being compliant), the definition of the terms "reference semantics" and "by reference" do not seem to be established as such, at least not with any consistency.

    I cannot find any official formal definition of the term "reference semantics" - that's not to say there isn't one, but if there is, then it would seem the computer science community in general doesn't know where to find it. Any pages that I have found have not made any reference to such a formal definition of the "established terminology" and opinions to what the terminology (the distinction between pass by value and pass by reference) means clearly differ. Every page I look at, the definition of the term "reference semantics" is either merely assumed, or the opinion of some random person, lecturer, academic or institution . Because there are varying views as to what "reference semantics" means, there are varying views of what "by reference" means. There is no set in stone official definition (by an official body of any note) of "reference semantics" that I can find. I've searched university lecture notes in computing science, academic papers, articles from both academia and industry (e.g. IBM). None make any reference to an established definition of the term "reference semantics", they all seem to have their own definition. Hence some take it that reference semantics means "pointer semantics" and others "strict alias semantics". The "pointer semantics" camp often allow the term "by pointer" to be a subset of "by reference" and thus many pieces of training material for "reference semantics" use "pointers" as valid examples of "reference semantics".

    That all said, within the context of C++, the term "by reference" means strict alias semantics. Although Stroustrup doesn't directly state the meaning of "reference semantics", he infers it when he states:
    Consider:
    Code:
    void f(int val, int& ref)
    {
      val++;
      ref++;
    }
    When f() is called, val++ increments a local copy of the first actual argument, whereas ref++ increments the second actual argument. For example,
    Code:
    void g()
    {
      int i = 1;
      int j = 1;
    
      f(i, j);
    }
    will increment j but not i. The first argument i, is passed by value, the second argument, j, is passed by reference.
    So, the subject matter is the actual argument that is passed to the function, is it copied or is it referenced (i.e. aliased). Thus, in the case of a pointer, it has nothing to do with what to the pointer points to, but the actual argument passed to the function, i.e. the pointer value itself. Hence a modified parallel of the above for pointers would be:
    Code:
    void f(int* val, int*& ref)
    {
      val++;
      ref++;
    }
    When f() is called, val++ increments a local copy of the first actual argument, whereas ref++ increments the second actual argument. For example,
    Code:
    void g()
    {
      std::vector<int> data(2, 0);
      int* i = &data[0];
      int* j = &data[0];
      
      f(i, j);
    }
    will increment j but not i. The first argument i, is passed by value, the second argument, j, is passed by reference.
    The only thing that comes into question then, is what if a reference object is passed to a function that has a reference argument? Isn't the refererence object the actual argument? Isn't the reference object copied and thus passed by value? Well, the answer to that (I read someone else describe it this way, and it helped) is that a reference should never be be thought of as being copied (regardless of what the compiler actually does), but instead, that a new reference is created to the actual argument, and since a reference object is an alias, it should be thought of that the aliased object is the actual argument that has been passed to the function and not the alias itself. The proof of the pudding is in the eating as they say. So, here is at least some evidence that C++ sees the aliased object and not the reference object.

    Code:
    #include <iostream>
    #include <vector>
    #include <typeinfo>
    
    class test
    {
    public:
      test(const std::vector<int>& v) : vec(v){}
      const std::vector<int>& vec;
    private:
      test& operator=(const test&);
    };
    
    int main()
    {
      std::vector<int> vec;
      test t(vec);
    
    
      std::cout << "vector type name     : " << typeid(vec).name()   << "\n" 
                << "vector ref type name : " << typeid(t.vec).name() << std::endl;
    }
    The above outputs:

    Windows
    Code:
    vector type name     : class std::vector<int,class std::allocator<int> >
    vector ref type name : class std::vector<int,class std::allocator<int> >
    Linux
    Code:
    vector type name     : St6vectorIiSaIiEE
    vector ref type name : St6vectorIiSaIiEE
    The above at a minimum, shows that C++ views the actual argument as the aliased object (vector) and not the alias (vector reference).

    Anyway, knowing what C++ means by reference semantics, doesn't dictate what the rest of the computer science community means by reference semantics. That said, I've come to the position that I think that the strict alias view of reference semantics is the better view to have even in the wider context. That being the case, I would rather that it had been called "alias semantics" and "pass by alias" - at least then, it would have allowed less room for interpretation.

  3. #18
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: passing smart pointer

    Quote Originally Posted by monarch_dodra View Post
    Meh. Personally, I don't believe you could say either way based off of type alone, but rather "what" you consider the argument is. As you say, a pointer is itself both a value, and a reference to something else. A function may want to operate on either the pointer itself, or the pointed object.

    EG:

    Code:
    void modifyT(T* p); //reference semantic on T type
    void samePoints(T* p1, T* p2); //value semantics on T* type
    void findObject(T** p); //Reference semantics on T* type
    If you don't define what your functions are trying to do, and what the argument is, then it makes no sense to talk of reference/value semantics based off type alone. IMO, doing so is just a sterile back and forth argument.

    No context. No semantics.
    Yeah, that is where I was coming from in post #10. My point being is that it depends on intent, i.e. what is the subject matter?

    But, if you take the strict alias view of reference semantics, then the subject matter is always what is passed as the actual argument, not the intent. If you take the more loose view of reference semantics, then the subject matter comes down to intent and not necessarily the actual argument. However, C++ takes the strict alias view, hence it is always the actual argument that is the subject matter. As superbonzo has just pointed out, the C++ standard does not make any reference to the terms "pass by reference" or "pass by value", it only mentions "reference semantics", which although it doesn't define what that term means, it does make statements that allude to it meaning strict alias. e.g.

    slice_array assignment [lib.slice.arr.assign]
    Code:
    void operator =( const valarray <T >&) const ;
    slice_array & operator =( const slice_array &);
    1 These assignment operators have reference semantics, assigning the values of the argument array elements to
    selected elements of the valarray<T> object to which the slice_array object refers
    .
    Hence, pointers do not have reference semanitcs for assignment and therefore do not strictly conform to the notion of reference semantics.
    Last edited by PredicateNormative; August 21st, 2014 at 07:10 AM.

  4. #19
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: passing smart pointer

    So, razzle, lets get back to businness...

    Quote Originally Posted by razzle View Post
    In systems with hard real-time constraints there are two options, either prohibit dynamic memory allocations altogether or use an allocator with timing guarantees. So not even in the special case of real-time should dynamic allocations obviously be avoided, and certainly not in the general case.
    You are missing the point, the reason for avoiding dynamic memory allocation in real-time systems, is not always to do with the timing guarantees of the allocator - incidentally, at the end of the day, the timing guarantees of any dynamic memory allocator are either directly or indirectly at the mercy of the underlying system. Yes allocators can be empirically tested on specific systems, but the timing results of that specific system cannot be assumed on a system where either the hardware varies, the execution environment varies, or both.

    That said, even if you are coding for a system that is timing sensitive, you do not necessarily need to avoid dynamic memory allocation just because of timing. For example, if you know the bounds of the maximum amount of memory that you will need, then you can create a memory pool that makes a single up front large memory allocation at application startup and then manages how memory from that pool is internally allocated throughout the life of the process. The thing is though, if your allocation/deallocation pattern is not simple, then this option brings its own issues, e.g. writing an internal memory manager that minimises fragmentation within the pool (i.e. minimises the occurance of unused parts of memory between used parts). Also in the case of fragementation, how do you deal with the situation where the memory pool manager gets a request for a large chunk of its allocation, but it is unable to service the request because it doesn't have a contiguous block of memory free that is large enough for the request (even though its total remaining reserve is larger than the request)? An exception you might say? Yes, but this failure might be a critical failure causing your system to fail - a failure that could have been avoided in the case where dynamic allocation wasn't necessary. In addition, you would need to manage object alignment requirements yourself - another potential risk.

    That aside, lets say you are working on a safety related embedded system (many hard real-time systems are safety related), you have tested and somehow proved that dynamic memory allocation requests will always be serviced within a required time period and result in a successful allocation. Thus you are happy that you can use dynamic memory allocation in such a system, so everything is ok right? Wrong. If you are working on a safety related system, then you will need to prove as best you can that your system is safe (will never fail in an unsafe manner, will never accidentally overwrite the memory space of another process etc.). For this reason, many industrial and government customers will insist that you conform to an accepted safety related coding standard. The one that is most often used in the Automotive and Defence industries is "MISRA C++: Guidelines for the use of the C++ language in critical systems". If you are truely conforming to that standard as best you can, then every instance where you break a MISRA rule has to be documented and justified. For example, every time you use dynamic memory allocation, every time you make a call to a library that is not MISRA compliant, every time you decide to pass a const char* pointer (or any other non-const pointer for that matter) without also passing the size of the data to a function, you must document and justify reason for doing so - and generally your justifications will need to be accepted by the software safety officer (if the software safety officer does not support your justification, then a likely outcome will be that you need to rewrite that section of code in a (more) compliant manner). Some customers of safety related systems will not allow the blanket disregard of any MISRA rule that is marked by MISRA as "Required" (e.g. Rule 18-4-1 (Required) Dynamic heap memory allocation shall not be used). When you are required to conform to such a standard on a daily basis, it somewhat shapes the way in which you program - safety (and safety standard compliance) comes first. Thus you prefer automatic storage objects to dynamically allocated objects (even in the case of being able to use smart pointers), not only because it saves a headache as far as documenting safety standard violations goes (and getting the justifications accepted), but also because it is a safer way of coding (mistakes are less likely) and your code is going to run faster too. The forward of the MISRA guidelines starts with a quote from Bjarne Stroustrup,

    "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows yout whole leg off."
    The idea of the MISRA guidelines is to minimise the chances of a developer making mistakes and thus improving the safety and robustness of the software. That does not mean that you can never break a MISRA rule, but it does mean you should think twice about it, and when you do, be prepared to defend/justify your decision. So all that is in the context of real-time safety related systems. But in the wider context...

    It is a fact that people make more mistakes around dynamic memory allocation than they do around automatic objects. You'll know this if you have worked with a variety of developers at varying levels and will have no doubt seen for yourself the horrendous mistakes that people make with, or without smart pointers; without smart pointers, memory leaks, access of invalid pointers, mismatch of new/delete, new[]/delete[], failure to write exception neutral objects, leading to potential double deletion errors etc.; even with smart pointers, I've seen numerous instances of where people have allocated an array to a smart pointer that is intended for a single object, I've seen weird instances of where people have allocated an array of primitive type using malloc and passed the result to a smart pointer constructor (as you'll no doubt guess, that was a guy from a C back ground that did that), I've seen people use auto_ptr in containers and then wonder why they have problems, I've seen people using smart pointers to allocate an object in one module and pass it into another module(i.e. shared object) for procesing and destruction - yes the solution to all these problems is to educate such people, but these are all issues that would not occur with automatic objects, or in some cases use of the provided STL containers. Look, I'm not saying never use dynamic memory allocation, I'm simply saying prefer automatic storage where possible, only use dynamic memory allocation when necessary (i.e. when automatic storage is not appropriate and/or possible, e.g. large allocations; allocations where the size is not known at compile time or needs to change dynamically at run-time; when using creational design patterns; etc.). If you look over posts that I have submitted on this forum, you will see that I often use dynamic memory allocations (though I always wrap bare allocations up in complete RAII objects so that users of the object are unable to tell that dynamic memory allocation has taken place).


    Quote Originally Posted by razzle View Post
    Many, maybe even most modern programming languages rely heavily on dynamic memory. If you're into object orientation and functional programming and want to do it well, dynamic memory is essential. In C++ there are ways to accomplish this in a safe, efficient and orderly manner.
    I haven't said anything to the contrary.

    Quote Originally Posted by razzle View Post
    Your objections are moot and typical of those who view C++ through a C lens.
    What advice have I given that suggests that I am displaying the view of someone who views C++ through a C lens? I have simply said that you should avoid using dynamic memory allocation unless it is really necessary (i.e. the example that I have given in my previous paragraph) and that you do not need to dynamically allocate memory to make use of polymorphism - there are plenty of polymorphic OO design patterns that you can make use of without it (in fact, you should prefer composition to inheritence anyway). At the end of the day, all I have really said with respect to dynamic memory allocation in a nut shell is avoid the gratuitous use of dynamically allocating memory (i.e. prefer automatic objects when they are appropriate).

    Quote Originally Posted by razzle View Post
    Full use of object orientation and functional programming requires dynamic memory and in my view C++ is as suitable for this as say Java and C#. Your advice implies that C++ doesn't play in the same league. I beg to differ. Okay, C++ may require a little more on part of the programmer but that's a small price to pay for the extra flexibility.
    What advice have I given that suggests:
    1) that full use of object orientation and functional programming does not require dynamic memory, or that C++ is not as suitable for this as say Java and C#, or
    2) that C++ doesn't play in the same league
    As far as I can see, I have not made any such claims.


    Quote Originally Posted by razzle View Post
    I rely on the object oriented and functional approaches to secure and robust code.
    Me too, but that does not mean that I use dynamic memory allocation gratuitously - I use it when necessary.

    Quote Originally Posted by razzle View Post
    Routinely applied defensive copying has no place here.
    Never said it did, and never said that it should be routinely applied, all I said was that if an object is passed a native pointer, then in the context where it needs to be able to access the data after the function call, then the only safe thing you can do is copy the data - it is not safe to store a copy of the pointer itself since you have no idea of the life-time of the data (you should never assume that the life-time of the data as any longer that the function call) and from an ownership point of view, you cannot assume ownership of the data pointed to by a native pointer. If it was a smart pointer instead of a native pointer, I wouldn't have made a comment.

    Quote Originally Posted by razzle View Post
    In C style C++ it may look different but even so you wouldn't want extensive copying to turn your program into a dinosaur in a tar pit.
    Why on earth are you incorrectly assuming that I am coming from a C style C++?

    Quote Originally Posted by razzle View Post
    Thread safety is not guaranteed by the RAII idiom.
    Never said it was, but I did say that an explicit RAII class could be scaled to support threading (i.e. it could be easily made thread safe).

    Quote Originally Posted by razzle View Post
    In the smart pointer case the internal counter must be atomic. Furthermore the variable that's holding the smart pointer may have to be atomic depending on the situation, just like when an ordinary pointer is used.
    Yeah, but I haven't yet come accross a smart pointer implementation that is genuinely completely thread safe. Even if there is one, you not only have to put locks around the smart pointer, but you also need to lock the object to which it points (this requires the object itself to be thread safe) and if you are not consistent with lock ordering everywhere then you end up with thread deadlock. It should also surely be better/safer (far less room for mistakes) to handle locking and locking order in one place (i.e. using an explicit RAII class), than many places using a smart pointer and some other lockable object to which it refers.

    Quote Originally Posted by razzle View Post
    So smart pointers are RAII and thread safety concerns are no reason to avoid them. On the contrary. It's better to apply a well known established abstraction systematically rather than inventing the RAII wheel over and over again on every occasion. Prefer smart pointers whenever applicable.
    It is not about reinventing the wheel over and over, it is simply about safely managing read/write access to dynamically allocations in one place (i.e. thread safe aggregation). I don't have a problem with using smart pointers internally to manage necessary allocations, but from a thread safety point of view, I don't think smart pointers should be passed around public interfaces left right and centre - you are only going to give yourself a potential nightmare rewrite if multithreading and heance thread safety need to be added at some point down the development life-cycle. That is not to say there are never good reasons to pass a smart pointer on a public interface, there are (optional data for example), but whenever there isn't a really good reason to do so, I would advise caution.

  5. #20
    Join Date
    Jul 2013
    Posts
    576

    Re: passing smart pointer

    Quote Originally Posted by superbonzo View Post
    nowhere in the standard the expression "pass by reference" is used,
    It is if you look carefully. I never claimed the standard made a big deal out of this terminology. It doesn't even define it but still it's used in a few places indeed.

    One complication is that the same notation is used for two semantic situations; the narrow case when focus is on the parameter and the wider case when the focus is on what the parameter represents. Sometimes a notational distinction is used to separate the cases, for example by-value/by-reference (with the "-" added) to denote the narrower case. This is applied in the standard.

    But neither the Stroustrup book nor the standard deviates from the basic distinction between "by value" and "by reference". That's my point. There certainly isn't a third case "by pointer" as was claimed.
    Last edited by razzle; August 25th, 2014 at 02:29 AM.

  6. #21
    Join Date
    Jul 2013
    Posts
    576

    Re: passing smart pointer

    Quote Originally Posted by superbonzo View Post
    either you're wrong and the meaning is more semantical than syntactical ( this is how I've always read it BTW ) or you're right and that terminology has poor conceptual and practical utlity. I don't know ...
    That's a false dilemma since I never claimed parameter passing is a question of syntax only.

    This is what I said in an earlier post,

    "Again, the semantics of parameter passing pertains to the passing of the parameters, not their usage in a wider context. When value semantics is used it's called pass by value. When reference semantics is used it's called pass by reference."

    Or expressed differently in the case of pointers: When you pass a pointer you pass the pointer and not what it's pointing to. You can pass the pointer either by value or by reference (by-value or by-reference to be precise), nothing else.
    Last edited by razzle; August 24th, 2014 at 03:08 AM.

  7. #22
    Join Date
    Jul 2013
    Posts
    576

    Re: passing smart pointer

    Quote Originally Posted by PredicateNormative View Post
    Agreed, however, outside of the context of Stroustrup and the C++ standard (neither of which by the way give any formal definition of the term reference semantics, though both do make statements that would exclude pointers from being compliant), the definition of the terms "reference semantics" and "by reference" do not seem to be established as such, at least not with any consistency.
    It's precisely the fact the neither Stroustrup nor the standard cares to define this terminology that tells us it's established. It's assumed so well known that no definition is deemed necessary. It's simply used without further ado.

    Nowhere inside or outside those sources, despite intensive searching, have you been able to find support for your claim that C++ supports three parameter passing mechanisms, by value, by reference and by pointer, right? So even if you consider yourself a big C++ authority I suggest you drop this claim. At the end of the day Stroustrup and the C++ Standards Committee carry more weight than you. It's time to accept that.

    It's important to know this terminology because it's used not only for C++ but also other languages and to compare languages. For example C and Java support pass by value only, Fortran supports by reference only (at least in the early versions) and C++ supports both.

    If you claim that objects are passed by reference at a Java forum you will be severely rebuffed. You will be told that no object is ever passed in Java. It's the object reference that is passed and it's passed by value just like the primitives always are.

    And the fact that C sports pointers doesn't mean it supports pass by reference. You would have to say that pointers passed by value can be used to simulate pass by reference, and you could say the same in C++ too of course.

    Etcetera.
    Last edited by razzle; August 24th, 2014 at 04:59 AM.

  8. #23
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: passing smart pointer

    Quote Originally Posted by razzle View Post
    It's precisely the fact the neither Stroustrup nor the standard cares to define this terminology that tells us it's established. It's assumed so well known that no definition is deemed necessary. It's simply used without further ado.
    Yes, however, as I stated previously:
    Quote Originally Posted by PredicateNormative
    I cannot find any official formal definition of the term "reference semantics" - that's not to say there isn't one, but if there is, then it would seem the computer science community in general doesn't know where to find it. Any pages that I have found have not made any reference to such a formal definition of the "established terminology" and opinions to what the terminology (the distinction between pass by value and pass by reference) means clearly differ. Every page I look at, the definition of the term "reference semantics" is either merely assumed, or the opinion of some random person, lecturer, academic or institution . Because there are varying views as to what "reference semantics" means, there are varying views of what "by reference" means. There is no set in stone official definition (by an official body of any note) of "reference semantics" that I can find. I've searched university lecture notes in computing science, academic papers, articles from both academia and industry (e.g. IBM). None make any reference to an established definition of the term "reference semantics", they all seem to have their own definition. Hence some take it that reference semantics means "pointer semantics" and others "strict alias semantics".
    If the true terminology was still so well widely known and accepted, there wouldn't be so many varying opinions. The fact is, it may have been well established a long time ago, and understood by those that have experience and knowledge of the history of the terms, but there has been such wide misinterpretation of these terms over recent years, that the terminology is getting surrounded by misinterpretation and in some cases even drowned out. I expect the reason why Stroustrup or the standard do not define the terminology is as you say, they assume it to be so well known that that no definition is required (though it would be useful if they did provide it, or at least make reference to an official definition just to avoid misunderstanding).

    Quote Originally Posted by razzle View Post
    Nowhere inside or outside those sources, despite intensive searching, have you been able to find support for your claim that C++ supports three parameter passing mechanisms, by value, by reference and by pointer, right?
    Wrong, I found plenty of claims that C++ has pass by value, pass by pointer and pass by reference. Here are a significant few (which I will argue against):

    - http://pic.dhe.ibm.com/infocenter/co...y_pointer.html - maybe not that significant...
    - https://isocpp.org/wiki/faq/const-co...overview-const - isocpp is the offical website of the C++ Standard Foundation, as you will no doubt know, Bjarne Stroustrup and Herb Sutter are directors of the C++ Standard Foundation. You would think that things that get put on that site have their backing. However, the fact that they never mention the term pass-by-pointer in any of their books, would suggest that neither Stroustrup or Sutter had been consulted before the comments against the code in the link were posted. I would very much doubt that either Stroustrup or Sutter sutter support the term pass-by-pointer and therefore, I would expect they would have suggested that the term pass-by-pointer should be removed (had they been consulted) - that is my opinion though.
    - More Effective C++ (Scott Meyers): Item 12 - It is probably worth noting that there is only one occurance of the term in this book, and no occurances in any of the rest of Meyers books (or at least the 3 that I own). Thus, it would seem that it is a one off incident that could potentially be considered a mistake.

    If you do a Google search, you will see a good number of academic institutions are incorrectly teaching pass-by-pointer as valid terminology alongside pass-by-value and pass-by-reference.



    Quote Originally Posted by razzle View Post
    Nowhere inside or outside those sources, despite intensive searching, have you been able to find support for your claim that C++ supports three parameter passing mechanisms, by value, by reference and by pointer, right? So even if you consider yourself a big C++ authority I suggest you drop this claim. At the end of the day Stroustrup and the C++ Standards Committee carry more weight than you. It's time to accept that.
    If you had read my previous posts more carefully, you would have noticed that I stopped supporting the term "pass by pointer". Did you even read post #17 properly? I spent a significant amount of time showing why I have changed my mind and only accept pass-by-value and pass-by-reference. To be fair though, I never stated that I no longer see pass-by-pointer as valid terminology, neither did I state that I now accept that there are only two parameter passing mechanisms in C++, perhaps if I'd done both, it would have avoided confusion. That said though, I did spend the time to expain why passing pointers is pass by value and why passing references is pass by reference (even though C++ reference objects have a size and under they hood might be copied by value by the compiler). Pointers clearly do not adhere to strict alias semantics, they can be considered objects in their own right, they have a value that can be manipulated, pointers are copied by value on the interface, therefore they are pass by-value. References on the other hand are not objects in their own right they are strict aliases, they do not have a value that can be manipulated, in fact C++ makes every effort to prevent anyone from thinking of them as objects, and therefore regardless of whether or not a compiler actually copies a reference object on an interface, it is still pass by reference, there is no programmatic way to prove that a reference outside of an interface is different to one inside the interface, they have no value that can be manipulated and are therefore not pass-by-value, but pass-by-reference. I spent the time to show, by example, and by explanation that pointers are pass by-value and not a form of pass by-reference,. I never claimed to be a "big C++ authority" and I dropped any claim that "pass by pointer" is a subset of "pass by reference" a long way back in this thread.

    Here is a quote from post #17 with some additional highlighting:

    Quote Originally Posted by PredicateNormative
    So, the subject matter is the actual argument that is passed to the function, is it copied or is it referenced (i.e. aliased). Thus, in the case of a pointer, it has nothing to do with what to the pointer points to, but the actual argument passed to the function, i.e. the pointer value itself. Hence a modified parallel of the above for pointers would be:
    Code:
    void f(int* val, int*& ref)
    {
      val++;
      ref++;
    }
    When f() is called, val++ increments a local copy of the first actual argument, whereas ref++ increments the second actual argument. For example,
    Code:
    void g()
    {
      std::vector<int> data(2, 0);
      int* i = &data[0];
      int* j = &data[0];
      
      f(i, j);
    }
    will increment j but not i. The first argument i, is passed by value, the second argument, j, is passed by reference.


    Quote Originally Posted by razzle View Post
    It's important to know this terminology because it's used not only for C++ but also other languages and to compare languages. For example C and Java support pass by value only, Fortran supports by reference only (at least in the early versions) and C++ supports both.

    If you claim that objects are passed by reference at a Java forum you will be severely rebuffed. You will be told that no object is ever passed in Java. It's the object reference that is passed and it's passed by value just like the primitives always are.

    And the fact that C sports pointers doesn't mean it supports pass by reference. You would have to say that pointers passed by value can be used to simulate pass by reference, and you could say the same in C++ too of course.

    Etcetera.
    I have no problem with any of that.
    Last edited by PredicateNormative; August 28th, 2014 at 08:31 AM.

  9. #24
    Join Date
    Oct 2008
    Posts
    1,456

    Re: passing smart pointer

    and if you search "java pass by reference" you'll find neverending discussions even more hilarious than ours. Indeed, due to the fact in Java "assignment" ( and parameter initialization ) of variables of class type operates always on the underlying references, in Java full reference semantics ( as intended in langauges like c++, eg, say, allowing to write a swap function ) is impossible. So, they say that everything is passed by value ( but it would suffices to weaken java aliasing rules a little, to allow a language level operator, say, "Assign" capable of operating on the pointed to object, instantaneously making Java "pass by reference" again ... ).

    Hironically, the relevant wikepedia article uses a totally different terminology ( invented by Liskov ) that is neither pass-by-value nor pass-reference, it's "pass by sharing" invented to accomodate the peculiar semantics in java-like languages. This excerpt is humorous ( especially the "citation needed" bit ):

    It is used by languages such as Python,[5] Iota, Java (for object references),[6] Ruby, Javascript, Scheme, OCaml, AppleScript, and many others. However, the term "call by sharing" is not in common use; the terminology is inconsistent across different sources. For example, in the Java community, they say that Java is pass-by-value, whereas in the Ruby community, they say that Ruby is pass-by-reference[citation needed], even though the two languages exhibit the same semantics.
    ... so, razzle's high reactivity to the subject is explained

    that said, all this remains irrilevant in the c or c++ world, where there's no implicit "boxing" to deal with; indeed, as PredicateNormative observed, a google search shows a lot of teaching material where pointers are suggested as both a "passing mechanism" and more specifically as a way to "pass by reference" ( indeed, according to many java-ers from the google search aforementioned the ability of writing a swap function is the proof of the pass-by-reference of the language and you surely can write a swap function in C ).

    too much confusion for an "established terminology" !

  10. #25
    Join Date
    Jul 2013
    Posts
    576

    Re: passing smart pointer

    Quote Originally Posted by PredicateNormative View Post
    If you had read my previous posts more carefully,
    I've read your post and you're still using the established terminology incorrectly. For example, you say,

    "... I did spend the time to expain why passing pointers is pass by value ... "


    In the established terminology you make a distinction as to whether you're referring to the narrower semantics of the parameter passing, or to the wider semantics of the parameter being passed.

    With the narrower semantics a pointer is passed either by-value or by-reference just like any parameter.

    With the wider semantics a pointer is pointing to an object and that object can be said to be passed by reference when the pointer is passed (regardless of whether the pointer itself is passed by-value or by-reference in the narrow sense).
    Last edited by razzle; August 31st, 2014 at 11:48 PM.

  11. #26
    Join Date
    Jul 2013
    Posts
    576

    Re: passing smart pointer

    Quote Originally Posted by superbonzo View Post
    too much confusion for an "established terminology" !
    To avoid being confused and to avoid confusing others it's important to know the established terminology.

    Once you do that you can confidently play with convention, but only if everybody knows you know you're breaking the rules.

    Barbara Liskov could drink champange from her left shoe at a royal wedding dinner if she wanted and everybody would smile admiringly and think nothing of it.
    Last edited by razzle; September 1st, 2014 at 12:04 AM.

  12. #27
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: passing smart pointer

    Quote Originally Posted by razzle View Post
    With the wider semantics a pointer is pointing to an object and that object can be said to be passed by reference when the pointer is passed (regardless of whether the pointer itself is passed by-value or by-reference).
    THAT is actualy an objection I have to the whole naming thing.
    a pointer doesn't HAVE to point to an object at all. Whereas a value is a value, and a reference can't be anything other than a reference to an object (if we leave out any abusive tricks with casting to get a reference to something that isn't what it says it is). For a pointer, no elaborate tricks are needed, and in fact, NULL is a common "points to nothing" indicator, but there are equally other values that might have special meaning (MFC and even windows API is full of these), MAKEINTRESOURCE is probably the most Obvious one.

  13. #28
    Join Date
    Jul 2013
    Posts
    576

    Re: passing smart pointer

    Quote Originally Posted by OReubens View Post
    THAT is actualy an objection I have to the whole naming thing.
    a pointer doesn't HAVE to point to an object at all. Whereas a value is a value, and a reference can't be anything other than a reference to an object (if we leave out any abusive tricks with casting to get a reference to something that isn't what it says it is). For a pointer, no elaborate tricks are needed, and in fact, NULL is a common "points to nothing" indicator, but there are equally other values that might have special meaning (MFC and even windows API is full of these), MAKEINTRESOURCE is probably the most Obvious one.
    I don't understand why you mean by "the whole naming thing"?

    But if you're referring to a confusing terminology I can only say this is one important reason to stick to the established terminology. You minimize the risk of being misunderstood. That's why it's being upheld both in the Stroustroup C++ book and in the C++ standard.
    Last edited by razzle; September 1st, 2014 at 12:23 AM.

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)