fclose(0)

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

    #16
    Re: fclose(0)

    Bartc wrote:
    "Richard Heathfield" <rjh@see.sig.in validwrote
    >>
    >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().
    The type is acceptable, but the value is not. Would
    you expect `fprintf (NULL, "Hello, world!\n");' to work?
    How about `fprintf (NULL, NULL);'?

    The relevant passage is Section 7.1.4 paragraph 1:

    "Each of the following statements applies unless
    explicitly stated otherwise [...]: If an argument to
    a function has an invalid value (such as [...] a null
    pointer, [...]) [...]the behavior is undefined. [...]"

    --
    Eric Sosman
    esosman@ieee-dot-org.invalid

    Comment

    • Eric Sosman

      #17
      Re: fclose(0)

      Bartc wrote:
      [...]
      What's wrong with fclose() doing something like: "ABORTING: Invalid handle
      to fclose()".
      It does! The spelling of the error message differs somewhat
      implementation to implementation; on one I'm familiar with, the
      message is spelled "SIGSEGV" ...

      --
      Eric Sosman
      esosman@ieee-dot-org.invalid

      Comment

      • Lew Pitcher

        #18
        Re: fclose(0)

        In comp.lang.c, Eric Sosman wrote:
        Bartc wrote:
        >[...]
        >What's wrong with fclose() doing something like: "ABORTING: Invalid
        >handle to fclose()".
        >
        It does! The spelling of the error message differs somewhat
        implementation to implementation; on one I'm familiar with, the
        message is spelled "SIGSEGV" ...
        and I've seen that message, but spelled as "S0C4"


        --
        Lew Pitcher

        Master Codewright & JOAT-in-training | Registered Linux User #112576
        http://pitcher.digitalfreehold.ca/ | GPG public key available by request
        ---------- Slackware - Because I know what I'm doing. ------


        Comment

        • Bartc

          #19
          Re: fclose(0)


          "Eric Sosman" <esosman@ieee-dot-org.invalidwrot e in message
          news:XImdnTItnK X_4I7VnZ2dnUVZ_ quhnZ2d@comcast .com...
          Bartc wrote:
          >"Richard Heathfield" <rjh@see.sig.in validwrote
          >>>
          >>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.
          The relevant passage is Section 7.1.4 paragraph 1:
          >
          "Each of the following statements applies unless
          explicitly stated otherwise [...]: If an argument to
          a function has an invalid value (such as [...] a null
          pointer, [...]) [...]the behavior is undefined. [...]"
          I suspect this was written when there were already many implementations that
          behaved this way.

          If this was the case then it would be better to admit it rather than
          suggest, as a few people have, that crashing on passing a null pointer is
          actually a good idea.

          --
          Bartc




          Comment

          • Richard Heathfield

            #20
            Re: fclose(0)

            Bartc said:

            <snip>
            If this was the case then it would be better to admit it rather than
            suggest, as a few people have, that crashing on passing a null pointer is
            actually a good idea.
            Crashing is not an idea - either good or bad. It is merely a consequence.

            If a programmer is dense enough to break the contract between himself and
            the implementation, he has no business complaining when something happens
            that he doesn't like. If you don't want a crash or some other bad
            consequence of passing an invalid argument (and neither do I), the answer
            is simple: ***don't pass an invalid argument***.

            --
            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

            • Joe Wright

              #21
              Re: fclose(0)

              Richard Heathfield wrote:
              Bartc said:
              >
              <snip>
              >
              >If this was the case then it would be better to admit it rather than
              >suggest, as a few people have, that crashing on passing a null pointer is
              >actually a good idea.
              >
              Crashing is not an idea - either good or bad. It is merely a consequence.
              >
              If a programmer is dense enough to break the contract between himself and
              the implementation, he has no business complaining when something happens
              that he doesn't like. If you don't want a crash or some other bad
              consequence of passing an invalid argument (and neither do I), the answer
              is simple: ***don't pass an invalid argument***.
              >
              I'm not sure it's invalid. Consider..

              FILE *fp = fopen("file", "r");

              which fails for some reason. Later in the program we do..

              int stat = fclose(fp);

              The fclose finds that fp does not point to an open file and returns EOF.

              No crash, no problem.

              --
              Joe Wright
              "Everything should be made as simple as possible, but not simpler."
              --- Albert Einstein ---

              Comment

              • Richard Heathfield

                #22
                Re: fclose(0)

                Joe Wright said:
                Richard Heathfield wrote:
                <snip>
                >If you don't want a crash or some other
                >bad consequence of passing an invalid argument (and neither do I), the
                >answer is simple: ***don't pass an invalid argument***.
                >>
                I'm not sure it's invalid. Consider..
                >
                FILE *fp = fopen("file", "r");
                >
                which fails for some reason. Later in the program we do..
                >
                int stat = fclose(fp);
                If fp is a null pointer, the argument *is* invalid, because fclose requires
                fp to be a pointer to a stream that is associated with a file. A null
                pointer doesn't qualify, since it is guaranteed not to point to any
                object.
                The fclose finds that fp does not point to an open file and returns EOF.
                That is one legitimate outcome of undefined behaviour, yes. As you know,
                there are plenty of others.
                No crash, no problem.
                I'm not sure I agree about the "no problem" part.

                --
                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

                • Ian Collins

                  #23
                  Re: fclose(0)

                  Richard Heathfield wrote:
                  Joe Wright said:
                  >
                  >Richard Heathfield wrote:
                  >
                  <snip>
                  >
                  >>If you don't want a crash or some other
                  >>bad consequence of passing an invalid argument (and neither do I), the
                  >>answer is simple: ***don't pass an invalid argument***.
                  >>>
                  >I'm not sure it's invalid. Consider..
                  >>
                  > FILE *fp = fopen("file", "r");
                  >>
                  >which fails for some reason. Later in the program we do..
                  >>
                  > int stat = fclose(fp);
                  >
                  If fp is a null pointer, the argument *is* invalid, because fclose requires
                  fp to be a pointer to a stream that is associated with a file. A null
                  pointer doesn't qualify, since it is guaranteed not to point to any
                  object.
                  >
                  It's a pity that case isn't specified in the way malloc/free is.

                  It is always safe to call free with the result of malloc, so it would be
                  consistent to always be a able to call any resource freeing function
                  with the result of its corresponding allocation function.

                  --
                  Ian Collins.

                  Comment

                  • Eric Sosman

                    #24
                    Re: fclose(0)

                    Bartc wrote:
                    "Eric Sosman" <esosman@ieee-dot-org.invalidwrot e in message
                    news:XImdnTItnK X_4I7VnZ2dnUVZ_ quhnZ2d@comcast .com...
                    >Bartc wrote:
                    >>"Richard Heathfield" <rjh@see.sig.in validwrote
                    >>>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.
                    >
                    > The relevant passage is Section 7.1.4 paragraph 1:
                    >>
                    >"Each of the following statements applies unless
                    >explicitly stated otherwise [...]: If an argument to
                    >a function has an invalid value (such as [...] a null
                    >pointer, [...]) [...]the behavior is undefined. [...]"
                    >
                    I suspect this was written when there were already many implementations that
                    behaved this way.
                    The Committee's mandate was not to invent a new programming
                    language from whole cloth, but to codify existing practice insofar
                    as practical.

                    In the Rationale, the Committee laid out the principles that
                    it tried to apply when making decisions about the language. One
                    of these was "Keep the spirit of C," and the very first point in
                    the short list of facets that constitute that spirit is "Trust
                    the programmer." As Richard Heathfield pointed out earlier, trust
                    is not a one-sided relationship; the trusted party bears a burden
                    arising from the fact of being trusted.
                    If this was the case then it would be better to admit it rather than
                    suggest, as a few people have, that crashing on passing a null pointer is
                    actually a good idea.
                    The good idea is not to pass a null pointer in the first place.
                    If you want a hand-holding language (and there's no shame in wanting
                    such a thing), you can find plenty of them.

                    --
                    Eric Sosman
                    esosman@ieee-dot-org.invalid

                    Comment

                    • Chris Torek

                      #25
                      Re: fclose(0)

                      In article <i--dnZ85CdjKOo7VnZ 2dnUVZ_uGdnZ2d@ comcast.com>
                      Eric Sosman <esosman@ieee-dot-org.invalidwrot e:
                      In the Rationale, the Committee laid out the principles that
                      >it tried to apply when making decisions about the language. One
                      >of these was "Keep the spirit of C," and the very first point in
                      >the short list of facets that constitute that spirit is "Trust
                      >the programmer." As Richard Heathfield pointed out earlier, trust
                      >is not a one-sided relationship; the trusted party bears a burden
                      >arising from the fact of being trusted.
                      A burden and a benefit, simultaneously. :-)
                      The good idea is not to pass a null pointer in the first place.
                      And yet, if this is the case, why does free() accept NULL? The
                      same argument holds here, and -- historically speaking -- at the
                      time the C89 standard was being created, actual implementations
                      actually crashed if you called free(NULL). So the committee have
                      attempted to have it both ways: "We trust you (putting the burden
                      of checking for NULL first) when you call fclose(), but we do not
                      trust you (removing the burden of checking for NULL first) when
                      you call free()".

                      It is not consistent. But it is C. :-)
                      --
                      In-Real-Life: Chris Torek, Wind River Systems
                      Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
                      email: gmail (figure it out) http://web.torek.net/torek/index.html

                      Comment

                      • Richard Tobin

                        #26
                        Re: fclose(0)

                        In article <67hl00F2mn7q3U 2@mid.individua l.net>,
                        Ian Collins <ian-news@hotmail.co mwrote:
                        >If fp is a null pointer, the argument *is* invalid, because fclose requires
                        >fp to be a pointer to a stream that is associated with a file. A null
                        >pointer doesn't qualify, since it is guaranteed not to point to any
                        >object.
                        >It's a pity that case isn't specified in the way malloc/free is.
                        The case is different with malloc(). Malloc() can return null
                        when it succeeds, if its argument is 0.

                        I believe the requirement for free(0) to work was added at the same
                        time that malloc(0) was required to work and allowed to return a null
                        pointer.

                        -- Richard
                        --
                        :wq

                        Comment

                        • Richard Tobin

                          #27
                          Re: fclose(0)

                          In article <fuvh9u$mlt$1@r egistered.motza rella.org>,
                          santosh <santosh.k83@gm ail.comwrote:
                          >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.
                          The standard *does* say that you get undefined behaviour if you pass
                          null to a library function expecting a pointer unless it explicitly
                          says you can. So the behaviour is certainly undefined.

                          -- Richard
                          --
                          :wq

                          Comment

                          • Jack Klein

                            #28
                            Re: fclose(0)

                            On Sat, 26 Apr 2008 16:21:13 GMT, "Bartc" <bc@freeuk.comw rote in
                            comp.lang.c:
                            >
                            "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().
                            There are a large number of standard library functions that accept a
                            pointer to char, expecting it to be the first character of a '\0'
                            terminated string. There are also functions in the C standard library
                            that return a pointer to char on success, but could return NULL,
                            strchr(), for one. Your suggestion, by analogy, could extend to
                            saying that all functions expecting a pointer to char should accept a
                            null pointer.

                            On the other hand, I think it would have been convenient to specify
                            that fclose(NULL) would be a no-op, not for the reason that you
                            mention, but for parity with free(NULL) being defined as a no-op.

                            As is it, at the end of an operation that allocates one or more
                            dynamic memory block, and opens one or more files, in a clean up
                            section that might be reached prematurely if any of the resource
                            allocations failed, you just have to write:

                            free (mem1);
                            free (mem2);
                            if (file1) fclose(file1);
                            if (file2) fclose(files):

                            ....which makes the fclose() checking inelegant by comparison. But
                            such is life.

                            --
                            Jack Klein
                            Home: http://JK-Technology.Com
                            FAQs for
                            comp.lang.c http://c-faq.com/
                            comp.lang.c++ http://www.parashift.com/c++-faq-lite/
                            alt.comp.lang.l earn.c-c++

                            Comment

                            • CBFalconer

                              #29
                              Re: fclose(0)

                              Chris Torek wrote:
                              Eric Sosman <esosman@ieee-dot-org.invalidwrot e:
                              >
                              .... snip ...
                              >
                              A burden and a benefit, simultaneously. :-)
                              >
                              >The good idea is not to pass a null pointer in the first place.
                              >
                              And yet, if this is the case, why does free() accept NULL? The
                              same argument holds here, and -- historically speaking -- at the
                              time the C89 standard was being created, actual implementations
                              actually crashed if you called free(NULL). So the committee have
                              attempted to have it both ways: "We trust you (putting the burden
                              of checking for NULL first) when you call fclose(), but we do not
                              trust you (removing the burden of checking for NULL first) when
                              you call free()".
                              However fclose doesn't crash on receiving a NULL. It returns EOF.

                              --
                              [mail]: Chuck F (cbfalconer at maineline dot net)
                              [page]: <http://cbfalconer.home .att.net>
                              Try the download section.


                              ** Posted from http://www.teranews.com **

                              Comment

                              • CBFalconer

                                #30
                                Re: fclose(0)

                                Joe Wright wrote:
                                >
                                .... snip ...
                                >
                                I'm not sure it's invalid. Consider..
                                >
                                FILE *fp = fopen("file", "r");
                                >
                                which fails for some reason. Later in the program we do..
                                >
                                int stat = fclose(fp);
                                >
                                The fclose finds that fp does not point to an open file and
                                returns EOF.
                                And between fopen and fclose you use the file. If fopen failed it
                                is not usable, and it does not need closing. The standard says:

                                7.19.5.1 The fclose function

                                Synopsis
                                [#1]
                                #include <stdio.h>
                                int fclose(FILE *stream);

                                Description

                                [#2] The fclose function causes the stream pointed to by
                                stream to be flushed and the associated file to be closed.
                                Any unwritten buffered data for the stream are delivered to
                                the host environment to be written to the file; any unread
                                buffered data are discarded. The stream is disassociated
                                from the file. If the associated buffer was automatically
                                allocated, it is deallocated.

                                Returns

                                [#3] The fclose function returns zero if the stream was
                                successfully closed, or EOF if any errors were detected.

                                --
                                [mail]: Chuck F (cbfalconer at maineline dot net)
                                [page]: <http://cbfalconer.home .att.net>
                                Try the download section.


                                ** Posted from http://www.teranews.com **

                                Comment

                                Working...