CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 31
  1. #16
    Join Date
    Apr 1999
    Posts
    27,449

    Re: try/catch don't work under release version???

    Quote Originally Posted by amcelroy View Post
    Sorry to revive a dead thread, but I had this same problem. Try Catch works under debug but not release for x64 compiler using VS2010. The issues seems to be that Try Catch aren't implemented if the compiler is set to optimize the code.
    And the same thing applies to your situation as in the other -- let's see your code that you claim should throw an exception, as what you think is being executed may never be executed.

    Optimizing code means that code is removed and moved around. So the code you think should be throwing an exception may not have even been called, used, or it could have been removed from the final executable.

    Do you really think that a major compiler only has exception handling when the code is unoptimized? If that were the case, then there would be thousands of programmers reporting this issue.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 28th, 2013 at 02:51 PM.

  2. #17
    Join Date
    Feb 2013
    Posts
    5

    Re: try/catch don't work under release version???

    My particular piece of code is to catch an error if the user passes a pointer to a class that isn't valid.
    d is a custom class that is linked to an OpenCL device and has a bunch of stuff in it. For my test, d is a NULL pointer.

    Code:
    try{
    		d->GetContext();
    	}
    	catch(...){
    		return OPENCLV_DEVICE_NOT_FOUND;
    	}
    	return 0;
    Debug and Release with optimization off runs fine, any optimization and try-catch doesn't work.

    Austin

  3. #18
    Join Date
    Apr 1999
    Posts
    27,449

    Re: try/catch don't work under release version???

    Quote Originally Posted by amcelroy View Post
    My particular piece of code is to catch an error if the user passes a pointer to a class that isn't valid.
    d is a custom class that is linked to an OpenCL device and has a bunch of stuff in it. For my test, d is a NULL pointer.
    Accessing a member function using a NULL pointer doesn't guarantee any exception will be thrown. The only thing it does do is guarantee undefined behaviour, and undefined behaviour means that anything can happen.

    Instead of that, why not yourself actually throw an exception instead of relying on things you don't know will throw. You will see that there is nothing wrong with the exception handling.

    Regards,

    Paul McKenzie

  4. #19
    Join Date
    Apr 1999
    Posts
    27,449

    Re: try/catch don't work under release version???

    Quote Originally Posted by amcelroy View Post
    My particular piece of code is to catch an error if the user passes a pointer to a class that isn't valid.
    In addition, this type of check is pointless. I can pass you a pointer that is valid in terms of being in the program's address space, but invalid in terms of the context of the program.

    What if I pass a pointer to dynamically allocated memory, delete the pointer, and pass to you that address again? How do you know that the internals of what pointer points to is trash? Maybe it isn't trash yet, but is waiting to be overwritten later by the heap?

    Let the programmer who passed that illegal pointer to your function pay the price. There is no way for you to identify in all (probably most) cases if a pointer is valid or not.

    The only way to circumvent this is for you to create the object in a factory, and you pass that pointer to the object to the caller as a "handle". Then if the caller passes the handle to you, you do a lookup to see if it was one of the handles that came from your factory. That is the only way to get anywhere close to checking for an "illegal" pointer.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 28th, 2013 at 03:16 PM.

  5. #20
    Join Date
    Feb 2013
    Posts
    5

    Re: try/catch don't work under release version???

    Well, in this example I pass a NULL pointer, but the user might pass anything, I've no idea what the user is going to do. I can't check for all possible invalid combinations. If I pass a NULL pointer, call a Getter function to return a value of something from a NULL pointer, I don't understand how that can't possibly be an error. It clearly is when optimization is off, but when any optimization is on it doesn't catch it.

    The MS compiler must see that I'm not using d->GetContext() for anything and decides to optimize this out. Even if I do something like:

    Code:
            try{
    		cl_context f = d->GetContext();
    	}
    	catch(...){
    		return OPENCLV_DEVICE_NOT_FOUND;
    	}
    	return 0;
    try-catch still isn't thrown, the program does straight to return 0. So optimization must still be deciding not to execute the code in the try-catch loop. Yeah, the compiler knows better than me 99.9% of the time, but this seems like an error that should be thrown.

  6. #21
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: try/catch don't work under release version???

    Quote Originally Posted by amcelroy View Post
    Well, in this example I pass a NULL pointer, but the user might pass anything, I've no idea what the user is going to do. I can't check for all possible invalid combinations. If I pass a NULL pointer, call a Getter function to return a value of something from a NULL pointer, I don't understand how that can't possibly be an error. It clearly is when optimization is off, but when any optimization is on it doesn't catch it.

    The MS compiler must see that I'm not using d->GetContext() for anything and decides to optimize this out. Even if I do something like:

    Code:
            try{
    		cl_context f = d->GetContext();
    	}
    	catch(...){
    		return OPENCLV_DEVICE_NOT_FOUND;
    	}
    	return 0;
    try-catch still isn't thrown,
    Well, a smart compiler sees that your cl_context f is never used at all so it excludes this line!
    Just add something to use this cl_context f !
    Victor Nijegorodov

  7. #22
    Join Date
    Feb 2013
    Posts
    5

    Re: try/catch don't work under release version???

    Quote Originally Posted by VictorN View Post
    Well, a smart compiler sees that your cl_context f is never used at all so it excludes this line!
    Just add something to use this cl_context f !
    Argh!!! I'll just turn optimization off, 100% of the heavy lifting through OpenCL and I would rather do the error handling and reporting to shutdown OpenCL gracefully then let the programmer screw something up on an easily catchable accident such as a NULL pointer or invalid memory location.

    This code is wrapped in a DLL and I can't control the object 100% of the time. Just was letting the first poster know he wasn't alone and how he might be able to solve the issue.

  8. #23
    Join Date
    Apr 1999
    Posts
    27,449

    Re: try/catch don't work under release version???

    Quote Originally Posted by amcelroy View Post
    If I pass a NULL pointer, call a Getter function to return a value of something from a NULL pointer, I don't understand how that can't possibly be an error.
    There is a big difference in being an error and an error that guarantees an exception is thrown.

    I think you have the wrong idea about exception handling in C++. The only exceptions that are guaranteed to be thrown are:

    1) Exceptions that you throw.

    2) Exceptions that are guaranteed by the ANSI specification to throw (e.g. the vector::at() guarantees to throw on illegal bounds, operator new is guaranteed to throw on failure, dynamic_cast throws on an illegal reference, etc.)

    3) Exceptions that are thrown by the third-party library that is being used.

    4) SEH exceptions for Windows (if they are enabled).

    In no other circumstance is an exception guaranteed to be thrown. The keyword you seem to be missing is thrown. Just because your code is dodgy or an error doesn't guarantee a throw to occur.

    This would guarantee a throw:
    Code:
    if ( user_did_something_stupid )
       throw myException;
    If you wrote that, then you would make headway.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 28th, 2013 at 03:43 PM.

  9. #24
    Join Date
    Apr 1999
    Posts
    27,449

    Re: try/catch don't work under release version???

    Quote Originally Posted by amcelroy View Post
    Argh!!! I'll just turn optimization off, 100% of the heavy lifting through OpenCL and I would rather do the error handling and reporting to shutdown OpenCL gracefully then let the programmer screw something up on an easily catchable accident such as a NULL pointer or invalid memory location.
    So what happens when those other accidents that you can't detect happen? You're users are going to expect that your function catches everything and it cannot do that.

    Second, there are a myriad of examples of NULL pointers and accessing a member function through the NULL pointer and not crashing. Again, accessing a member using a NULL pointer is not a guaranteed throw. The only thing you can do is
    Code:
    void someFunctin(T *ptr)
    {
    //...
        if ( ptr )
        {
           // do work with ptr
        }
        else
        {
           // error -- here you can throw an exception back to caller
        }
    }
    No try/catch is needed there. Anything other than that is a waste of time, as you're going to totally miss pointers that have proper addresses within the program's address space but are illegal to use in the context of the program. Again, the case of the pointer value that was created with new, and then deleted, and then passed to your function. There is no way you will be able to know that the pointer value is illegal.

    Last, it is the responsibility of the caller to provide your class valid pointers. There are constructs that the user should be using to guarantee that what is being passed to you is valid, such as smart pointers and other such classes. You can't be responsible for every single mistake that comes from the user using your class incorrectly.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 28th, 2013 at 04:01 PM.

  10. #25
    Join Date
    Mar 2006
    Posts
    151

    Re: try/catch don't work under release version???

    From amcelroy:
    If I pass a NULL pointer, call a Getter function to return a value of something from a NULL pointer, I don't understand how that can't possibly be an error.
    Actually, that is quite easy to do in a non-erroneous way, as long as you are careful not to access any member data or the v-table of the possibly NULL class. (MFC code did it fairly often for reasons I no longer remember.)

    Here's an example:
    Code:
    struct Test
    {
        int FunctionA(int x)
        {
            if (this == NULL)
            {
                return x * 100;
            }
            else
            {
                return x * m_i;
            }
        }
    
        virtual int FunctionB(int x)
        {
            return x * 150;
        }
    
        int m_i;
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        Test * ptest = 0;
    
        int y = ptest->FunctionA(3); // not in v-table so no crash
        cout << y << endl;
    
        int z = ptest->FunctionB(5); // crash here because it will attempt to dereference a v-table at NULL.
        cout << z << endl;
    
        return 0;
    }
    This happily outputs 300 before crashing. The "this" pointer is just a hidden parameter in each (non-static) member function. Since non-virtual functions aren't in the v-table the compiler is able to determine exactly which code to invoke during compilation. As long as no virtual functions are called and no class member data is used, the NULL this pointer won't be dereferenced and the non-virtual member function can successfully execute.

  11. #26
    Join Date
    Feb 2013
    Posts
    5

    Re: try/catch don't work under release version???

    This is all pretty interesting, the finer points of C++ compilers. I'm just trying to be as responsible as possible in catching errors. I've tried to contain the damage the user can do, but there will invariably be something that someone does that will crash the program.

    NULL was just an example, what about some a pointer to a random variable, do these cases still not cause crashes?

  12. #27
    Join Date
    Mar 2006
    Posts
    151

    Re: try/catch don't work under release version???

    From amcelroy:
    NULL was just an example, what about some a pointer to a random variable, do these cases still not cause crashes?
    Well, it largely boils down to what Paul McKenzie was saying in posts #18 and #19. It's the whole "undefined behavior" idea. If the random variable points outside the program's address space you'll crash. If not, it could produce obvious, subtle, or unrecognizable errors. It might cause a side effect resulting in a seemingly inexplicable crash minutes or hours later (e.g. perhaps by overwriting a pointer stored somewhere else).

    You're possibly too concerned with being robust. You certainly want your function to be robust, but if users of your function have a bug in their code, that's their problem, not yours. Also, what if someone wants to use your function in speed-critical code? Extra checks for bad pointers (besides not being guaranteed to work for reasons others have described) would only slow the program down and would be useless once that someone has debugged his or her code.

    Note that NULL very often isn't a bad pointer but is rather a sentinel value (perhaps indicating something hasn't been previously allocated). Many consider it good programming practice to set pointers to NULL when done with them so that if they get dereferenced unexpectedly a crash will be guaranteed rather than "undefined behavior".

  13. #28
    Join Date
    Feb 2013
    Location
    United States
    Posts
    56

    Re: try/catch don't work under release version???

    If you do not know what code will be calling yours, then it is good idea to check whether a passed-in pointer is NULL or not. If it is not NULL, then assume it is valid.

  14. #29
    Join Date
    Apr 1999
    Posts
    27,449

    Re: try/catch don't work under release version???

    Quote Originally Posted by amcelroy View Post
    This is all pretty interesting, the finer points of C++ compilers. I'm just trying to be as responsible as possible in catching errors. I've tried to contain the damage the user can do, but there will invariably be something that someone does that will crash the program.

    NULL was just an example, what about some a pointer to a random variable, do these cases still not cause crashes?
    If you are concerned about the validity of the data being passed to your function, the solution is to have your users get handles issued by you, and not just created willy-nilly by the user.

    I mentioned this earlier -- you want the user to pass valid pointers to you, then you should be the one issuing the pointers to the user up front by making available a "Create" fiunction. The user want to destroy the pointer, then they must call your "Destroy" function. In this sense, you are basically creating handles for the user, and they must use this handle to do anything with your code.

    With the above approach, you have total control of what gets created, what gets destroyed, and can legitimately check if a handle is valid or not. Your "poor-mans" approach is IMO a waste of time -- you need to create a proper factory/handle model to accomplish any real error checking.

    For example, how is it that Windows never crashes if someone calls a WinAPI function with an invalid HWND? Internally the Windows system has a list of all the valid HWND's, so that when an API function is called, it looks up in the list for that passed-in value and determines whether to go forward with the function, or return an error.

    Regards,

    Paul McKenzie

  15. #30
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: try/catch don't work under release version???

    When a function accepts as a parameter a memory pointer, there are 1 of 4 possibilites:
    1) the pointer is correct and points to what is expected
    2) the pointer is NULL. This may or may not be an error depending upon the interface specification
    3) the pointer references valid memory in the program address space but does not point to what is expected
    4) the pointer references invalid memory outside of the program address space

    If you want to undertake pointer parameter checking, then 2) can be done easily, if required, by testing the pointer for NULL and if it is then throwing an exception. 4) will cause an exception when the memory is accessed - so use some statements that access the memory which won't be optimised away by the complier if the result isn't used. 3) can really only be checked by using the factory method as Paul outlined in post #29. This would require changes to all programs that use the function as they would have to obtain the factory produced handle and pass as function argument the factory handle rather than just a pointer to some memory. The only way that 3) can be checked for easily - and is not guarenteed - is to have some 'magic number' stored in a class member variable by the class constructor which can be tested whenever a pointer to the class is referenced.

    What level of checking a particular function does on its provided arguments is really down to overall system design/architecture and the tradeoff between robustness and speed. In some environments the level of checking performed is determined by compile time pre-processor identifiers. So there is the 'debug' version with all checking on and the 'release' version with only the most basic (or no) checks. But whatever checking is done or not done on function parameters should be stated clearly in the function contract documentation so that users of the function are aware.

Page 2 of 3 FirstFirst 123 LastLast

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