Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #102713 > unrolled thread

Using fread function

Started byjanus <emekamicro@gmail.com>
First post2017-01-29 10:07 -0800
Last post2017-01-30 13:57 -0800
Articles 20 on this page of 36 — 7 participants

Back to article view | Back to comp.lang.c


Contents

  Using fread function janus <emekamicro@gmail.com> - 2017-01-29 10:07 -0800
    Re: Using fread function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-29 14:31 -0500
      Re: Using fread function supercat@casperkitty.com - 2017-01-30 08:03 -0800
      Re: Using fread function Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-01 13:59 -0800
        Re: Using fread function jameskuyper@verizon.net - 2017-02-05 11:40 -0800
          Re: Using fread function Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-08 22:04 -0800
            Re: Using fread function jameskuyper@verizon.net - 2017-02-09 05:39 -0800
              Re: Using fread function supercat@casperkitty.com - 2017-02-09 07:47 -0800
                Re: Using fread function Keith Thompson <kst-u@mib.org> - 2017-02-09 09:19 -0800
                  Re: Using fread function supercat@casperkitty.com - 2017-02-09 09:55 -0800
                    Re: Using fread function Keith Thompson <kst-u@mib.org> - 2017-02-09 12:10 -0800
                      Re: Using fread function supercat@casperkitty.com - 2017-02-09 13:01 -0800
                Re: Using fread function Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-12 09:36 -0800
                  Re: Using fread function supercat@casperkitty.com - 2017-02-12 10:52 -0800
                    Re: Using fread function Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-19 21:19 -0800
                      Re: Using fread function supercat@casperkitty.com - 2017-02-20 09:35 -0800
                        Re: Using fread function Keith Thompson <kst-u@mib.org> - 2017-02-20 09:52 -0800
                          Re: Using fread function supercat@casperkitty.com - 2017-02-20 11:15 -0800
                            Re: Using fread function Keith Thompson <kst-u@mib.org> - 2017-02-20 11:45 -0800
                              Re: Using fread function "James R. Kuyper" <jameskuyper@verizon.net> - 2017-02-20 15:38 -0500
                                Re: Using fread function Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-23 12:12 -0800
                                  Re: Using fread function jameskuyper@verizon.net - 2017-02-24 10:37 -0800
                        Re: Using fread function Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-23 05:04 -0800
                          Re: Using fread function supercat@casperkitty.com - 2017-02-23 07:58 -0800
                            Re: Using fread function Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-25 11:48 -0800
                              Re: Using fread function jameskuyper@verizon.net - 2017-02-25 13:44 -0800
                                Re: Using fread function Tim Rentsch <txr@alumni.caltech.edu> - 2017-04-17 13:12 -0700
                                  Re: Using fread function supercat@casperkitty.com - 2017-04-17 13:50 -0700
              Re: Using fread function Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-12 09:31 -0800
    Re: Using fread function Keith Thompson <kst-u@mib.org> - 2017-01-29 13:14 -0800
    Re: Using fread function Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-30 08:18 -0800
      Re: Using fread function supercat@casperkitty.com - 2017-01-30 08:44 -0800
      Re: Using fread function Keith Thompson <kst-u@mib.org> - 2017-01-30 11:58 -0800
        Re: Using fread function Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-30 13:05 -0800
          Re: Using fread function supercat@casperkitty.com - 2017-01-30 13:39 -0800
          Re: Using fread function Keith Thompson <kst-u@mib.org> - 2017-01-30 13:57 -0800

Page 1 of 2  [1] 2  Next page →


#102713 — Using fread function

Fromjanus <emekamicro@gmail.com>
Date2017-01-29 10:07 -0800
SubjectUsing fread function
Message-ID<02c75a0c-84d7-4669-8bde-472730c7f8d3@googlegroups.com>
Hello All,

I just noticed that swapping the positions of the inner parameters does not have any material effect on result. That led me to think that "fread" function just multiple the two parameters.

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

size_t fread(void *ptr,  size_t nmemb, size_t size, FILE *stream);

Is my position correct?

Happy Sunday!

Janus

[toc] | [next] | [standalone]


#102723

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-01-29 14:31 -0500
Message-ID<79af9f0c-d7e1-ef68-d186-f1ce0baa9e6c@verizon.net>
In reply to#102713
On 01/29/2017 01:07 PM, janus wrote:
> Hello All,
>
> I just noticed that swapping the positions of the inner parameters
> does not have any material effect on result. ...

What "material effects" did you look at? You apparently missed a couple 
of important effects.

> ... That led me to think
> that "fread" function just multiple the two parameters.
>
> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

Since C99, according to 7.21,.8.1p1, the correct prototype is

     size_t fread(void * restrict ptr,
          size_t size, size_t nmemb,
          FILE * restrict stream);

The significance of this change from C90 is that it's now explicitly 
undefined behavior if there's any overlap between the FILE object 
pointed at by stream, and the first size*nmemb bytes of the memory 
pointed at by ptr.  I believe that it also means that it's undefined 
behavior for that block of memory to overlap the location where errno is 
stored. I can't imagine that it has ever been safe to make such a calls 
to fread(), but the standard has never said so directly. In C99 the 
"restrict" keyword was introduced, which provided a convenient way of 
implying that problem. It still doesn't say so directly - you need to 
understand the "restrict" keyword in order to figure out the implications.

