fclose(0)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Bartc

    fclose(0)

    This short program:

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

    int main(void) {
    int status;

    status=fclose(0 );

    printf("fclose( 0) status: %d\n",status);

    }

    crashes on the first two implementations I tried. Then I tried DMC and that
    gave the expected EOF status.

    Given the emphasis on error-checking in this group, it seems astonishing
    that a library function (executed at most once per file) cannot do this
    elementary check on it's parameter.

    (It's possible a zero FILE* handle is returned by fopen() but the file has
    to be closed for other reasons before it can checked by the application.)

    Was I unlucky or is it normal for C library functions to be so fragile?

    -- Bart


  • Richard Heathfield

    #2
    Re: fclose(0)

    Bartc said:
    This short program:
    >
    #include <stdio.h>
    #include <stdlib.h>
    >
    int main(void) {
    int status;
    >
    status=fclose(0 );
    >
    printf("fclose( 0) status: %d\n",status);
    >
    }
    >
    crashes on the first two implementations I tried.
    The Standard requires that you pass to fclose a pointer to a stream object
    of type FILE. You did not do this. (0 doesn't point to any object at all,
    let alone a stream object.) You broke the rules, so all bets are off.

    <snip>
    Given the emphasis on error-checking in this group, it seems astonishing
    that a library function (executed at most once per file) cannot do this
    elementary check on it's parameter.
    Well, of course it could, but it isn't obliged to. One of the ways an
    implementation can hand you astounding performance is to keep the
    error-checking down to an absolute minimum, trusting you to do any
    necessary checks yourself (because the alternative is to do the checks,
    even when *you* know they're not needed).
    Was I unlucky or is it normal for C library functions to be so fragile?
    C trusts you. Be worthy of that trust, or use a different language.

    --
    Richard Heathfield <http://www.cpax.org.uk >
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999

    Comment

    • santosh

      #3
      Re: fclose(0)

      Bartc wrote:
      This short program:
      >
      #include <stdio.h>
      #include <stdlib.h>
      >
      int main(void) {
      int status;
      >
      status=fclose(0 );
      >
      printf("fclose( 0) status: %d\n",status);
      >
      }
      >
      crashes on the first two implementations I tried. Then I tried DMC and
      that gave the expected EOF status.
      >
      Given the emphasis on error-checking in this group, it seems
      astonishing that a library function (executed at most once per file)
      cannot do this elementary check on it's parameter.
      >
      (It's possible a zero FILE* handle is returned by fopen() but the file
      has to be closed for other reasons before it can checked by the
      application.)
      >
      Was I unlucky or is it normal for C library functions to be so
      fragile?
      According to the standard fclose must return EOF if "errors were
      detected". However it says nothing about the range of possible errors.
      Is it an error if the operation fails to close a file with an otherwise
      perfectly valid FILE * parameter? According to the standard the answer
      is a clear yes. Is it also an error if the argument to fclose is an
      illegal or invalid pointer value? The standard doesn't explicitly
      address this issue, but I think the intent is to treat an illegal
      pointer value (basically NULL and other trap representations ) as a
      failure, and hence return EOF. OTOH an invalid pointer value cannot be
      detected by most implementations of fclose and I think it invokes
      undefined behaviour, whose result might be anything from a crash to
      returning EOF.

      So for the code in question I'd say that conforming compilers are
      allowed to do anything since the behaviour is undefined (not explicitly
      stated in the standard, but inferred) upon giving fclose an illegal
      argument. So it becomes a QoI issue and it seems that DigitalMars has
      the best behaviour of your test set.

      Comment

      • Richard

        #4
        Re: fclose(0)

        "Bartc" <bc@freeuk.comw rites:
        This short program:
        >
        #include <stdio.h>
        #include <stdlib.h>
        >
        int main(void) {
        int status;
        >
        status=fclose(0 );
        >
        printf("fclose( 0) status: %d\n",status);
        >
        }
        >
        crashes on the first two implementations I tried. Then I tried DMC and that
        gave the expected EOF status.
        >
        Given the emphasis on error-checking in this group, it seems
        astonishing
        that a library function (executed at most once per file) cannot do this
        elementary check on it's parameter.
        >
        (It's possible a zero FILE* handle is returned by fopen() but the file has
        to be closed for other reasons before it can checked by the
        application.)
        Error. Read the manual.
        >
        Was I unlucky or is it normal for C library functions to be so fragile?
        >
        -- Bart
        I like it when they crash. It means I dont have to check the return code
        for error conditions and my debugger tells me straightaway where it
        broke.

        Why would I want the libraries to cover up my sloppy mistakes?

        Excessive error checking to cover for lazy programmers might well add
        unnecessary overheads.

        Comment

        • Ben Bacarisse

          #5
          Re: fclose(0)

          "Bartc" <bc@freeuk.comw rites:
          This short program:
          >
          #include <stdio.h>
          #include <stdlib.h>
          >
          int main(void) {
          int status;
          >
          status=fclose(0 );
          >
          printf("fclose( 0) status: %d\n",status);
          >
          }
          >
          crashes on the first two implementations I tried. Then I tried DMC and that
          gave the expected EOF status.
          Not everyone will expect the same thing!
          Given the emphasis on error-checking in this group, it seems astonishing
          that a library function (executed at most once per file) cannot do this
          elementary check on it's parameter.
          Of course it can. The behaviour is undefined so it may check (or not
          check) anything it likes in this case. What has the emphasis of this
          group got to do with what a standard library function does?
          (It's possible a zero FILE* handle is returned by fopen() but the file has
          to be closed for other reasons before it can checked by the
          application.)
          Yes, I agree that it is annoying that one can't fclose the result of
          fopen (like one can free the result of malloc) but such is C.
          Was I unlucky or is it normal for C library functions to be so
          fragile?
          It's normal. Have you tried strlen(0), strcpy(0, 0) or fopen(0, 0)?
          Luck is another matter. In a way you were lucky that at least one
          implementation flagged up the call (with a crash). If you'd used one
          that just returns EOF (which is allowed), you'd have no warning that
          the construct is not portable.

          --
          Ben.

          Comment

          • Bartc

            #6
            Re: fclose(0)


            "Richard Heathfield" <rjh@see.sig.in validwrote in message
            news:dZCdnaOyg5 Rp247VnZ2dnUVZ8 uadnZ2d@bt.com. ..
            Bartc said:
            >
            >This short program:
            >>
            >#include <stdio.h>
            >#include <stdlib.h>
            >>
            >int main(void) {
            >int status;
            >>
            >status=fclose( 0);
            >>
            >printf("fclose (0) status: %d\n",status);
            >>
            >}
            >>
            >crashes on the first two implementations I tried.
            >
            The Standard requires that you pass to fclose a pointer to a stream object
            of type FILE. You did not do this. (0 doesn't point to any object at all,
            let alone a stream object.) You broke the rules, so all bets are off.
            fopen() returns a FILE* value, which can include NULL. So it's argueable
            that NULL (or (FILE*)NULL) is acceptable, type-wise, to fclose().
            >One of the ways an
            implementation can hand you astounding performance is to keep the
            error-checking down to an absolute minimum
            This is a /file/ operation. The cost of the check is negligible compared to
            the file processing time.
            C trusts you. Be worthy of that trust, or use a different language.
            I was. But I was interpreting it using a C program. I will have to put in
            extra checks for possible uses of NULL file handles that can crash C, to
            keep that other language robust.

            --
            Bartc


            Comment

            • Bartc

              #7
              Re: fclose(0)


              "Ben Bacarisse" <ben.usenet@bsb .me.ukwrote in message
              news:87d4oc7i1f .fsf@bsb.me.uk. ..
              "Bartc" <bc@freeuk.comw rites:
              >status=fclose( 0);
              >crashes on the first two implementations I tried. Then I tried DMC and
              >that
              >gave the expected EOF status.
              >
              Not everyone will expect the same thing!
              >
              >Given the emphasis on error-checking in this group, it seems astonishing
              >that a library function (executed at most once per file) cannot do this
              >elementary check on it's parameter.
              >
              Of course it can. The behaviour is undefined so it may check (or not
              check) anything it likes in this case. What has the emphasis of this
              group got to do with what a standard library function does?
              Something to do with setting an example?

              If a writer of a library function can't check a handle (for a common error
              like NULL, in a non-speed-critical function) why should anybody else?
              It's normal. Have you tried strlen(0), strcpy(0, 0) or fopen(0, 0)?
              I know about null string pointers. I'd prefer the library to be tolerant of
              them.
              Luck is another matter. In a way you were lucky that at least one
              implementation flagged up the call (with a crash). If you'd used one
              that just returns EOF (which is allowed), you'd have no warning that
              the construct is not portable.
              That's true. And if I did have a file that needed closing then fclose(0)
              returning EOF wouldn't tell me there was a problem (although I would find
              out in due course).

              But then, it may crash quietly.

              What's wrong with fclose() doing something like: "ABORTING: Invalid handle
              to fclose()".

              --
              Bartc


              Comment

              • Richard

                #8
                Re: fclose(0)

                "Bartc" <bc@freeuk.comw rites:
                "Ben Bacarisse" <ben.usenet@bsb .me.ukwrote in message
                news:87d4oc7i1f .fsf@bsb.me.uk. ..
                >"Bartc" <bc@freeuk.comw rites:
                >
                >>status=fclose (0);
                >
                >>crashes on the first two implementations I tried. Then I tried DMC and
                >>that
                >>gave the expected EOF status.
                >>
                >Not everyone will expect the same thing!
                >>
                >>Given the emphasis on error-checking in this group, it seems astonishing
                >>that a library function (executed at most once per file) cannot do this
                >>elementary check on it's parameter.
                >>
                >Of course it can. The behaviour is undefined so it may check (or not
                >check) anything it likes in this case. What has the emphasis of this
                >group got to do with what a standard library function does?
                >
                Something to do with setting an example?
                >
                If a writer of a library function can't check a handle (for a common error
                like NULL, in a non-speed-critical function) why should anybody else?
                Because it has a documented range of inputs. Why waste time? This is not
                ADA. It is C.

                Comment

                • Ben Bacarisse

                  #9
                  Re: fclose(0)

                  "Bartc" <bc@freeuk.comw rites:
                  "Ben Bacarisse" <ben.usenet@bsb .me.ukwrote in message
                  news:87d4oc7i1f .fsf@bsb.me.uk. ..
                  >"Bartc" <bc@freeuk.comw rites:
                  >
                  >>status=fclose (0);
                  >
                  >>crashes on the first two implementations I tried. Then I tried DMC and
                  >>that
                  >>gave the expected EOF status.
                  >>
                  >Not everyone will expect the same thing!
                  >>
                  >>Given the emphasis on error-checking in this group, it seems astonishing
                  >>that a library function (executed at most once per file) cannot do this
                  >>elementary check on it's parameter.
                  >>
                  >Of course it can. The behaviour is undefined so it may check (or not
                  >check) anything it likes in this case. What has the emphasis of this
                  >group got to do with what a standard library function does?
                  >
                  Something to do with setting an example?
                  I am confused as to which way round the example should be set. Maybe
                  you are surprised by how keen we are on error checking, given how lax
                  the library is? I don't know, but I don't think that is your main
                  point.

                  Anyway, I don't think there *is* an emphasis on functions checking their
                  input. There certainly is on checking the results, but that is not
                  the same. I think most regulars here will have caught the C bug of
                  doing rather minimal checking *in* a function. See, for example, the
                  recent posts about K&R solutions -- most of the examples posted ensure
                  that a function is called correctly and don't re-check inside.
                  If a writer of a library function can't check a handle (for a common error
                  like NULL, in a non-speed-critical function) why should anybody else?
                  >
                  >It's normal. Have you tried strlen(0), strcpy(0, 0) or fopen(0, 0)?
                  >
                  I know about null string pointers. I'd prefer the library to be tolerant of
                  them.
                  Then you'll have to write a set of wrappers.
                  >Luck is another matter. In a way you were lucky that at least one
                  >implementati on flagged up the call (with a crash). If you'd used one
                  >that just returns EOF (which is allowed), you'd have no warning that
                  >the construct is not portable.
                  >
                  That's true. And if I did have a file that needed closing then fclose(0)
                  returning EOF wouldn't tell me there was a problem (although I would find
                  out in due course).
                  >
                  But then, it may crash quietly.
                  >
                  What's wrong with fclose() doing something like: "ABORTING: Invalid handle
                  to fclose()".
                  Nothing, except that there is an assumption that the library does not
                  write error messages. I don't think it is forbidden, it is just not
                  expected (at least on the systems I am used to).

                  --
                  Ben.

                  Comment

                  • Default User

                    #10
                    Re: fclose(0)

                    Bartc wrote:

                    printf("fclose( 0) status: %d\n",status);
                    Was I unlucky or is it normal for C library functions to be so
                    fragile?

                    There is no defined behavior for Undefined Behavior.




                    Brian

                    Comment

                    • Antoninus Twink

                      #11
                      Re: fclose(0)

                      On 26 Apr 2008 at 15:06, Bartc wrote:
                      int status;
                      >
                      status=fclose(0 );
                      fclose takes a pointer argument, so this is the same as
                      status=fclose(N ULL);
                      which is obviously not a good idea.

                      [guess] Instead of fclose, did you mean close, which takes a file
                      descriptor as an argument? Are you wondering about whether it's OK to
                      close(0) (i.e. close the stdin stream)? If so, the answer is yes: it's
                      useful for piping data between parent and child processes. (You can use
                      dup() to bind the output of a pipe back to stdin.)

                      Comment

                      • Bartc

                        #12
                        Re: fclose(0)


                        "Antoninus Twink" <nospam@nospam. invalidwrote in message
                        news:slrng16njs .5i9.nospam@nos pam.invalid...
                        On 26 Apr 2008 at 15:06, Bartc wrote:
                        >int status;
                        >>
                        >status=fclose( 0);
                        >
                        fclose takes a pointer argument, so this is the same as
                        status=fclose(N ULL);
                        which is obviously not a good idea.
                        >
                        [guess] Instead of fclose, did you mean close, which takes a file
                        descriptor as an argument? Are you wondering about whether it's OK to
                        close(0) (i.e. close the stdin stream)? If so, the answer is yes: it's
                        useful for piping data between parent and child processes. (You can use
                        dup() to bind the output of a pipe back to stdin.)
                        No, it came up in something like:

                        f=fopen(...);
                        fclose(f);

                        where the fopen failed. I would just have expected fclose to do nothing
                        given a null file handle (as I tend to do in my own functions that use
                        handles).

                        No big deal, I already use wrappers and it's a one-line fix. Was just mildly
                        surprised that that one line isn't already there.

                        --
                        Bartc


                        Comment

                        • Ben Pfaff

                          #13
                          Re: fclose(0)

                          "Bartc" <bc@freeuk.comw rites:
                          status=fclose(0 );
                          This yields undefined behavior. Are you thinking of
                          fflush(NULL), which is well-defined?
                          --
                          "Given that computing power increases exponentially with time,
                          algorithms with exponential or better O-notations
                          are actually linear with a large constant."
                          --Mike Lee

                          Comment

                          • Richard Heathfield

                            #14
                            Re: fclose(0)

                            Bartc said:
                            >
                            "Richard Heathfield" <rjh@see.sig.in validwrote in message
                            news:dZCdnaOyg5 Rp247VnZ2dnUVZ8 uadnZ2d@bt.com. ..
                            >Bartc said:
                            >>
                            >>This short program:
                            >>>
                            >>#include <stdio.h>
                            >>#include <stdlib.h>
                            >>>
                            >>int main(void) {
                            >>int status;
                            >>>
                            >>status=fclose (0);
                            >>>
                            >>printf("fclos e(0) status: %d\n",status);
                            >>>
                            >>}
                            >>>
                            >>crashes on the first two implementations I tried.
                            >>
                            >The Standard requires that you pass to fclose a pointer to a stream
                            >object of type FILE. You did not do this. (0 doesn't point to any object
                            >at all, let alone a stream object.) You broke the rules, so all bets are
                            >off.
                            >
                            fopen() returns a FILE* value, which can include NULL. So it's argueable
                            that NULL (or (FILE*)NULL) is acceptable, type-wise, to fclose().
                            No, it isn't, because the Standard doesn't say so. The Standard says that,
                            if you call fclose, you must pass to it a pointer to a stream object of
                            type FILE that has a file associated with it. You didn't do this.

                            <snip>

                            --
                            Richard Heathfield <http://www.cpax.org.uk >
                            Email: -http://www. +rjh@
                            Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
                            "Usenet is a strange place" - dmr 29 July 1999

                            Comment

                            • Keith Thompson

                              #15
                              Re: fclose(0)

                              "Bartc" <bc@freeuk.comw rites:
                              [...]
                              >On 26 Apr 2008 at 15:06, Bartc wrote:
                              >>int status;
                              >>>
                              >>status=fclose (0);
                              [...]
                              >
                              No, it came up in something like:
                              >
                              f=fopen(...);
                              fclose(f);
                              >
                              where the fopen failed. I would just have expected fclose to do nothing
                              given a null file handle (as I tend to do in my own functions that use
                              handles).
                              In that case, it's probably just as easy to avoid calling fclose if
                              the fopen failed than to call it. You have to test whether fopen
                              succeeded anyway; if it doesn't, you don't attempt to read any input
                              from the file, right? So you have to do something like this:

                              f = fopen(...);
                              if (f != NULL) {
                              fread(...);
                              fclose(...);
                              }
                              else {
                              /* Report that you couldn't open the file */
                              }
                              No big deal, I already use wrappers and it's a one-line fix. Was just mildly
                              surprised that that one line isn't already there.
                              Yeah, most standard libary functions don't check for invalid input.
                              free(NULL) is a rare exception.

                              Note that, in the case of fclose(), checking for a null pointer
                              argument would just handle one failure case. There are plenty of
                              other errors that can't reasonably be caught, such as calling fclose()
                              with an uninitialized pointer.

                              --
                              Keith Thompson (The_Other_Keit h) <kst-u@mib.org>
                              Nokia
                              "We must do something. This is something. Therefore, we must do this."
                              -- Antony Jay and Jonathan Lynn, "Yes Minister"

                              Comment

                              Working...