From my experience, the error handling in C is one of the few cases, where the goto statement is useful. It can just go to the end of the function scope and fall through, thus freeing all the so far allocated memory in a stack based manner.
@James you're not just going to exit the function. You are going to the end of it where you have the deallocation necessary. If something hasn't been allocated yet, you just goto a label below its deallocation
Subscribed! Notifications to ALL. Mid-corona lockdown, I have set to the task of learning C (go figure, I'm a developer that did'nt get to have C in school...) so this is usefull (and that is an understatement)...lemme have more of this :)
3:35 to 3:47 that's now clear my doubts of why errno is stored and why it's value differ ..in every time before or after function call like opening files or other. That's really amazing and helpful I was in doubts and confusion about it
It's generally a good idea to send error messages to stderr instead of stdout. It's just convention, but it makes your programs easier to use if we separate the output. Otherwise, printf works just fine.
Great video, thanks for all this work! I got a question: You mention that macros give you the line number and file name, while a functions give you safety (and a cleaner syntax). This makes me think that you can write an error-handling function (say, check_func(int val, int lineno, char *filename)), but instead of calling it directly, use a macro (the macro expands to a call to check_func while adding the line number and file name). Not sure whether that is a good idea...
Beginner students ignore the internal manual because they have videos like this or the all mighty stack overflow. They are more direct and to the exact point. I guess the next thing is to ask if that is a bad thing. Also, you were right about the common pronunciation of errno. But if you were to teach it to students, maybe say error number for clarity.
I don't think using videos and stack overflow is a bad thing. I would want to use those AND the man pages. The manual pages definitely don't feel super friendly to the uninitiated. But, once you get used to how they are structured, I can usually find most answers more quickly with the man pages than I can with a browser, and I don't need a network connection.
as a beginner programmer I felt like this video showed me some good/common practices (such as the use of this specific macro) that I can now implement into my code that I might not have gotten from just the man pages. If you have any resources other than videos that help show common practices in action dm me plz
@@JacobSorber I would phrase it as the beginner uses stack-overflow and RUclips, the seasoned professional uses man pages. Always good to introduce professional habits early. Eventually you might be at a job site and need a quick reference and hitting RUclips from the company hardware may be a negative.
1. errno is a C standard thing. It is NOT specific to unix. For instance most (all?) file opening functions on Windows set errno. 2. errno may be set to a value even when the function failing does not invoke a system call (strtol for instance).
what I dont understand is why they use a negative one do indicte a failure. From working with linux and bash and so on, usually the canonical failure code is 1 and not -1.
The exit call will terminate the program. Depending on the operating system, it will terminate the process, close open files, free allocated memory, etc. -- but it depends on the operating system. Some embedded operating systems may be less forgiving. Additionally, there may be some things (shared memory structures?) that the operating system won't know to clean up. Good practice would be to always clean up after yourself -- and this might have to be part of your design from the beginning so that you don't have a function call 15-deep that can terminate the program (you might also consider looking at on_exit if that's an issue from inherited code).
It means that this part of conditional expresion runs some code and returns -1, it does nothing in this particular macro since it doesn' t assign value to variable. Try this to see how it works: int a = 3; a = (a == 3) ? ({printf("true ");1;}) : ({printf("false ");0;}); printf("a: %d ", a);
does this mean in multithreaded .. i cannot check errorno unless i encapsulate the sys call function inside a critical section ... because maybe other thread will call another syscall and change the error no before i handle it ?
From the man page for errno: _errno_ is defined by the ISO C standard to be a modifiable lvalue of type _int_ , and must not be explicitly declared; _errno_ may be a macro. _errno_ is thread-local; setting it in one thread does not affect its value in any other thread.
It sounds like you're trying to match this video up to some specific requirement (maybe for a school assignment?). In any case, the question is vague enough that I'm not sure how to answer. When I think about "exceptions", I'm typically thinking about illegal instructions (bad code or trying to execute data that isn't code), illegal memory accesses (bad pointer dereferences, usually), or arithmetic problems (divide by zero, overflow)-not so much error codes returned from any library call. But, these terms aren't super specific. If it's for an assignment, I don't know what your instructor expects or counts as an illegal exception.
3:41: "So one morning, ERRNO is set by a lot of different calls..." Yes I know it's _one warning,_ but I prefer the fairy tale version better and I want to hear the rest of it. Any takers?
Ah, that's funny. Editing glitch, of course. I'll try to remember what story I was about to tell about ERRNO going on an epic adventure and weave it into a future video. 😀
I almost always modify the play back speed of videos on RUclips (under the gear icon). The only real problem I've hit with that is shifting from watching on RUclips to interacting with people in real-life.
Not all operating systems use -1 (or 0 or pick your favorite constant) to indicate an error on exit. EXIT_SUCCESS and EXIT_FAILURE should be used (they're defined in stdlib.h) #include int main(int argc, char* argv[]) { if (argc < 2) exit(EXIT_FAILURE); exit(EXIT_SUCCESS); }
All operating systems support 0, but not all operating systems support -1. To quote C99/N1256 7.20.4.1 paragraph 5, emphasis mine: "If the value of status is *zero* or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned."
@@marbens If I remember correctly, Digital's VMS operating system used odd/even to represent success/failure (and it's been long enough, I don't remember if even was success or failure). I remember reading through the JPEG code one time and they had a #ifdef around exit codes with comments whining about VMS "not being standard" (since the developer didn't use EXIT_SUCCESS and EXIT_FAILURE). VMS predates C99 by a number of years.
Please Jacob do a series of design patterns in C.
This please!
That was super helpful and entertaining! :)
It also replaced my bedtime story since I’m about to sleep. Cheers!
From my experience, the error handling in C is one of the few cases, where the goto statement is useful. It can just go to the end of the function scope and fall through, thus freeing all the so far allocated memory in a stack based manner.
@James you're not just going to exit the function. You are going to the end of it where you have the deallocation necessary. If something hasn't been allocated yet, you just goto a label below its deallocation
One interesting feature that I learned very recently is that you can use the %m formatter when using printf in replacement for %s plus strerror
GNU extension.
these are super helpful
Thanks.
Subscribed! Notifications to ALL. Mid-corona lockdown, I have set to the task of learning C (go figure, I'm a developer that did'nt get to have C in school...) so this is usefull (and that is an understatement)...lemme have more of this :)
3:35 to 3:47 that's now clear my doubts of why errno is stored and why it's value differ ..in every time before or after function call like opening files or other.
That's really amazing and helpful I was in doubts and confusion about it
Glad I could help.
great vid, very helpful.
just a question:
is there a reason to prefer fprint over printf?
It's generally a good idea to send error messages to stderr instead of stdout. It's just convention, but it makes your programs easier to use if we separate the output. Otherwise, printf works just fine.
in fprintf you can specify to which stream you want to output format text. printf simply writes to stdout.
stdout is buffered so there can be some inconsistencies in output
stderr isn’t buffered so as soon as printf is called it will write to the screen
great video , makes hard subjects easy to understand !
Great video, thanks for all this work!
I got a question:
You mention that macros give you the line number and file name, while a functions give you safety (and a cleaner syntax).
This makes me think that you can write an error-handling function (say, check_func(int val, int lineno, char *filename)), but instead of calling it directly, use a macro (the macro expands to a call to check_func while adding the line number and file name).
Not sure whether that is a good idea...
Beginner students ignore the internal manual because they have videos like this or the all mighty stack overflow. They are more direct and to the exact point.
I guess the next thing is to ask if that is a bad thing.
Also, you were right about the common pronunciation of errno. But if you were to teach it to students, maybe say error number for clarity.
I don't think using videos and stack overflow is a bad thing. I would want to use those AND the man pages. The manual pages definitely don't feel super friendly to the uninitiated. But, once you get used to how they are structured, I can usually find most answers more quickly with the man pages than I can with a browser, and I don't need a network connection.
as a beginner programmer I felt like this video showed me some good/common practices (such as the use of this specific macro) that I can now implement into my code that I might not have gotten from just the man pages. If you have any resources other than videos that help show common practices in action dm me plz
@@JacobSorber I would phrase it as the beginner uses stack-overflow and RUclips, the seasoned professional uses man pages. Always good to introduce professional habits early. Eventually you might be at a job site and need a quick reference and hitting RUclips from the company hardware may be a negative.
Your videos are great, please keep it up
1. errno is a C standard thing. It is NOT specific to unix. For instance most (all?) file opening functions on Windows set errno.
2. errno may be set to a value even when the function failing does not invoke a system call (strtol for instance).
Love your videos
Thanks.
amazing video! thank you so much
Great quality videos!!
Really good video
exceptional as always ;) 🙌
Thank you so very much for your informative post!!!!!
It helped a lot, thank you!
Thanks
Amazing, love from India...
is writing macro better then writing function? Thanks.
what I dont understand is why they use a negative one do indicte a failure. From working with linux and bash and so on, usually the canonical failure code is 1 and not -1.
very helpful! thank you!
You're welcome!
I have problem with memory layout in c and how c get interpreted into assembly and interted into memory
When using exit(-1), shouldn't free all the dynamically allocated stuff that you previously have outside the failing function call?
The exit call will terminate the program. Depending on the operating system, it will terminate the process, close open files, free allocated memory, etc. -- but it depends on the operating system. Some embedded operating systems may be less forgiving. Additionally, there may be some things (shared memory structures?) that the operating system won't know to clean up. Good practice would be to always clean up after yourself -- and this might have to be part of your design from the beginning so that you don't have a function call 15-deep that can terminate the program (you might also consider looking at on_exit if that's an issue from inherited code).
@@papasmurf9146 on embedded systems exit() makes no sense.
That's why it doesn't matter what to do in exit()
What is the -1; after exit(-1); for?
It means that this part of conditional expresion runs some code and returns -1, it does nothing in this particular macro since it doesn' t assign value to variable.
Try this to see how it works:
int a = 3;
a = (a == 3) ? ({printf("true
");1;}) : ({printf("false
");0;});
printf("a: %d
", a);
Clang?
You forgot to use the macro on fputc().
awesome!!!
Is it preferable to use assert instead of the macro?
I don't think so. Assertions are only for debugging, not for control flow / error handling. They're usually even turned off for release builds.
Assert calls abort() in stead of exit()?
does this mean in multithreaded .. i cannot check errorno unless i encapsulate the sys call function inside a critical section ... because maybe other thread will call another syscall and change the error no before i handle it ?
From the man page for errno:
_errno_ is defined by the ISO C standard to be a modifiable lvalue of type _int_ , and must not be explicitly declared; _errno_ may be a macro.
_errno_ is thread-local; setting it in one thread does not affect its value in any other thread.
error is returned from system call posix that why c language is the best language for OS
can you help me with something?
Can I use this code as an "C program to generate illegal exception in UNIX"
It sounds like you're trying to match this video up to some specific requirement (maybe for a school assignment?). In any case, the question is vague enough that I'm not sure how to answer. When I think about "exceptions", I'm typically thinking about illegal instructions (bad code or trying to execute data that isn't code), illegal memory accesses (bad pointer dereferences, usually), or arithmetic problems (divide by zero, overflow)-not so much error codes returned from any library call. But, these terms aren't super specific. If it's for an assignment, I don't know what your instructor expects or counts as an illegal exception.
I'm glad that you replied...
Thank you for your concern...
Well I'm searching for a college assignment...
That's true
3:41: "So one morning, ERRNO is set by a lot of different calls..."
Yes I know it's _one warning,_ but I prefer the fairy tale version better and I want to hear the rest of it. Any takers?
Ah, that's funny. Editing glitch, of course. I'll try to remember what story I was about to tell about ERRNO going on an epic adventure and weave it into a future video. 😀
@@JacobSorber If you enjoy this sort of thing, google misheard lyrics or mondegreens.
too fast, slow down
I almost always modify the play back speed of videos on RUclips (under the gear icon). The only real problem I've hit with that is shifting from watching on RUclips to interacting with people in real-life.
slow down
Not all operating systems use -1 (or 0 or pick your favorite constant) to indicate an error on exit. EXIT_SUCCESS and EXIT_FAILURE should be used (they're defined in stdlib.h)
#include
int main(int argc, char* argv[])
{
if (argc < 2)
exit(EXIT_FAILURE);
exit(EXIT_SUCCESS);
}
All operating systems support 0, but not all operating systems support -1. To quote C99/N1256 7.20.4.1 paragraph 5, emphasis mine:
"If the value of status is *zero* or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned."
@@marbens If I remember correctly, Digital's VMS operating system used odd/even to represent success/failure (and it's been long enough, I don't remember if even was success or failure).
I remember reading through the JPEG code one time and they had a #ifdef around exit codes with comments whining about VMS "not being standard" (since the developer didn't use EXIT_SUCCESS and EXIT_FAILURE).
VMS predates C99 by a number of years.