> size_t fread(void *ptr,  size_t nmemb, size_t size, FILE *stream);
>
> Is my position correct?

"The fread function returns the number of elements successfully read, 
which may be less than nmemb if a read error or end-of-file is 
encountered." (7.21.8.1p3)

A successful call to fread(ptr, size, nmemb, stream) will therefore 
always return the value of nmemb. If it isn't successful, due to 
reaching the end of the file after reading N bytes, but before reading 
the nmemb elements, fread() will return N/size.

If N % size > 0, then fread() will have read a partial element. "If a 
partial element is read, its value is indeterminate." (7.21.8.1p2). 
Naively, you might expect that it would have filled the first N%size 
bytes of that partial element, leaving the remaining bytes unchanged. 
However, 7.21.8.1p2 means that this expectation need not be valid. You 
should consider the entire "size" bytes of the partial element to be 
unusable. Therefore, the first argument determine how large a portion of 
the input data has an indeterminate value.

That's a total of three different ways that "size" has a different 
effect on the results than "nmemb".

[toc] | [prev] | [next] | [standalone]


#102758

Fromsupercat@casperkitty.com
Date2017-01-30 08:03 -0800
Message-ID<44309152-d98d-490b-aa0e-3cad8294c198@googlegroups.com>
In reply to#102723
On Sunday, January 29, 2017 at 1:32:06 PM UTC-6, James R. Kuyper wrote:
> The significance of this change from C90 is that it's now explicitly 
> undefined behavior if there's any overlap between the FILE object 
> pointed at by stream, and the first size*nmemb bytes of the memory 
> pointed at by ptr.

A "restrict" qualifier may be suggestive of that, but it wouldn't prove
anything.  It would be possible to write a version of "memmove" which
included restrict qualifiers on both memory arguments but had defined
behavior in all cases where memmove would do so.  Something like:

    void *memmove(void * restrict dest, void const * restrict src, 
                  size_t count)
    {
      unsigned char const * restrict src2=src;
      unsigned char * restrict dest2=dest;
      for (size_t i=0; i<count; i++)
      {
        if ((unsigned char*)src+i == dest2) // dest within src
        {
          for (size_t j=count; j--; )
            dest2[j]=(dest2-i)[j];
          return dest;
        }
        if (dest2+i == src) // src within dest
        {
          for (size_t j=0; j<count; j++)
            dest2[j] = (dest2+i)[j];
          return dest;
        }
      }
      src2 = src;
      for (size_t i=0; i<count; i++)
        dest2[i] = src2[i];
      return dest;
    }

Note that if the source and destination overlap all accesses will be done
with a pointer derived from dest, thereby honoring the "restrict" qualifier.
All pointer arithmetic will be in bounds if src and dest identify regions
large enough for the copy to succeed, and the == operator is defined both
for pointers within the same object and for pointers to disjoint objects.

[toc] | [prev] | [next] | [standalone]


#102934

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-02-01 13:59 -0800
Message-ID<kfnefzhd13n.fsf@x-alumni2.alumni.caltech.edu>
In reply to#102723
"James R. Kuyper" <jameskuyper@verizon.net> writes:

> On 01/29/2017 01:07 PM, janus wrote:
>> Hello All,
>>
>> I just noticed that swapping the positions of the inner parameters
>> does not have any material effect on result. ...
>
> What "material effects" did you look at?  You apparently missed a
> couple of important effects.
>
>> ... That led me to think
>> that "fread" function just multiple the two parameters.
>>
>> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
>
> Since C99, according to 7.21,.8.1p1, the correct prototype is
>
>     size_t fread(void * restrict ptr,
>          size_t size, size_t nmemb,
>          FILE * restrict stream);
>
> The significance of this change from C90 is that its now explicitly
> undefined behavior if there's any overlap between the FILE object
> pointed at by stream, and the first size*nmemb bytes of the memory
> pointed at by ptr.  [...]

Is it?  I agree that the intention in such cases is that they be
undefined behavior, but AFAIK there is no explicit statement in
the Standard that makes such a rule.  Based just on the function
prototype, we can't conclude anything about how the function is
defined (ie, in this respect), since the two 'restrict's do not
participate in type compatibility.  Is there some passage in
the Standard that makes this inference iron-clad, or is it just
a guess at what was meant?  If there is such a passage, what is
it (or are they)?

[toc] | [prev] | [next] | [standalone]


#103234

