CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Feb 2009
    Posts
    326

    catch parameter, pass by reference

    Hi,

    I am learning about exceptions and catch parameters.

    I tried defining the catch parameter as pass by reference, but it worked like pass by value.

    There is no compilation error, and the exception is caught, but works like pass by value.

    Let me know if it is completely absurd and catch parameters is always pass by value.

    Pasted below is the example:
    Code:
    #include <iostream>
    
    int main()
    {
       
        using std :: cout;
        using std :: endl;
    
        system("clear");
    
        int v1 = 10; 
    
        try 
        {   
            throw v1; 
        }   
    
        catch(int& pV1)
        {   
            cout << "It is being caught\n";
            pV1 = 20;
        }   
    
        cout << "v1 = " << v1 << endl;
    
        return(0);
    }
    Note:
    I understand that v1 can be modified inside a catch block by throwing &v1 and by having a corresponding catch block with int* parameter.
    But my question is concerning pass by reference catch parameter as stated at the beginning.
    Last edited by Muthuveerappan; July 29th, 2009 at 08:05 AM.

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

    Re: catch parameter, pass by reference

    The bit of information you are missing is that when you call throw, throw makes a temporary copy of the object being thrown (section 15.1.3 of the C++ Standard), and it is the copy that is caught by the catch statement. Therefore, your modification modified the copy and not the original as you expected (the copy is an lvalue, so that means that assiginig to it is a valid operation).

  3. #3
    Join Date
    Feb 2009
    Posts
    326

    Re: catch parameter, pass by reference

    Thanks a lot PredicateNormative!! very well explained.

    Therefore I guess there is not much sense using a pass by reference.

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

    Re: catch parameter, pass by reference

    You should always throw by value and catch by reference (unless you have a very good reason), because catching by value will slice polymorphic objects, and throwing and catching by pointer leaves the developer wondering whether or not they need to delete the allocation pointed to by the pointer once they have reached the end of the catch block (assuming that the developer who is catching the exception is not the same one as the one that threw the exception).

  5. #5
    Join Date
    Feb 2009
    Posts
    326

    Re: catch parameter, pass by reference

    Thats very interesting, I didn't think that far (slicing problem and pointer whether to delete or not).

    I agree with you, its best to catch by reference for the reasons you stated and you could save one less copy.


    Question
    -----------
    Any reason why internally a temporary copy is made before throwing the exception ?

    Testing
    ----------
    As u stated, throw makes a temporary copy and this is seen by the invocation of the copy constructor.
    I just tested this and works as u stated, thanks again, given below is the program for reference:

    Code:
    #include <iostream>
    using std :: cout;
    using std :: endl;
    
    class ClassA
    {
        public:
            ClassA();
            ClassA(const ClassA& pClassA);
    };
    
    
    int main()
    {
        system("clear");
    
        ClassA objA1;
    
        try 
        {   
            throw objA1;
        }       
            
        catch(...)
        {}  
    
    
        return(0);
    }
    
    ClassA :: ClassA()
    {
        cout << "Default Constructor is invoked\n";
    }
    
    ClassA :: ClassA(const ClassA& pClassA)
    {
        cout << "Copy Constructor in invoked\n";
    }

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

    Re: catch parameter, pass by reference

    Think about what would happen in the following case if throw did not make a copy:

    Code:
    int function(std::string value)
    {
      int result(0);
      std::stringstream ss;
      ss << value;
     if(!(ss>>result))
      {
         throw value;
      }
      return result;
    }// value's life will end here
    I wouldn't get into the habit of throwing string objects (try to only throw objects that derive from std::exception unless you have good reason), however, I have thrown one here to keep the point simple.

    The string object value is created at the pass-by-value function interface. It is a local function object and its lifetime is contained within the function scope, therefore when the function ends, value will be destroyed (popped off the stack). Now consider this, if throw does not create a copy, then, when the stack unwinds, the exception will exit the function and all of the local function objects will be destroyed including value. This means that by the time the exception reaches the catch statement, there will be no valid exception object to access (because it will have been popped off the stack), and attempting to access it will yeild undefined behaviour. So the solution that the C++ Standard lays down is that throw must copy the object being thrown, the compiler can then control the life time of the copy so that it is not invalidated as the stack unwinds. This means that the object will always be valid for the catch statement.

  7. #7
    Join Date
    Feb 2009
    Posts
    326

    Re: catch parameter, pass by reference

    Thanks for that, I think I understand better now ... I initiated this thread for catch parameter and now looks like I didn't have a good understanding of throw and lot of other things. Thanks for patiently answering my questions.

    Prior to your explanation, I missed the following:
    1) Guess I completely missed the point that once the exception is thrown, the control leaves the function (assuming it is not handled inside the function) and any local variable (inside the function) that is thrown as an exception will not be alive outside the function.

    2) And exceptions are not like function calls, in function calls, when a function is invoked, the function contents are executed, and then the control returns to the point immediately after the function call, but with exception control never returns to that point, so once the exception is raised (assuming there is no catch that handles the exception), the functions exits and never to be return after catch block is completed.

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

    Re: catch parameter, pass by reference

    Glad to be of help.

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured