C language and ways to inform about the results of actions

Question:

The topic is complex and extensive, and I really want to understand it properly, but there is little information in books, and it often turns out that real experience has little overlap with theory.

The C language has a huge number of ways to report the results of actions and errors. Now someone will throw a rotten vegetable at me, arguing that in C there are only primitive return codes.

Yes, only return codes… But they are used in very different ways.

Of course, it is possible to implement exceptions using setjmp / longjmp . But, as D. Ritchie said: If you need a PL/1, you know where to get it…

Here are the options for processing the results of execution that I see most often:

  1. The function returns a code that is a report of its work:

     const int r_code = some_func(a, b, c);
  2. Or, for example, the function returns a pointer to the created object, and if the object could not be created, the function returns NULL , without providing any additional information about the reason for the failure:

     object *obj = object_create(a, b, c);
  3. Also, the function can return a pointer to the created object, writing to the given location a detailed report of the operation (and not just additional information about the error):

     information i; object *obj = object_create(a, b, c, &i);
  4. Another function can use the global variable of the current thread to provide information about the error:

     FILE *f = fopen(a, b); if (f == NULL) { // Обработка errno()

And an almost infinite number of options…

When writing code, you often have to juggle different ways of handling errors and reporting the results of actions.

My questions:

  1. Is there a universal way in C for all this? And if not, what is the reason?

  2. It would be interesting to know what other approaches exist, what are their pros and cons?

  3. Is there a big difference in the complexity of developing/maintaining code that does/does not use exceptions? This is not about exceptions in C++ , but about exceptions in languages ​​with full garbage collection – ala Java .

For example, I wrote in Java for some time, and so, when I saw the real industrial code in which all possible exceptions were caught and checked, I didn’t understand at all how it could be supported and developed when there were 5 lines of library calls you have to write hundreds of try/catch/finally lines … And with any slightest edit, you have to dig up all the code in order to add support for exception handling, which did not exist before, somewhere in the 100500 error handling branch.

Answer:

I will try to answer, although it is very difficult, given who is asking and how.

Is there a universal way in C for all this? And if not, what is the reason?

There is no universal way. Not recommended for use. Why is that? everything is very simple – it's pure C. Here the programmer is responsible for his own code, no one will wipe his hands and mouth.

It would be interesting to know what other approaches exist, what are their pros and cons?

In principle, all the usual methods have been listed. There are several other methods

  • score on mistakes (very often used)
  • use a third-party framework (yes, there is such a thing for C. For example, cello ).

Is there a big difference in the complexity of developing/maintaining code that does/does not use exceptions? This is not about exceptions in C ++, but about exceptions in languages ​​with full garbage collection – ala Java.

Garbage collection has a very relative relationship with exceptions. And to make some conclusions from an initially incorrect assumption is fraught with strange conclusions. Therefore, they will not even discuss where exceptions or garbage collection are better. Let's leave that to the holivar experts.

But in Java, the exception specification is really a problem. You need to either constantly forward the entire list of valid exceptions, or write a basic one and not worry. In c++, they also tried to do this, but they refused in time (and made noexcept, which is more understandable).

When developing with exceptions, the most important thing is that it is difficult to allow a situation where the program has gone haywire. For example, one function initializes an object, and the second one uses it. If the first can return NULL, and the second does not expect this … then the error can be long and tedious to look for. With exceptions, this will have to be processed and the code will not go further (but anyway, the programmer must code it, it rarely happens right away and beautifully).

Scroll to Top