Fromjameskuyper@verizon.net
Date2017-02-05 11:40 -0800
Message-ID<05a6afe0-d7db-4877-a244-1c5c7bc8e928@googlegroups.com>
In reply to#102934
On Wednesday, February 1, 2017 at 4:59:24 PM UTC-5, Tim Rentsch wrote:
> "James R. Kuyper" <jameskuyper@verizon.net> writes:
...
> > Since C99, according to 7.21,.8.1p1, the correct prototype is
> >
> >     size_t fread(void * restrict ptr,
> >          size_t size, size_t nmemb,
> >          FILE * restrict stream);
> >
> > The significance of this change from C90 is that its now explicitly
> > undefined behavior if there's any overlap between the FILE object
> > pointed at by stream, and the first size*nmemb bytes of the memory
> > pointed at by ptr.  [...]
> 
> Is it?  I agree that the intention in such cases is that they be
> undefined behavior, but AFAIK there is no explicit statement in
> the Standard that makes such a rule.  Based just on the function
> prototype, we can't conclude anything about how the function is
> defined (ie, in this respect), since the two 'restrict's do not
> participate in type compatibility.  Is there some passage in
> the Standard that makes this inference iron-clad, or is it just
> a guess at what was meant?  If there is such a passage, what is
> it (or are they)?

Sorry for taking so long to reply. I recognized the issue you raised as soon as I read your message, but I wanted to check every relevant detail before responding, and I didn't have time to do so before today.

Qualifiers that are applied directly to the parameters in a function prototype that is not a function definition are pretty much completely irrelevant (this is not true of qualifiers that apply to the pointed-at type of a pointer parameter, rather than to the parameter itself). Arguments to a prototyped function are converted to the unqualified version of the corresponding parameter's type (6.5.2.2p2). Qualifiers on parameters of function declarations are ignored when determining whether or not the corresponding types are compatible (6.7.6.3p15). The requirement that "All declarations that refer to the same ... function shall have compatible type; otherwise, the behavior is undefined." (6.2.7p2) does not, therefore, require that parameter types in different declarations be identically qualified.
In particular, this means that the parameter types in a function definition's declaration need not have the same qualifiers that they had in any other declaration of that same function.
The consequences of a parameter's qualifier apply only to lvalue expressions (6.7.3p4) involving the qualified identifier, which can occur only inside the definition of the function that the parameter is part of. Therefore, the "restrict" qualifiers that the standard specifies for standard library functions in section 7 would technically be completely meaningless, even if the standard did require that C standard library functions be implemented in C (which it does not).

I don't think those qualifiers are intended to be meaningless. I think that they were intended to convey permission for implementors to perform the same optimizations within the implementation of standard library routines that would be permitted if they were implemented in C using those prototypes in the function definition. I recommend that all developers assume that this is the case, and therefore avoid code that would have would have undefined behavior if it were the case. However, I concede that I cannot find any wording in the standard that says anything of the kind.

Section 6.7.3.1 of the Rationale mentions that

"The restrict qualifier can be used to express the restriction on overlap in a new prototype that is compatible with the original version:"
     void *memcpy(void * restrict s1, const void * restrict s2,
     size_t n);"

The Rationale is not normative, but gives insight into the committee's intent.

[toc] | [prev] | [next] | [standalone]


#103512

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-02-08 22:04 -0800
Message-ID<kfn37fn7ve2.fsf@x-alumni2.alumni.caltech.edu>
In reply to#103234
jameskuyper@verizon.net writes:

> On Wednesday, February 1, 2017 at 4:59:24 PM UTC-5, Tim Rentsch wrote:
>> "James R.  Kuyper" <jameskuyper@verizon.net> writes:
>
> ...
>
>>> Since C99, according to 7.21,.8.1p1, the correct prototype is
>>>
>>>     size_t fread(void * restrict ptr,
>>>          size_t size, size_t nmemb,
>>>          FILE * restrict stream);
>>>
>>> The significance of this change from C90 is that its now explicitly
>>> undefined behavior if there's any overlap between the FILE object
>>> pointed at by stream, and the first size*nmemb bytes of the memory
>>> pointed at by ptr.  [...]
>>
>> Is it?  I agree that the intention in such cases is that they be
>> undefined behavior, but AFAIK there is no explicit statement in
>> the Standard that makes such a rule.  Based just on the function
>> prototype, we can't conclude anything about how the function is
>> defined (ie, in this respect), since the two 'restrict's do not
>> participate in type compatibility.  Is there some passage in
>> the Standard that makes this inference iron-clad, or is it just
>> a guess at what was meant?  If there is such a passage, what is
>> it (or are they)?
>
> Sorry for taking so long to reply.  I recognized the issue you raised
> as soon as I read your message, but I wanted to check every relevant
> detail before responding, and I didn't have time to do so before
> today.

No worries.  I appreciate the double check.

> Qualifiers that are applied directly to the parameters in a function
> prototype that is not a function definition are pretty much
> completely irrelevant (this is not true of qualifiers that apply to
> the pointed-at type of a pointer parameter, rather than to the
> parameter itself).  Arguments to a prototyped function are converted
> to the unqualified version of the corresponding parameter's type
> (6.5.2.2p2).  Qualifiers on parameters of function declarations are
> ignored when determining whether or not the corresponding types are
> compatible (6.7.6.3p15).  The requirement that "All declarations that
> refer to the same ... function shall have compatible type;
> otherwise, the behavior is undefined."  (6.2.7p2) does not,
> therefore, require that parameter types in different declarations be
> identically qualified.
> In particular, this means that the parameter types in a function
> definition's declaration need not have the same qualifiers that they
> had in any other declaration of that same function.
> The consequences of a parameter's qualifier apply only to lvalue
> expressions (6.7.3p4) involving the qualified identifier, which can
> occur only inside the definition of the function that the parameter
> is part of.  Therefore, the "restrict" qualifiers that the standard
> specifies for standard library functions in section 7 would
> technically be completely meaningless, even if the standard did
> require that C standard library functions be implemented in C (which
> it does not).
>
> I don't think those qualifiers are intended to be meaningless.  I
> think that they were intended to convey permission for implementors
> to perform the same optimizations within the implementation of
> standard library routines that would be permitted if they were
> implemented in C using those prototypes in the function definition.
> I recommend that all developers assume that this is the case, and
> therefore avoid code that would have would have undefined behavior if
> it were the case.  However, I concede that I cannot find any wording
> in the standard that says anything of the kind.
>
> Section 6.7.3.1 of the Rationale mentions that
>
> "The restrict qualifier can be used to express the restriction on
> overlap in a new prototype that is compatible with the original
> version:"
>      void *memcpy(void * restrict s1, const void * restrict s2,
>      size_t n);"
>
> The Rationale is not normative, but gives insight into the committee's intent.

Seems like rather a long way of saying, "I think you're right.
It seems clear that the intention is that there be undefined
behavior in such cases, but AFAICT the Standard never actually
comes right out and says so (or gives any explicit statement to
that effect)."

[toc] | [prev] | [next] | [standalone]


#103518

Fromjameskuyper@verizon.net
Date2017-02-09 05:39 -0800
Message-ID<28dc26c8-8063-4334-9850-b1a5ba7876f3@googlegroups.com>
In reply to#103512
On Thursday, February 9, 2017 at 1:04:12 AM UTC-5, Tim Rentsch wrote:
...
> Seems like rather a long way of saying, "I think you're right.
> It seems clear that the intention is that there be undefined
> behavior in such cases, but AFAICT the Standard never actually
> comes right out and says so (or gives any explicit statement to
> that effect)."

It would have been, had that been what I wanted to say. What I wanted to say was "You're right, and here's an explanation why." Obviously, you don't need the explanation - it's for other people reading this thread. I was sufficiently aware of the relevant issues that I knew exactly what you were referring to when you made your comment. However, I was not sufficiently aware of them to avoid incorrectly expressing the message you were commenting on. That being the case, I'd expect there to be a lot of people who were not aware of the issues at all. 

It's rather peculiar that, like function parameter names, qualifiers on parameters in a non-defining prototype are permitted but meaningless. I believe that they were permitted, so that the same prototype could be used for the declaration and the definition. However, because they are meaningless, it's not mandatory for the declaration and the definition to have prototypes that match in those ways. It could have been mandatory; the standard goes out of it's way to make it not mandatory, so that was clearly deliberate.

[toc] | [prev] | [next] | [standalone]


#103520

Fromsupercat@casperkitty.com
Date2017-02-09 07:47 -0800
Message-ID<d0e4b764-cef7-41d1-af6c-9b71a2ae323c@googlegroups.com>
In reply to#103518
On Thursday, February 9, 2017 at 7:40:00 AM UTC-6, james...@verizon.net wrote:
> It's rather peculiar that, like function parameter names, qualifiers on parameters in a non-defining prototype are permitted but meaningless. I believe that they were permitted, so that the same prototype could be used for the declaration and the definition. However, because they are meaningless, it's not mandatory for the declaration and the definition to have prototypes that match in those ways. It could have been mandatory; the standard goes out of it's way to make it not mandatory, so that was clearly deliberate.

I also find it peculiar that the Standard doesn't require that
implementations do anything useful with qualifiers like "restrict" and
"register" but requires that even implementations where they serve no
purpose must still go through the effort of validating them.  In cases
where many or all implementations' natural behavior in the absence of a
qualifier would match the required behavior with the qualifier, but 
either:

  (1) the qualifier could allow implementations to generate more efficient
      code, or

  (2) the qualifier could make the code usable on platforms that were
      capable of supporting the behavior at some cost but didn't do so by
      default

allowing implementations that naturally support the required behavior to
"support" the qualifier by simply it would minimize the burden the qualifier
would place upon implementations.

[toc] | [prev] | [next] | [standalone]


#103538

FromKeith Thompson <kst-u@mib.org>
Date2017-02-09 09:19 -0800
Message-ID<lnwpczxowx.fsf@kst-u.example.com>
In reply to#103520
supercat@casperkitty.com writes:
> On Thursday, February 9, 2017 at 7:40:00 AM UTC-6, james...@verizon.net wrote:
>> It's rather peculiar that, like function parameter names, qualifiers
>> on parameters in a non-defining prototype are permitted but
>> meaningless. I believe that they were permitted, so that the same
>> prototype could be used for the declaration and the
>> definition. However, because they are meaningless, it's not mandatory
>> for the declaration and the definition to have prototypes that match
>> in those ways. It could have been mandatory; the standard goes out of
>> it's way to make it not mandatory, so that was clearly deliberate.
> 
> I also find it peculiar that the Standard doesn't require that
> implementations do anything useful with qualifiers like "restrict" and
> "register" but requires that even implementations where they serve no
> purpose must still go through the effort of validating them.  In cases
> where many or all implementations' natural behavior in the absence of a
> qualifier would match the required behavior with the qualifier, but 
> either:
>
>   (1) the qualifier could allow implementations to generate more efficient
>       code, or
>
>   (2) the qualifier could make the code usable on platforms that were
>       capable of supporting the behavior at some cost but didn't do so by
>       default
>
> allowing implementations that naturally support the required behavior to
> "support" the qualifier by simply it would minimize the burden the qualifier
> would place upon implementations.

