3

Is there a preferable way to report errors in C? For example if a file that is supposed to be opened does not exist, should I use

if( fp == NULL ) 
{
      perror("Error: ");
      return(-1);
}

(copied from http://www.tutorialspoint.com/c_standard_library/c_function_perror.htm )

or

if( fp == NULL ) 
{
      fprintf(stderr, "Unable to open file for reading.\n");
      return(-1);
}
Suzanka
  • 127
  • 2
  • 9
  • 3
    Use `exit(EXIT_FAILURE);` instead of `return -1;`, IMO `perror` is preferable (you get more information about the error), but use `perror("fopen")` instead of `perror("Error: ");` – David Ranieri Feb 24 '16 at 08:47
  • 1
    It's up to you. There is no prefered way. With `fprintf` you are in total control of what will be displayed. [`perror`](http://www.cplusplus.com/reference/cstdio/perror/) is platform dependant and takes into account the `errno` variable. – Jabberwocky Feb 24 '16 at 08:53
  • You should print both errno and strerror(errno), but keep in mind that errno is volatile, so it's a good idea to save it into an own variable. (Note: nowadays errno isn't actually a variable, it is sg like this: `#define errno (*_Errno())` or `#define errno (*__errno_location ())` -- that's because of threads) – Lorinczy Zsigmond Feb 24 '16 at 17:11
  • Thank you all. Sounds like `errno` is a useful way to handle errors. – Suzanka Feb 25 '16 at 18:57
  • 1
    Possible duplicate of [When should I use perror("...") and fprintf(stderr, "...")?](http://stackoverflow.com/questions/12102332/when-should-i-use-perror-and-fprintfstderr) – Mogsdad Mar 11 '16 at 18:33

2 Answers2

2

You can use perror() or strerror to get the error message. If you want to postpone the display of error message or if you want to log the message to a file, then save the errno and use strerror() because perror only writes to the standard error stream and it uses the global errno set and the errno might change any time if any library function is called before printing the error message.

Example using saved errno:

int savederrno;
....
if( fp == NULL ) 
{
  savederrno = errno; /* Save the errno immediately after an api/lib function or a system call */
  /*If you want to write to a log file now, write here using strerror and other library calls */
}

....
/* use strerror function to get the error message and write to log
    or write to std error etc*/

The following man pages explain the error reporting in detail.

http://www.gnu.org/software/libc/manual/html_node/Error-Messages.html http://man7.org/linux/man-pages/man3/errno.3.html

Umamahesh P
  • 1,224
  • 10
  • 14
  • 1
    Information in the link is wrong. 1. strerror requires string.h 2. no need to extern int errno when errno.h is included 3. it prints the error to stdout 4. it returns 0 on error –  Feb 24 '16 at 11:55
  • Thanks for the feedback. I have removed the link and added a new link from IBM developer works. – Umamahesh P Feb 24 '16 at 14:04
  • This resource is also defective, although I have not read the entire page to asses it entirely. See the program au-errnoDemo.zip. 1. abuse of full-caps name for something which is not a macro 2. predictable name for a /tmp file 3. missing headers for open 4. the 3rd parameter is meaningless wthout O_CREAT 5. error printed to stdout 6. errno not saved before perror, contradicting your own advice. –  Feb 24 '16 at 16:35
  • Thanks. I have replaced the link with Linux and gnu man page URLs. The pages explain the need to save the errno, when extern int errno needs to be declared etc. – Umamahesh P Feb 25 '16 at 01:09
0

tutorialspoint.com is extremely terrible (at least when it comes to C) and as such must not be used. The standard resource to learn from is "The C Programming Language, 2nd edition" by Kernighan and Ritchie.

The preferred way to report stuff is to include the failing function in the message and use perror, e.g. perror("open")

EDIT: originally this did not include any justification for the claim about the site. I did not feel like it is necessary nor sensible. There is no write up I could link to either. They key was to avoid the site and everyone interested can easily conclude material in there is questionable at best and straight up wrong at worst.

However, since I got a weird backlash here are some excerpts:

http://www.tutorialspoint.com/c_standard_library/c_function_malloc.htm

#include <stdio.h>
#include <stdlib.h>

Missing include for strcpy and strcat.

int main()
{
   char *str;

   /* Initial memory allocation */
   str = (char *) malloc(15);

No need to cast malloc. Missing null-check. Why the 15?

   strcpy(str, "tutorialspoint");

Bad error-inducing style. What if the length was to change? If an explicit allocation really needs to happen, strlen() + 1 can be used to get the needed size.

   printf("String = %s,  Address = %u\n", str, str);

'u' is an incorrect specifier for pointer type.

   /* Reallocating memory */
   str = (char *) realloc(str, 25);

Standard bad idiom. The code should use a temporary pointer to recover from error, or if recovery is not an option, exit.

   strcat(str, ".com");

What's up with realloc from 15 to 25 just to add ".com"?

   printf("String = %s,  Address = %u\n", str, str);

   free(str);

   return(0);
}

Does this justify my claim about the site?

  • 5
    Thats a purely opinion based answer. – Magisch Feb 24 '16 at 08:51
  • Care to elaborate? Whether to use perror or something else, and what to use perror with is mostly a manner of style, although most software does exactly what I described. As for tutorialspoint.com, I suggest you check it out before you downvote my answer. –  Feb 24 '16 at 08:53
  • "Mostly manner of style" "Is just terrible" "as such must not be used" "Preferred way" thats all your opinion, and the arguments to justify it are lacking in your answer. – Magisch Feb 24 '16 at 08:54
  • Why are you mixing the opinion about the site with the opinion on perror usage? While one can arguably refrain from commenting about the site (why?), there is no way to say anything about perror which would not be an opinion. –  Feb 24 '16 at 09:15
  • Thats a case of a "Primarily opinion based" question here which should be closed. You've hit the nail on the head. If its not factually answerable, you shouldn't answer it. – Magisch Feb 24 '16 at 09:21
  • The question seems perfectly reasonable. But if it is not, why don't you explain this to OP and redirect them to a place where it can be asked? –  Feb 24 '16 at 09:24
  • You cannot just say no to a site, it might be useful to someone. -1, because this is spam. The definition of spam is to promote a service, but doing the opposite is as bad as promoting a service. – Box Box Box Box Feb 24 '16 at 09:25
  • Also, I have been using that site for a long time. It is your opinion that it is not good, and I am not telling you to be a fan of it. I am telling you not to make an anti-recommendation, as that is off-topic for SO. It is opinion-based as @Magisch said. – Box Box Box Box Feb 24 '16 at 09:28
  • So what exactly is one supposed to do when a newbie provides a link to a defective resource? Just ignore it? Especially with a language like C it is extremely crucial to have a good resource to learn from. –  Feb 24 '16 at 09:46
  • When a nebie provide a link to a defective source, just say that it is wrong. Many pages on that website are good, and it might be possible that this one isn't. But what you're saying tells that all pages on that website are bad, worst, and defective. I cannot understand how you have managed to visit all the pages of that website, it has thousands. And if you haven't, saying that it is worst is wrong. Some page might be useful. – Box Box Box Box Feb 24 '16 at 09:56
  • 2
    Give the pages I have seen (example above), this does not look like a resource which can be trusted with content related to the C programming language. Even if some pages happen to be correct, I don't see why would anyone use this site in the first place. How could you tell the difference as a newbie? So what else is to do than to discourage the use of the site? –  Feb 24 '16 at 10:00
  • 1
    Had OP omitted his mention of that specific site you so despise (and I don't know in order to verify its despicability), all that'd be left of your post would be *one* sentence: "The preferred way... [etc]". So yeah. The rest of this answer is pretty much an opinionated rant. – Linus Kleen Feb 24 '16 at 18:38
  • You did not address the reason for the rant, which was also expressed as a question in my last comment. Let me repeat then. A newbie posts a link to a resource I consider defective. Given how hard it is to learn C, it is crucial to have correct resources and OP does not. Unfortunately there is no page pointing out mistakes on tutorialspoint I could link to. What was I supposed to do then? I only stated the site is wrong and in an edit provided an example with blatant errors. You are not advocating for leaving it as it is, are you? If not, what else should have been done here? –  Feb 24 '16 at 19:01
  • Really. I understand your motivation. I totally do. In golden times past, people would say "I got this code from w3schools and it doesn't do what I want". Same here. While I'm *totally* on your side about the invalidity of the code samples on that other site, all your answer does is (possibly rightly so) discourage use of that site and defend *your* opinion why it should be avoided. But it doesn't *answer* OP's question. The *reason* for your rant may be totally valid but is misplaced here as an answer to someone else's question which wasn't "is site A's example better than site B's example." – Linus Kleen Feb 24 '16 at 19:38
  • I did answer the question (I said to use perror with the failing function name as an argument) and it is in line with the most upvoted comment. But even if I did not, OP says they are learning (at least in part) from what I consider a bad resource, so what should I do now? While not explicitly stated by your comment, it seems you are arguing it should be ignored and I cannot agree with such approach. Say one documented more atrocities from that site. Would linking to such a page be considered fine here? –  Feb 24 '16 at 20:02