Error handling is one of the most important things you need to do in order to write good production level C code You can get the sysinternals suite from the Windows Store or with winget package manager.
Your video is GREAT! I would only comment that it would be preferable to print to stderr instead of stdout (printf), for critical errors that terminate the application. So, you should use fprintf(stderr, ...) instead. The main reason for this, is that different redirection is typically done for stderr and stdout - the user might want to handle error messages differently from the informational messages.
I've felt the lack of a separate error channel because I thought "just put everything into stdout, so much easier!" in a project: * the stdout quickly became unreadable and broke formatting * it also broke the REPL which was using stdin/out => errors needed special integration to be readable so "just put errors into stderr, so much easier!" :))
Great video! this is actually a big issue i certainly had in my first few c programs before i had enough experience to know better. One thing to note is the perror function. If you call perror, not only will it print to stderr (always print to stderr instead of stdout for errors), but it will also give you a description of the error number encountered. (the same text from the errno command)
I really appreciate your focus on important and interesting information. There is no unnecessary spam and begging for likes and subscriptions. I immediately liked and subscribed 8-)
Thanks for presenting this. One of the things that always botherd me is progaming books that say they are leaving out the error checking to simplify the code for understanding, which it does, was that they often leave out a section on proper error checking and handling. When I first taught myself programming, I did a lot of research and reading (before the internet). I didn't fully trust anything and made sure that if my program failed it didn't crash the system, barring a system/hardware failure. Then modern systems like Windows came out and all bets were off. I could still write good code, but now I was more dependent on the Windowing system to not introduce errors, like memory leaks that forced me to write work arounds.
Instead of calling gcc or clang directly, you can call 'make prog' and it will compile prog.c using environment variables CFLAGS LDFLAGS and LDLIBS. No Makefile required. You can see exactly the calls make will use with 'make -p'. One benefit is no a.out, and it's usually less typing.
@@erc0re526 In the opening paragraph of OpenBSD's make(1) man page, it says, " If neither of these exist, make can still rely on a set of built-in system rules." One of the many reasons I like OpenBSD is the quality of its documentation. Notably, GNU make has the same behavior but their manpage incorrectly states that "you must write a file called the makefile".
Check everything unless you know for a fact it can't fail and even then you may want to check. If you're not sure about something, look it up and verify. I self taught myself in the late 80's and early 90's and always double checked everything. Return values are there for a reason. Programmer's mantra: Trust but Verify.
I didn't even know there was an errno program. I thought maybe you wrote it yourself but looked it up and found it in moreutils. I'll have to recommend this to anyone learning C.
Be interesting to do a retake of this using zig, as it’s a good demo of how zig applies error handling to existing C idioms, without adding a tonne of boilerplate or weird abstractions. The error backtrace is particularly handy as well.
That is a cool tip, thanks! Just notice that it opens on full screen and so if you want to open the manual in split screen you can either use the :term like I do in the video or the :Man vim command which opens the manual as a Vim buffer
@@nirlichtman Yeah, forgot that it takes over the entire screen by default 😅I use neovim which opens the man page in a split window which I assume it's not impossible to do in vim.
These days, rather than prototyping without error handling I lean into explicitly terminating the program. void _panic(int line) { printf("PANIC: %d ", line); exit(-1); } #define panic _panic(__LINE__) This helps with finding problems early without littering the program with boilerplate, and later it's useful for identifying places that I may want to add additional error handling logic. As a side bonus, it's also an active deterrant against internalizing an active ignorance of error handling. With how much time I spend prototyping, it's foolish to think it will be easy to mode-switch out of the habits I develop while prototyping.
instead of initializing the whole buffer with zeros you can set the last char of it to zero: #define BUF_LEN 256; char buffer[BUF_LEN]; buffer[BUF_LEN - 1] = '\0'; thanks for your content!
Then your buffer is filled with garbage (former stack data) except the last char. You merely ensure that if an un-initialized char buffer is used, it will stop at the end at least. I wouldn't recommend this technique unless CPU time is so critical that "whatever = {0};" is too expensive
@@eitantal726 I agree with Eitan on this point, it is a good practice to always ensure that you are working with all zeroed buffers or else it can lead to weird bugs
Then there's code that lumps all errors together. Disk full? Read-only filesystem? Out of memory? File not found? User value out of range? All the same error reported to the user!
@@nirlichtman I don't get it why people are still using Linux as their main OS (And saying that it is better than Windows)? Let me explain my point of view (Related to Ubuntu mostly): 1. Linux OS is asking for the password every once in a while, approx. 100 times a day, wasting a bunch of time. If you're not lucky, Linux can't detect even the right password Isn't it archaic and stupid? 2. Linux isn't compatible with many software programs and drivers 3. It is a command base OS - you have endless shortcuts and commands which are impossible to remember 4. End of life after couple of years, which requires you to install a new version 5. GUI in Windows is extremely better I'm embedded developer, so I am using Linux only because I have to, but for my daily use, I'm happy with Windows
@@Jonathan-ru9zl Yah my main reasons for preferring Windows as my main OS is the compatilibilty and that I like the user interface and am very familiar with it, and now that there is WSL there is not really a reason for me to switch to Linux, but i like using Linux distros for server side since they mostly have low hardware requirements and are comfortable for those kind of stuff
Hi Nir, I watched most of your videos and I liked your projects very much. So I want to learn how do you improved yourself so much in low-level programming.
Thanks! What helped me the most with learning low level is to make my own projects and play around with various linux/windows api calls, for example one of my projects was a c++ web server that stored messages that i sent it, another thing that helped me was to contribute to open source projects which is a great way to learn how to work with a lot of existing code and to use the debugger effectively.
@@Abhishek-pp8ck the best way to learn in my opinion is to make your own projects in c and work with the man pages alongside to learn about the os functions, for example an idea for a networking project in c can be a web server and client, or maybe an online simple game, for a general guide on networking i remember beejs guide to networking as good
For a immediately C coder like me, it's a great topic to incorporate error handling the correct C way. And a big thanks for not using music and not using disturbing video editing. May I ask, why you kind of do advertising for a Chinese brand?
Are you referring to my hostname with "lenovo" in it? that is not part of any advertising on purpose, it's my laptops name for many years, but indeed it is a good idea now to change the name didn't think about this, thanks for the feedback :)
@@nirlichtman Yes I am and just what i thought. Now retired reseller and had installed thousands of Windows computers, by wiped out everything on the hard drive. I just installed a clean system and minimum of drivers. Now it's Linux Mint LMDE and C programming with Code::Blocks. Keep up the great work.
Before I get into this, shouldn’t main return an integer? Also I see you dereferencing the “strrchr” function, but I didn’t even know that was possible. Can anyone explain if this is valid C?
You're correct. When I have time I'll compare the assembly and see what or IF the compiler does anything differently. This is why C is so insane... Why not just throw a 'this is wrong learn C' error? No the compiler just does 'something '.... Smh
Actually, returning void from main is completely valid C :) According to the documentation, since C99 the main entry point can return void and this means the program exit code is undefined devdocs.io/c/language/main_function About the deref of strchr, it also valid C, but as I explain later in the video, it is recommended to check if it failed before derefing it
@@Not_Even_Wrong Fair enough, I'm mainly a Windows programmer, so seeing how "void main" is legal confused me a bit. After a minute of research, a lot of the C++ people hate the idea of "void main", and require programmers to use "int main" instead.
@@nirlichtman okay it's valid in the sense that unspecified in C means implementation defined. It can always return 0 or 1 or whater BUT the compiler has to decide. In contrast to undefined which means nobody has to decide... This is the part of C that I don't like... Thanks for replying either way. Taught me once again to not trust stackoverflow...
Another good example is yohttps srrver video, after the ser er has been used once (at leadt for me) bind() will fail the next time with return code - 1. I dobt want to blame you , this might be a problem with my wsl setup. But without debug printing the return values, i would have never kniwn that bind was the reason the server only works sometimes
Your comment on that vid was indeed one of my inspirations for making this video :) Bind indeed can fail sometimes if you run it again on the same port not long after the previous run has finished (my guess is that it is due to some OS used ports cleanup that has not happened yet)
I have a quick question. Why do you use the windows terminal, or at least riced some other terminal to look like the window's one, on linux? Is it just for the laughs?
You can get the dev man pages with your package manager, if you are using Debian/Ubuntu you can run apt install manpages-dev, more info about my setup in the channel description link
Why are you printing the errno with printf? Use `perror(3)`. It will print the error string to stderr (which is what you should be doing), so you don't have to use errno on the command line. This is better for users and better for logging.
The Importance of Error Handling in C: I have expected some ideas of sophisticated error handling in C and I found just a basic of the return value handling as on first page of the C language tutorial. 👎
FAKE TUTORIAL: At 2:27 if you stop the video and microstep back and forth (with dot and comma) you can spot the compile error he didn't want us to see.
Actually, the tutorial is completely real - that is a compiler warning, not an error (the warning is related to the address structure - this is not related to the point of the video anyway) and I am completely fine with you seeing it, it appears for more than a microstep no need for dot and comma.