I think you accidentally a word.  Did you mean "by simply *ignoring*
it"?  If so, what exactly do you mean by that?

Are you suggesting that an implementation that doesn't do anything
useful with "restrict" should be able to ignore it altogether, so that

    int n = restrict 42;

would be quietly treated as a valid declaration?  Or that an
implementation that ignores register should allow the address of a
register-qualified object to be taken?

If so, why?

If I write code that uses "register" or "restrict", I want my compiler
to check my code for validity, whether they have any semantic impact or
not.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#103542

Fromsupercat@casperkitty.com
Date2017-02-09 09:55 -0800
Message-ID<ac73adab-30f6-42f6-b243-01b361645a03@googlegroups.com>
In reply to#103538
On Thursday, February 9, 2017 at 11:19:16 AM UTC-6, Keith Thompson wrote:
> Are you suggesting that an implementation that doesn't do anything
> useful with "restrict" should be able to ignore it altogether, so that
> 
>     int n = restrict 42;
> 
> would be quietly treated as a valid declaration?  Or that an
> implementation that ignores register should allow the address of a
> register-qualified object to be taken?
> 
> If so, why?
> 
> If I write code that uses "register" or "restrict", I want my compiler
> to check my code for validity, whether they have any semantic impact or
> not.

If an implementation isn't going to do anything useful with "restrict",
would it be more useful to have the authors spend a day or more adding
logic to deal with all the places where the keyword is or is not allowed
to appear syntactically, or would it be more useful to have the author
spend a day on some other feature which would improve the behavior of
programs that can actually run?

I would not disagree that--all else being equal--an implementation which
ensured that "restrict" was only used in spots where it is legal could
be regarded as being of higher quality than one which will accept it just
about anywhere, but if in the judgment of the implementer the time that
would be required to achieve that could be more usefully spent in some
other fashion, I would not regard the value of having compilers validate
the usage of "restrict" as being so enormous as to justify overriding the
implementer's judgment.

Incidentally, one of the reasons I favor optional features is that there
are some platforms for which compilers cannot be effectively upgraded;
certain newer language features could be supported on those platforms by
feeding code through utilities that would convert those constructs to
platforms the older platform can support, but handling other features
would be more difficult.  Having the newer Standards recognize a category
of implementations which support many new features but not all of them
would seem nicer than simply saying that the Standard is no longer
applicable to older platforms.

[toc] | [prev] | [next] | [standalone]


#103562

FromKeith Thompson <kst-u@mib.org>
Date2017-02-09 12:10 -0800
Message-ID<lnk28zxgzd.fsf@kst-u.example.com>
In reply to#103542
supercat@casperkitty.com writes:
> On Thursday, February 9, 2017 at 11:19:16 AM UTC-6, Keith Thompson wrote:
>> Are you suggesting that an implementation that doesn't do anything
>> useful with "restrict" should be able to ignore it altogether, so that
>> 
>>     int n = restrict 42;
>> 
>> would be quietly treated as a valid declaration?  Or that an
>> implementation that ignores register should allow the address of a
>> register-qualified object to be taken?
>> 
>> If so, why?
>> 
>> If I write code that uses "register" or "restrict", I want my compiler
>> to check my code for validity, whether they have any semantic impact or
>> not.
>
> If an implementation isn't going to do anything useful with "restrict",
> would it be more useful to have the authors spend a day or more adding
> logic to deal with all the places where the keyword is or is not allowed
> to appear syntactically, or would it be more useful to have the author
> spend a day on some other feature which would improve the behavior of
> programs that can actually run?

Rhetorical questions ignored.

> I would not disagree that--all else being equal--an implementation which
> ensured that "restrict" was only used in spots where it is legal could
> be regarded as being of higher quality than one which will accept it just
> about anywhere, but if in the judgment of the implementer the time that
> would be required to achieve that could be more usefully spent in some
> other fashion, I would not regard the value of having compilers validate
> the usage of "restrict" as being so enormous as to justify overriding the
> implementer's judgment.

That time has already been spent.  All conforming C99 and C11 compilers
recognize the "restrict" keyword and handle it correctly, diagnosing any
uses of it that are syntactically incorrect.  I presume it wasn't at all
difficult.  I oppose fragmenting the language in the manner you
advocate.

[snip]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#103570

