Can I Handle Exceptions with Try Catch in C? (setjmp, longjmp)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today i want to do something interesting i want to try to create try catch style exception handling in c [Music] hey everybody welcome back today i want to show you how to do something that a lot of programmers especially new programmers don't think is possible specifically that is try catch style exception handling in c i mean when we talk about c and we talk about its limitations that's one of the big ones right no classes no exceptions no stl but not anymore today i want to show you how to pull off this style of error handling using two functions set jump and long jump in c and as always source code is available through patreon so let's get into it okay so today we're going to start with a simple program it has main and one other function it takes a bunch of doubles from the argument list and basically reads them into an array then it has a function that computes the average of those values so that's up here pretty straightforward it's going to take the array of values in and its length it's going to go through i have a for loop here that's going to go through and compute the average of the values so it's going to add them all up and then divide by the length and then it returns that average and then we're printing out the average right here and i also have a simple make file here this looks like just about any other make file that i've made in any of my other videos i'll link below to my other make videos in the description if you want to reference those just if you feel like you need a refresher now if we come into the terminal you'll notice that this works fine i can run my example program with a few numbers you can see that it computes the average and prints it out just fine i'll try it with another set of numbers just to make sure that we didn't just get lucky but one thing you will notice about this current program is if i run it without any arguments then you get this not a number thing and let's just say that's not what i want today let's say that i want to print out some sort of error message if the array has length 0. okay so let's go back into our example now of course we could catch this up front right i could have an error message here that just says something like you know if length is less than or equal to zero and i could handle the error there and i could also check after the fact and check whether or not what compute average returned was not a number but what if i don't want to explicitly check return values what if i wanted instead to throw an exception so if we were using c plus plus or java or ruby or python or just about any other language out there that's not c we could simply put this in some kind of try catch block like this and then if we had a problem in the function we could just throw an exception and we could then print out the error out here in main and c doesn't have this functionality built into the language and of course we can debate about whether or not one error handling style is more or less convenient or more efficient or more readable than the other it really is going to depend on the program and programmer taste but my question for today is not should we use exception handling but rather can we use exception handling here without switching to a different language and of course the answer is we can otherwise i wouldn't have made this video so to do this today we're going to use two functions set jump and long jump and they're going to help get us there so let's look at how this works so the first thing i'm going to do is jump up here to the top and include a header file of course okay now the idea with setjump is that it saves the program's computing context so it's like taking a snapshot of the program or at least a snapshot of where it's currently executing and it saves that context specifically so that we can later jump back to that spot in the program using long jump now one thing we are going to need is a variable that's going to save that context so i'm going to declare that up here we'll call it save buff so this jump buff type is just a type that's declared for this purpose for set jump to use and i'm making it a global variable because it needs to exist across different function calls okay so now let's go back down in main and let's use set jump so what i'm going to do here is just we're going to call setjump we're going to pass in our save buff in there and we're going to check to see if it returns 0. and then if it does return 0 we are going to run this code down here now set jump is a little weird and i want to make sure you understand it before we go too much further when we call it it's going to initially return zero it's saving state but it's initially going to return zero so this code the code here inside the if statement is always going to run so this if block is going to act like my try block okay and i'll come back to that in a minute but first let's go up to our function and add an exception okay so if we come up here basically what we're going to do let's let's say right at the beginning we just check to see if our length is less than or equal to zero and if it is what i'm gonna do is call long jump with our save buff and one we'll just go with one for now doesn't have to be one but we'll go with one so now what this is going to do is when this is called when long jump is called it's going to jump back down in the program down here where we called set jump it's going to come down to this point and it's going to cause set jump to return again that's the really weird part is set jump is actually going to return again but this time set jump is going to return a 1 instead of a 0 because we passed in a 1 right here so what that means is jump back to set jump and return a 1 instead of a 0. so if this happens down here we are going to then return from set jump but it's not going to return zero anymore so we won't go into this block so we basically skip over this block and now if we compile our example and we run it okay so you can see this still works but if we run it here you notice now we get no output we don't get that not a number which is i guess a step in the right direction it's not really what we wanted we wanted to actually handle the error and print out some error message and so instead what we'll do is let's just come down here and we'll make an else block here this will act like a catch block and then i can say [Music] error invalid input and don't forget the semicolon and then if we come down here and we try to run it now you notice that we get this catch style behavior so basically it tries to compute the average it can't and it jumps back and so this is basically how try and catch blocks work so that's pretty cool now you're probably thinking like what are the limitations of this for example like can we nest these kinds of try catch blocks and we could we would just need to have different save buffs for every time we nest one we would need a different variable so we save the state in a different location so they don't save on top of each other but some of you purists out there might also be saying yeah this behaves like a try catch block but it's not as pretty it's definitely not as readable it's not as easy to understand as a tri-catch block would be in another language that actually has tri-catch blocks built in so since the theme of this video is can we do it let's see if we can use the preprocessor to try to make our syntax look more like a try catch block and we'll do that with some defines up here now just to be clear folks you want to be very careful and think twice before doing any kind of complicated preprocessor hackery it can definitely get you into some problems some really weird situations that may be difficult to debug and that actually seems like something we should talk about in a future video but again today i'm just interested in what can be done not what should be done i mean i'm just having fun today so i'll let you decide whether or not this is a good idea for your software but for right now i want to see what we can do so what i'm going to do is up here let's just pound define try and we'll just make it equal to if set jump save buff equal 0. so i'm just going to say any time i type try it's going to look like this so i can come down here and replace this code with try so that's looking more like a try catch block now we come back up here and we'll say let's define i'm gonna say catch all and just define that to be else okay since this is just gonna catch anything that that we throw so now i can do something like that right pretty straightforward we didn't really change anything and we still get the same behavior now it looks like a try catch block so that's a little nicer but what if we also wanted to be able to throw different kinds of things and catch different kinds of things because that's something that you get in other languages and so for this i'm not going to give a perfect solution but let me just give you an idea of where you could go with this if i wanted to be able to throw different things in this case let's just say we're throwing integers because that's simple we could get more complicated but let's just define an ex another global variable up here i'm going to call it exception value and it's going to start out as zero okay now what i'm going to do here is i'm going to change up my try block just a little bit and what we're going to do is set exception value to set jump here after so basically what this is going to do is this is going to remember what returned from set jump okay if it's equal to 0 we're still doing what we're doing but now i can come in here and let's make another catch and this one's going to catch a particular number so now if if we see this do an else block just like we had before but this time we're going to add an if here and we're just going to check to see if our exception value is num okay so that's gonna be great and i also forgot we're still doing long jump up here we don't have a throw so let's pound to find a throw as well and we'll throw a particular number in this case whenever we see this we will just say save buff and throw the number okay so these are just basically going to allow me to change some syntax here so instead of here we will just go throw one right so now we're throwing the integer one really we're just saving it and we're jumping back and then down here let's make another catch and let's say we catch let's catch five and we'll say i got error number five okay and just to test out this because currently we're not ever throwing a five let's come up here and just say just if we get all the way through we're going to throw five like i'll remove this later on but let's just say that's what we wanted to do and so now if we run this you notice we get our generic catch all our invalid inputs but then say i came up here and ran it with results now i'm getting i caught error 5 because that's what we threw so if i throw a five it's going to fall into that first catch block but anything else that i throw is going to fall into the last one and so this isn't a perfect solution but it's kind of cool i just wanted to show you that you can do this basically you can create try catch blocks in c if you're willing to do a little bit of preprocessor hackery and use set jump and long jump i hope this is helpful i hope it expands your mind gives you some ideas about what is possible in your programming let me know down in the comments if you find this useful how you put it to good use and of course if you have extensions improvements or things that you think i should have done better drop this video a like if you liked it subscribe to the channel if you want to make sure you don't miss the next one which should be out next tuesday i'm trying to get these out weekly these days and until the next video i'll see you all later
Info
Channel: Jacob Sorber
Views: 10,459
Rating: 4.9781423 out of 5
Keywords: try catch in c, try catch, exception handling in c, try catch exceptions in c, catch exceptions in c, c tutorial, c preprocessor, throw exception in c, try catch exception in c, throw catch exceptions in c, catch try in c, try in c, catch in c, c try catch, c exception handling, macro, programming tutorial, how to try catch in c, try catch c, hackery, setjmp, longjmp, setjmp function call, setjmp system call, Setjmp longjmp exceptions
Id: eQcRcgOnl9o
Channel Id: undefined
Length: 11min 12sec (672 seconds)
Published: Tue Mar 09 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.