Fromsupercat@casperkitty.com
Date2017-02-09 13:01 -0800
Message-ID<995cd03f-384c-4c1e-b704-6bc5114005ea@googlegroups.com>
In reply to#103562
On Thursday, February 9, 2017 at 2:09:37 PM UTC-6, Keith Thompson wrote:
> > I would not disagree that--all else being equal--an implementation which
> > ensured that "restrict" was only used in spots where it is legal could
> > be regarded as being of higher quality than one which will accept it just
> > about anywhere, but if in the judgment of the implementer the time that
> > would be required to achieve that could be more usefully spent in some
> > other fashion, I would not regard the value of having compilers validate
> > the usage of "restrict" as being so enormous as to justify overriding the
> > implementer's judgment.
> 
> That time has already been spent.  All conforming C99 and C11 compilers
> recognize the "restrict" keyword and handle it correctly, diagnosing any
> uses of it that are syntactically incorrect.  I presume it wasn't at all
> difficult.  I oppose fragmenting the language in the manner you
> advocate.

Much of the embedded-systems world use a language which combines C89 with
a number of features from later versions of C.  If the Standard
describes a feature as something which quality implementations should
support when practical, programmers would entitled to assume support for
the feature except when targeting "unusual" implementations.  Recognizing
the existence of implementations that can't support all such features would
not reduce the number of implementations supporting them--it would merely
allow the Standard to say something useful about implementations which can
support all of the important features but can't practically support all of
the optional ones.

Further, I would suggest that the language would be more amenable to
optimization if it had more qualifiers which existing implementations could
process in conforming fashion without having to do anything other than pre-
define some macros.  Adding qualifiers in such a way that makes it hard for
code to use them while remaining compatible with existing implementations
would seem more likely to cause language fragmentation than adding qualifiers
which can be "accepted" by old and new implementations alike.

[toc] | [prev] | [next] | [standalone]


#103740

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-02-12 09:36 -0800
Message-ID<kfno9y72twm.fsf@x-alumni2.alumni.caltech.edu>
In reply to#103520
supercat@casperkitty.com writes:

> On Thursday, February 9, 2017 at 7:40:00 AM UTC-6, james...@verizon.net wrote:
>> It's rather peculiar that, like function parameter names, qualifiers
>> on parameters in a non-defining prototype are permitted but
>> meaningless.  I believe that they were permitted, so that the same
>> prototype could be used for the declaration and the definition.
>> However, because they are meaningless, it's not mandatory for the
>> declaration and the definition to have prototypes that match in those
>> ways.  It could have been mandatory;  the standard goes out of it's
>> way to make it not mandatory, so that was clearly deliberate.
>
> I also find it peculiar that the Standard doesn't require that
> implementations do anything useful with qualifiers like "restrict" and
> "register" but requires that even implementations where they serve no
> purpose must still go through the effort of validating them. [...]

It does because the point of a language standard is to define
a standard language.  Apparently that's a deeper concept than
I realized.

[toc] | [prev] | [next] | [standalone]


#103749

Fromsupercat@casperkitty.com
Date2017-02-12 10:52 -0800
Message-ID<e26967e5-4cbd-4261-aea0-381fd36a0496@googlegroups.com>
In reply to#103740
On Sunday, February 12, 2017 at 11:36:31 AM UTC-6, Tim Rentsch wrote:
> supercat writes:
> > I also find it peculiar that the Standard doesn't require that
> > implementations do anything useful with qualifiers like "restrict" and
> > "register" but requires that even implementations where they serve no
> > purpose must still go through the effort of validating them. [...]
> 
> It does because the point of a language standard is to define
> a standard language.  Apparently that's a deeper concept than
> I realized.

What fraction of tasks that are done by programs written for various C
implementations could be accomplished by Strictly Conforming programs in
a way that was just as readable and just as efficient?

The "language" in which Strictly Conforming programs can be written may be
usable for some purposes, but it is totally unsuitable for most of the
tasks which are performed by programs written in various dialects of C.

I would regard as important the ability of a compiler to usefully produce
executable programs that perform various tasks.  A quality compiler for
some platform should be compatible with existing code for architecturally-
compatible platforms, and should seek to provide diagnostics in cases where
code is unlikely to behave as intended.  Supplying diagnostics in cases
where there is no reason to believe the program's behavior would not match
the programmer's intent is far less important.

[toc] | [prev] | [next] | [standalone]


#104254

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-02-19 21:19 -0800
Message-ID<kfn4lzpwia8.fsf@x-alumni2.alumni.caltech.edu>
In reply to#103749
supercat@casperkitty.com writes:

> On Sunday, February 12, 2017 at 11:36:31 AM UTC-6, Tim Rentsch wrote:
>> supercat writes:
>>> I also find it peculiar that the Standard doesn't require that
>>> implementations do anything useful with qualifiers like "restrict" and
>>> "register" but requires that even implementations where they serve no
>>> purpose must still go through the effort of validating them.  [...]
>>
>> It does because the point of a language standard is to define
>> a standard language.  Apparently that's a deeper concept than
>> I realized.
>
> What fraction of tasks that are done by programs written for various C
> implementations could be accomplished by Strictly Conforming programs in
> a way that was just as readable and just as efficient?
>
> The "language" in which Strictly Conforming programs can be written may be
> usable for some purposes, but it is totally unsuitable for most of the
> tasks which are performed by programs written in various dialects of C.

You are confusing two different classes of program here, to wit,
programs that are written in standard C, and programs that are
strictly conforming.  My comment is about standard C, not about
C programs that are strictly conforming.

[toc] | [prev] | [next] | [standalone]


#104276

Fromsupercat@casperkitty.com
Date2017-02-20 09:35 -0800
Message-ID<ca025bfd-538e-462a-8709-aaa9aa0c5479@googlegroups.com>
In reply to#104254
On Sunday, February 19, 2017 at 11:19:50 PM UTC-6, Tim Rentsch wrote:
> supercat writes:
> > The "language" in which Strictly Conforming programs can be written may be
> > usable for some purposes, but it is totally unsuitable for most of the
> > tasks which are performed by programs written in various dialects of C.
> 
> You are confusing two different classes of program here, to wit,
> programs that are written in standard C, and programs that are
> strictly conforming.  My comment is about standard C, not about
> C programs that are strictly conforming.

The Standard defines two classes of programs: those which are Strictly
Conforming, and those which are Conforming but not Strictly Conforming.
I would interpret the class of "Strictly Conforming" programs as including
some which make use of some implementation-defined behaviors but will meet
their stated requirements with any combination of such behaviors that
conforming implementations could define (and thus to not rely upon any
Implementation Defined behaviors being defined in any *particular* fashion).

The Standard does not define any category of "Standard C" programs other
than the above, and the category of "Conforming" programs is so broad that
I don't think all such programs can be meaningfully described as being in
the same language, so if you're not referring to the category of "Strictly
Conforming" programs extended as above, to what are you referring?

[toc] | [prev] | [next] | [standalone]


#104280

FromKeith Thompson <kst-u@mib.org>
Date2017-02-20 09:52 -0800
Message-ID<lnd1ecn41j.fsf@kst-u.example.com>
In reply to#104276
supercat@casperkitty.com writes:
> On Sunday, February 19, 2017 at 11:19:50 PM UTC-6, Tim Rentsch wrote:
>> supercat writes:
>> > The "language" in which Strictly Conforming programs can be written may be
>> > usable for some purposes, but it is totally unsuitable for most of the
>> > tasks which are performed by programs written in various dialects of C.
>> 
>> You are confusing two different classes of program here, to wit,
>> programs that are written in standard C, and programs that are
>> strictly conforming.  My comment is about standard C, not about
>> C programs that are strictly conforming.
>
> The Standard defines two classes of programs: those which are Strictly
> Conforming, and those which are Conforming but not Strictly Conforming.
> I would interpret the class of "Strictly Conforming" programs as including
> some which make use of some implementation-defined behaviors but will meet
> their stated requirements with any combination of such behaviors that
> conforming implementations could define (and thus to not rely upon any
> Implementation Defined behaviors being defined in any *particular* fashion).

Isn't it simpler (and more accurate) just to use the definition in the
standard?

    A strictly conforming program shall use only those features
    of the language and library specified in this International
    Standard. It shall not produce output dependent on any
    unspecified, undefined, or implementation-defined behavior,
    and shall not exceed any minimum implementation limit.

A program that's required to print the value of INT_MAX will meet its
stated requirement, but it cannot be strictly conforming because its
output depends on something that's implementation-defined.  (I'm
assuming that the implementation-defined value of INT_MAX constitutes
implementation-defined behavior.  If not, it shouldn't be difficult to
construct another example.)

Strict comformance is, as the name implies, a strict requirement, one
that most programs don't meet.

A "conforming program" is "one that is acceptable to a conforming
implementation".  This includes programs that depend on
implementation-specific extensions, or even on undefined behavior.
Since a conforming implementation may *accept* a program containing `i =
i++`, such a program can be "conforming".  It is an almost uselessly
wide category.

> The Standard does not define any category of "Standard C" programs other
> than the above, and the category of "Conforming" programs is so broad that
> I don't think all such programs can be meaningfully described as being in
> the same language, so if you're not referring to the category of "Strictly
> Conforming" programs extended as above, to what are you referring?

There's also this (4p3):

    A program that is correct in all other aspects, operating on correct
    data, containing unspecified behavior shall be a correct program and
    act in accordance with 5.1.2.3.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#104284

Fromsupercat@casperkitty.com
Date2017-02-20 11:15 -0800
Message-ID<771b708b-a48b-4fde-87c1-79bbd7e2676c@googlegroups.com>
In reply to#104280
On Monday, February 20, 2017 at 11:51:47 AM UTC-6, Keith Thompson wrote:
> supercat writes:
> > The Standard defines two classes of programs: those which are Strictly
> > Conforming, and those which are Conforming but not Strictly Conforming.
> > I would interpret the class of "Strictly Conforming" programs as including
> > some which make use of some implementation-defined behaviors but will meet
> > their stated requirements with any combination of such behaviors that
> > conforming implementations could define (and thus to not rely upon any
> > Implementation Defined behaviors being defined in any *particular* fashion).
> 
> Isn't it simpler (and more accurate) just to use the definition in the
> standard?
> 
>     A strictly conforming program shall use only those features
>     of the language and library specified in this International
>     Standard. It shall not produce output dependent on any
>     unspecified, undefined, or implementation-defined behavior,
>     and shall not exceed any minimum implementation limit.
> 
> A program that's required to print the value of INT_MAX will meet its
> stated requirement, but it cannot be strictly conforming because its
> output depends on something that's implementation-defined.  (I'm
> assuming that the implementation-defined value of INT_MAX constitutes
> implementation-defined behavior.  If not, it shouldn't be difficult to
> construct another example.)

I was trying to suggest a guess at what you might be meaning by your use
of the term "Standard C Program".  I think it unlikely that the authors of
the Standard would have expected that recognizing the category of programs
which match their definition of "Strictly Conforming Program" would be more
useful than recognizing the category of programs I described, especially
given that things like the output character set, the relationship between
the first argument given to fopen() and physical disk files, etc. are all
Implementation Defined.

I would say that if a program's stated purpose is to output any odd number
in decimal format, then a program which outputs UINT_MAX in decimal format
would satisfy that requirement regardless of the value of UINT_MAX.  If
one wanted to define a category of programs which were allowed to make use
of Implementation Defined behaviors internally but were required to always
produce the same output regardless of how such behaviors were defined, that
would require adding additional language to define what "the same output"
would mean as applied to systems which handle I/O differently.

> Strict comformance is, as the name implies, a strict requirement, one
> that most programs don't meet.
> 
> A "conforming program" is "one that is acceptable to a conforming
> implementation".  This includes programs that depend on
> implementation-specific extensions, or even on undefined behavior.
> Since a conforming implementation may *accept* a program containing `i =
> i++`, such a program can be "conforming".  It is an almost uselessly
> wide category.

Indeed so.

> > The Standard does not define any category of "Standard C" programs other
> > than the above, and the category of "Conforming" programs is so broad that
> > I don't think all such programs can be meaningfully described as being in
> > the same language, so if you're not referring to the category of "Strictly
> > Conforming" programs extended as above, to what are you referring?
> 
> There's also this (4p3):
> 
>     A program that is correct in all other aspects, operating on correct
>     data, containing unspecified behavior shall be a correct program and
>     act in accordance with 5.1.2.3.

What that means is that use of Unspecified Behavior does not in and of
itself cause a program to fall short of any level of conformance that it
would otherwise achieve unless one of the allowable possibilities for the
behavior in question would cause the program to fail.  I don't see that
as defining any level of conformance.

So again, I ask, what do you mean by a "Standard C program"?  Or, to put it
another way, what must a collection of source text do, and refrain from doing,
to qualify as a "Standard C program"?

[toc] | [prev] | [next] | [standalone]


#104286

FromKeith Thompson <kst-u@mib.org>
Date2017-02-20 11:45 -0800
Message-ID<ln8tp0mysu.fsf@kst-u.example.com>
In reply to#104284
supercat@casperkitty.com writes:
[...]
> So again, I ask, what do you mean by a "Standard C program"?  Or, to
> put it another way, what must a collection of source text do, and
> refrain from doing, to qualify as a "Standard C program"?

As far as I can tell, the first use of the phrase "Standard C program"
is in the article to which I'm replying.  I suggest you figure out who
who, if anyone, actually used that phrase and ask them.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#104289

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-02-20 15:38 -0500
Message-ID<e6d3f0eb-b12b-3029-32b6-43cece886d41@verizon.net>
In reply to#104286
On 02/20/2017 02:45 PM, Keith Thompson wrote:
> supercat@casperkitty.com writes:
> [...]
>> So again, I ask, what do you mean by a "Standard C program"?  Or, to
>> put it another way, what must a collection of source text do, and
>> refrain from doing, to qualify as a "Standard C program"?
>
> As far as I can tell, the first use of the phrase "Standard C program"
> is in the article to which I'm replying.  I suggest you figure out who
> who, if anyone, actually used that phrase and ask them.

He was certainly incorrect to talk about 'your use of the term "Standard 
C Program"' in his response to a message of yours, since you never used 
anything like that term.
However, Tim Rentsch did talk about "programs written in Standard C", 
something that could reasonably be referred to as "Standard C programs".

Since Tim clearly distinguished that category from "strictly conforming 
programs", it's a legitimate question to ask how he defines the term.

The only other conformance category defined by the standard for programs 
is "conforming program". Most things that qualify as a "conforming 
program" according to the C standard could not be sanely referred to as 
"programs written in Standard C". The only feature a program can contain 
that could disqualify it as a conforming program is a #error directive 
that survives conditional compilation. I guarantee you that the "Code of 
Hammurabi" (in the original Akkadian) contains not a single #error 
directive, and therefore qualifies as a conforming C program.

"correct code" is a term used by the standard to explain the fact that a 
program with unspecified behavior should not be considered incorrect 
just because of that fact, and is therefore still constrained by the 
requirements of 5.1.2.3 (which indirectly implies virtually every other 
requirement imposed by the standard).
However, "correct program" doesn't qualify as a conformance category, 
because it must be "correct in all other aspects, operating on correct 
data". "correct in all other aspects" includes correctly meeting the 
program's requirements, which are program-specific. The same is true of 
"correct data". So "correct code" is about a lot more than just 
conformance to the C standard.

If I had to hazard a guess, it would be that Tim's talking about 
programs which don't have undefined behavior, but Tim should be 
answering that question, not me.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web