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


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

Re: Call to a function

Started byTim Rentsch <tr.17687@z991.linuxsc.com>
First post2023-11-10 03:37 -0800
Last post2023-12-24 11:12 -0800
Articles 11 — 5 participants

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

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Call to a function Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-11-10 03:37 -0800
    Re: Call to a function Kaz Kylheku <864-117-4973@kylheku.com> - 2023-11-10 22:04 +0000
      Re: Call to a function Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-11-13 08:14 -0800
    Re: Call to a function Phil Carmody <pc+usenet@asdf.org> - 2023-11-13 21:35 +0200
      Re: Call to a function Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-11-13 12:48 -0800
      Re: Call to a function Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-11-13 19:17 -0800
        Re: Call to a function Phil Carmody <pc+usenet@asdf.org> - 2023-11-16 13:47 +0200
          Re: Call to a function Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-11-16 06:39 -0800
            Re: Call to a function Phil Carmody <pc+usenet@asdf.org> - 2023-11-21 01:29 +0200
              Re: Call to a function James Kuyper <jameskuyper@alumni.caltech.edu> - 2023-11-21 23:21 -0500
              Re: Call to a function Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-12-24 11:12 -0800

#379496 — Re: Call to a function

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2023-11-10 03:37 -0800
SubjectRe: Call to a function
Message-ID<86il69zvno.fsf@linuxsc.com>
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>
>>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>> [...]
>>>
>>>> The point isn't quite the same.  The C standard explicitly says
>>>> integers may be converted to any pointer type.  The C standard
>>>> does not say that a pointer to an object type may be converted
>>>> to a pointer to function type.  Every implementation is within
>>>> its rights to reject any program whose static text includes[*] a
>>>> cast from a pointer to an object type to a pointer to function
>>>> type, regardless of whether the cast has any chance of being
>>>> executed.
>>>>
>>>> [*] meaning, still present as source of any preprocessor
>>>> conditionals have been processed, etc.
>>>
>>> I disagree.  (I think we've discussed this before.)
>>>
>>> Concretely, I believe that this program violates no syntax
>>> error or constraint.  It includes code whose behavior would
>>> be undefined if it were executed, but the `if (0)` prevents
>>> that.
>>>
>>> On what basis do you think a conforming implementation may
>>> reject it?
>>
>> First let me ask a question.  Does the C standard allow an
>> implementation to reject any program that is not strictly
>> conforming?
>
> Not just for that reason.
>
> This program:
>
> #include <stdio.h>
> int main(void) {
>     printf("%zu\n", sizeof (int));
> }
>
> is not strictly conforming, since it depends on the
> implementation-defined size of int.  A hosted implementation
> that rejected it would violate 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.

We have talked before about 4p3.  Your understandings of the
meaning and consequences of this sentence are mistaken, which if
you would take the time to read the published discussion notes
that led up to it being added to the standard I expect you would
realize.  In any case 4p3 is moot, because we are addressing the
qualifying condition:  if an implementation has a legitimate
reason not to accept a given program, then that program is not
"correct in all other aspects", and 4p3 doesn't apply.

Let's consider a concrete example.  This program

    #include <stdio.h>
    #include <stdint.h>

    extern char large[2305843009213693952];

    int
    main( void ){
        printf( "Hello, world\n" );
        printf( "\n" );
        printf( "SIZE_MAX is %21zu\n", SIZE_MAX );
        printf( "  large has %21zu  bytes\n", sizeof large );
        printf( "\n" );
        printf( "(... that's all, folks! ...)\n" );
        return  0;
    }

is, if I am not mistaken, free of any undefined behavior.  It can
be compiled and run, for example by gcc on a 64-bit linux system.
Yet if we ask clang to compile it on the same system, clang gives
an error complaining that the array is too large.  Note that the
same program, except with a one-smaller value of the array
dimension, can be compiled by clang without complaint, and run
successfully.  Clearly the clang implementors feel that the C
standard allows them not to accept this program, and the only
reason I can see for that is that the program is not strictly
conforming, because it exceeds a minimum implementation limit.

Long story short:  in how it treats this program, clang agrees
with my reading of the C standard.  Incidentally, gcc has the
same behavior as clang, only with a larger value of the array
dimension.


> (A perverse implementation could claim that it exceeds its
> capacity, but I think we can ignore that.)

Per the C standard, "capacity" applies to data-processing systems
or to processors, not implementations.  Implementations have
implementation limits, also referred to in the standard as
environmental limits or translation limits.


> What is your answer to your own question?

The C standard requires implementations to accept any strictly
conforming program.  There is no statement in the standard that
requires implementations to accept any program other than those
that are strictly conforming (except perhaps the "one program"
of 5.2.4.1 p1, but implementations are free to choose a strictly
conforming program to satisfy this requirement, so there is no
conflict there).  Hence the C standard allows implementations not
to accept any program that is not strictly conforming.


> And I hope we're not going to go back and forth too many times
> before you answer mine.

Having a shared understanding on this threshold question is a
necessary prerequisite to addressing the larger question.  If you
can't or won't agree that not being strictly conforming is by
itself sufficient basis for not accepting a program, then there
seems little point in continuing, as my answer depends on that
premise for its conclusion.

[toc] | [next] | [standalone]


#379499

FromKaz Kylheku <864-117-4973@kylheku.com>
Date2023-11-10 22:04 +0000
Message-ID<20231110101202.777@kylheku.com>
In reply to#379496
On 2023-11-10, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
> Having a shared understanding on this threshold question is a
> necessary prerequisite to addressing the larger question.  If you
> can't or won't agree that not being strictly conforming is by
> itself sufficient basis for not accepting a program, then there
> seems little point in continuing, as my answer depends on that
> premise for its conclusion.

But the following isn't strictly confroming:

 int x = 65536;

do you think that an implementation whose int is 32 bits wide has
grounds for rejecting it because it's not strictly conforming?

We generally expect correct programs that make use of
implementation-defined characteristics to be translated.

The requirement to accept strictly conforming programs does not add up
to a blanket permission to reject non-strictly conforming programs.

-- 
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca
NOTE: If you use Google Groups, I don't see you, unless you're whitelisted.

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


#379503

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2023-11-13 08:14 -0800
Message-ID<865y25zl37.fsf@linuxsc.com>
In reply to#379499
Kaz Kylheku <864-117-4973@kylheku.com> writes:

> On 2023-11-10, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>
>> Having a shared understanding on this threshold question is a
>> necessary prerequisite to addressing the larger question.  If you
>> can't or won't agree that not being strictly conforming is by
>> itself sufficient basis for not accepting a program, then there
>> seems little point in continuing, as my answer depends on that
>> premise for its conclusion.
>
> But the following isn't strictly confroming:
>
>  int x = 65536;
>
> do you think that an implementation whose int is 32 bits wide has
> grounds for rejecting it because it's not strictly conforming?
>
> We generally expect correct programs that make use of
> implementation-defined characteristics to be translated.
>
> The requirement to accept strictly conforming programs does not add up
> to a blanket permission to reject non-strictly conforming programs.

I think you are in effect asking two question.  The first question
is does the C standard allow non-strictly-conforming code not to be
accepted, even if the code is reasonable for the system being
targeted?  As I read the C standard, the answer to that question is
an unequivocal yes.

The second question is something like, is this a good idea?

Let me give a personal answer.  It doesn't bother me that the C
standard allows such programs not to be accepted (with implied
clause, by conforming implementations).  I say it doesn't bother me
in the same way that the C standard requires implementations to be
able to translate and execute only one program, and still be
conforming.  No compiler worth using is going to reject the
statement 'int x = 65536;' on a 32-bit platform.  Sure, the C
standard allows it, but nobody would use such a compiler, and it's
so much effort to write a C compiler that no one would do that,
except maybe as a joke.  If that's what they want, more power to
them - it will be funny for about 5 minutes.

On the other hand, consider this statement

    long pbits = 0240404242004042424254;

This statement compiles fine on my colo server, which runs linux,
and has 64-bit longs.  But if I were to compile it on a system with
32-bit longs, the compiler is within its rights to say "oops, bad
program, I'm not going to translate this garbage".  Personally I
view that behavior as a positive, so I'm glad the C standard allows
it.

The C standard deliberately sets a low bar.  In practice the low
bar doesn't matter at all, because compiler writers want to produce
a useful, above and beyond what the C standard might require.  And
in those cases like the 'long' assignment example above, there is a
benefit to compilers having the option to turn down the program.
The key phrase there is "having the option".  Different people have
different requirements and want different behaviors.  It's good
that the C standard recognizes that and allows a wide range of
choices, while still setting a reasonable bar for what programs
must be accepted.

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


#379506

FromPhil Carmody <pc+usenet@asdf.org>
Date2023-11-13 21:35 +0200
Message-ID<87a5rh1m5t.fsf@fatphil.org>
In reply to#379496
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>>> [...]
>>>>
>>>>> The point isn't quite the same.  The C standard explicitly says
>>>>> integers may be converted to any pointer type.  The C standard
>>>>> does not say that a pointer to an object type may be converted
>>>>> to a pointer to function type.  Every implementation is within
>>>>> its rights to reject any program whose static text includes[*] a
>>>>> cast from a pointer to an object type to a pointer to function
>>>>> type, regardless of whether the cast has any chance of being
>>>>> executed.
>>>>>
>>>>> [*] meaning, still present as source of any preprocessor
>>>>> conditionals have been processed, etc.
>>>>
>>>> I disagree.  (I think we've discussed this before.)
>>>>
>>>> Concretely, I believe that this program violates no syntax
>>>> error or constraint.  It includes code whose behavior would
>>>> be undefined if it were executed, but the `if (0)` prevents
>>>> that.
>>>>
>>>> On what basis do you think a conforming implementation may
>>>> reject it?
>>>
>>> First let me ask a question.  Does the C standard allow an
>>> implementation to reject any program that is not strictly
>>> conforming?
>>
>> Not just for that reason.
>>
>> This program:
>>
>> #include <stdio.h>
>> int main(void) {
>>     printf("%zu\n", sizeof (int));
>> }
>>
>> is not strictly conforming, since it depends on the
>> implementation-defined size of int.  A hosted implementation
>> that rejected it would violate 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.
>
> We have talked before about 4p3.  Your understandings of the
> meaning and consequences of this sentence are mistaken, which if
> you would take the time to read the published discussion notes
> that led up to it being added to the standard I expect you would
> realize.  In any case 4p3 is moot, because we are addressing the
> qualifying condition:  if an implementation has a legitimate
> reason not to accept a given program, then that program is not
> "correct in all other aspects", and 4p3 doesn't apply.
>
> Let's consider a concrete example.  This program
>
>     #include <stdio.h>
>     #include <stdint.h>
>
>     extern char large[2305843009213693952];
>
>     int
>     main( void ){
>         printf( "Hello, world\n" );
>         printf( "\n" );
>         printf( "SIZE_MAX is %21zu\n", SIZE_MAX );
>         printf( "  large has %21zu  bytes\n", sizeof large );
>         printf( "\n" );
>         printf( "(... that's all, folks! ...)\n" );
>         return  0;
>     }
>
> is, if I am not mistaken, free of any undefined behavior.  It can
> be compiled and run, for example by gcc on a 64-bit linux system.
> Yet if we ask clang to compile it on the same system, clang gives
> an error complaining that the array is too large.  Note that the
> same program, except with a one-smaller value of the array
> dimension, can be compiled by clang without complaint, and run
> successfully.  Clearly the clang implementors feel that the C
> standard allows them not to accept this program, and the only
> reason I can see for that is that the program is not strictly
> conforming, because it exceeds a minimum implementation limit.
>
> Long story short:  in how it treats this program, clang agrees
> with my reading of the C standard.  Incidentally, gcc has the
> same behavior as clang, only with a larger value of the array
> dimension.

Is your conclusion the same if the variable is scrapped and the printf
is given the type instead? clang retains its stance on the concept:

"""
phil@dovespaz:~$ clang -Wall -o crap crap.c
crap.c:11:59: error: array is too large (2305843009213693952 elements)
        printf( "  large has %21zu  bytes\n", sizeof(char[2305843009213693952]));
                                                          ^~~~~~~~~~~~~~~~~~~
1 error generated.
"""

Is there an "array", /per se/? I only see a type.

clang does seem to agree with me that it's a type it's looking at, as if
we try to feed it the expression-only version of sizeof, it notices that
you've given it a type name, not an expression:

"""
phil@dovespaz:~$ clang -Wall -o crap crap.c
crap.c:11:53: error: expected parentheses around type name in sizeof expression
        printf( "  large has %21zu  bytes\n", sizeof char[2305843009213693952]);
                                                    ^
                                                    (                         )
1 error generated.
"""

Phil
-- 
We are no longer hunters and nomads. No longer awed and frightened, as we have
gained some understanding of the world in which we live. As such, we can cast
aside childish remnants from the dawn of our civilization.
-- NotSanguine on SoylentNews, after Eugen Weber in /The Western Tradition/

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


#379507

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2023-11-13 12:48 -0800
Message-ID<87wmule5wq.fsf@nosuchdomain.example.com>
In reply to#379506
Phil Carmody <pc+usenet@asdf.org> writes:
> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
[...]
>> Long story short:  in how it treats this program, clang agrees
>> with my reading of the C standard.  Incidentally, gcc has the
>> same behavior as clang, only with a larger value of the array
>> dimension.
>
> Is your conclusion the same if the variable is scrapped and the printf
> is given the type instead? clang retains its stance on the concept:
>
> """
> phil@dovespaz:~$ clang -Wall -o crap crap.c
> crap.c:11:59: error: array is too large (2305843009213693952 elements)
>         printf( "  large has %21zu  bytes\n", sizeof(char[2305843009213693952]));
>                                                           ^~~~~~~~~~~~~~~~~~~
> 1 error generated.
> """
>
> Is there an "array", /per se/? I only see a type.

I'm not sure what distinction you're making.

I find it useful to think of "array" as an adjective, not a noun.  Of
course there's no array *object* or array *expression* in
`sizeof(char[2305843009213693952]`.  `char[2305843009213693952]` is
obviously an array *type*.  There's no ambiguity here.

> clang does seem to agree with me that it's a type it's looking at, as if
> we try to feed it the expression-only version of sizeof, it notices that
> you've given it a type name, not an expression:
>
> """
> phil@dovespaz:~$ clang -Wall -o crap crap.c
> crap.c:11:53: error: expected parentheses around type name in sizeof expression
>         printf( "  large has %21zu  bytes\n", sizeof char[2305843009213693952]);
>                                                     ^
>                                                     (                         )
> 1 error generated.
> """

Yes, of course it's a type name.  And?

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

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


#379508

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2023-11-13 19:17 -0800
Message-ID<86wmulxbuh.fsf@linuxsc.com>
In reply to#379506
Phil Carmody <pc+usenet@asdf.org> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>
>>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>>
>>>> [...]  Does the C standard allow an
>>>> implementation to reject any program that is not strictly
>>>> conforming?

[...]

>> Let's consider a concrete example.  This program
>>
>>     #include <stdio.h>
>>     #include <stdint.h>
>>
>>     extern char large[2305843009213693952];
>>
>>     int
>>     main( void ){
>>         printf( "Hello, world\n" );
>>         printf( "\n" );
>>         printf( "SIZE_MAX is %21zu\n", SIZE_MAX );
>>         printf( "  large has %21zu  bytes\n", sizeof large );
>>         printf( "\n" );
>>         printf( "(... that's all, folks! ...)\n" );
>>         return  0;
>>     }
>>
>> is, if I am not mistaken, free of any undefined behavior.  It can
>> be compiled and run, for example by gcc on a 64-bit linux system.
>> Yet if we ask clang to compile it on the same system, clang gives
>> an error complaining that the array is too large.  Note that the
>> same program, except with a one-smaller value of the array
>> dimension, can be compiled by clang without complaint, and run
>> successfully.  Clearly the clang implementors feel that the C
>> standard allows them not to accept this program, and the only
>> reason I can see for that is that the program is not strictly
>> conforming, because it exceeds a minimum implementation limit.
>>
>> Long story short:  in how it treats this program, clang agrees
>> with my reading of the C standard.  Incidentally, gcc has the
>> same behavior as clang, only with a larger value of the array
>> dimension.
>
> Is your conclusion the same if the variable is scrapped and the
> printf is given the type instead?

The short answer is yes.

The lower bound for SIZE_MAX is 65535.  As I read the C standard,
any object or any type whose 'sizeof' is bigger than 65535 means
the program exceeds a minimum implementation limit, and is
therefore not strictly conforming.  Because it is not strictly
conforming, implementations are free not to accept it.

> clang retains its stance on the concept:
>
> """
> phil@dovespaz:~$ clang -Wall -o crap crap.c
> crap.c:11:59: error: array is too large (2305843009213693952 elements)
>    printf( "  large has %21zu  bytes\n", sizeof(char[2305843009213693952]));
>                                                      ^~~~~~~~~~~~~~~~~~~
> 1 error generated.
> """
>
> Is there an "array", /per se/?  I only see a type.

An array type, but no array object.  I think most people would say
there isn't an array, but just a type.

> clang does seem to agree with me that it's a type it's looking at,
> [...]

Right, the operand of that sizeof is syntactically a type, not an
expression (or more specifically, what the C standard calls a "type
name").

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


#379511

FromPhil Carmody <pc+usenet@asdf.org>
Date2023-11-16 13:47 +0200
Message-ID<87y1exzzq6.fsf@fatphil.org>
In reply to#379508
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
> Phil Carmody <pc+usenet@asdf.org> writes:
>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>>
>>>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>>>
>>>>> [...]  Does the C standard allow an
>>>>> implementation to reject any program that is not strictly
>>>>> conforming?
>
> [...]
>
>>> Let's consider a concrete example.  This program
>>>
>>>     #include <stdio.h>
>>>     #include <stdint.h>
>>>
>>>     extern char large[2305843009213693952];
>>>
>>>     int
>>>     main( void ){
>>>         printf( "Hello, world\n" );
>>>         printf( "\n" );
>>>         printf( "SIZE_MAX is %21zu\n", SIZE_MAX );
>>>         printf( "  large has %21zu  bytes\n", sizeof large );
>>>         printf( "\n" );
>>>         printf( "(... that's all, folks! ...)\n" );
>>>         return  0;
>>>     }
>>>
>>> is, if I am not mistaken, free of any undefined behavior.  It can
>>> be compiled and run, for example by gcc on a 64-bit linux system.
>>> Yet if we ask clang to compile it on the same system, clang gives
>>> an error complaining that the array is too large.  Note that the
>>> same program, except with a one-smaller value of the array
>>> dimension, can be compiled by clang without complaint, and run
>>> successfully.  Clearly the clang implementors feel that the C
>>> standard allows them not to accept this program, and the only
>>> reason I can see for that is that the program is not strictly
>>> conforming, because it exceeds a minimum implementation limit.
>>>
>>> Long story short:  in how it treats this program, clang agrees
>>> with my reading of the C standard.  Incidentally, gcc has the
>>> same behavior as clang, only with a larger value of the array
>>> dimension.
>>
>> Is your conclusion the same if the variable is scrapped and the
>> printf is given the type instead?
>
> The short answer is yes.
>
> The lower bound for SIZE_MAX is 65535.  As I read the C standard,
> any object or any type whose 'sizeof' is bigger than 65535 means
> the program exceeds a minimum implementation limit, and is
> therefore not strictly conforming.  Because it is not strictly
> conforming, implementations are free not to accept it.

There's wording in the standard to support the "object" claim, but
I'm not seeing direct support for the "type" claim. Of course, there
might be a chain of deductions that leads there.

>> clang retains its stance on the concept:
>>
>> """
>> phil@dovespaz:~$ clang -Wall -o crap crap.c
>> crap.c:11:59: error: array is too large (2305843009213693952 elements)
>>    printf( "  large has %21zu  bytes\n", sizeof(char[2305843009213693952]));
>>                                                      ^~~~~~~~~~~~~~~~~~~
>> 1 error generated.
>> """
>>
>> Is there an "array", /per se/?  I only see a type.
>
> An array type, but no array object.  I think most people would say
> there isn't an array, but just a type.

The standard uses the word "array" as a noun to refer to an array
object, so I was using the same usage as the standard there. And clang
was using that same word, and it was that usage of the word I was
calling into question. Given your similar view, I definitely think the
clang diagnostic is sloppily worded.

>> clang does seem to agree with me that it's a type it's looking at,
>> [...]
>
> Right, the operand of that sizeof is syntactically a type, not an
> expression (or more specifically, what the C standard calls a "type
> name").

Syntactically, yes.

Phil
-- 
We are no longer hunters and nomads. No longer awed and frightened, as we have
gained some understanding of the world in which we live. As such, we can cast
aside childish remnants from the dawn of our civilization.
-- NotSanguine on SoylentNews, after Eugen Weber in /The Western Tradition/

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


#379512

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2023-11-16 06:39 -0800
Message-ID<86o7ftyd71.fsf@linuxsc.com>
In reply to#379511
Phil Carmody <pc+usenet@asdf.org> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Phil Carmody <pc+usenet@asdf.org> writes:
>>
>>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>>
>>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>>>
>>>>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>>>>
>>>>>> [...]  Does the C standard allow an
>>>>>> implementation to reject any program that is not strictly
>>>>>> conforming?
>>
>> [...]
>>
>>>> Let's consider a concrete example.  This program
>>>>
>>>>     #include <stdio.h>
>>>>     #include <stdint.h>
>>>>
>>>>     extern char large[2305843009213693952];
>>>>
>>>>     int
>>>>     main( void ){
>>>>         printf( "Hello, world\n" );
>>>>         printf( "\n" );
>>>>         printf( "SIZE_MAX is %21zu\n", SIZE_MAX );
>>>>         printf( "  large has %21zu  bytes\n", sizeof large );
>>>>         printf( "\n" );
>>>>         printf( "(... that's all, folks! ...)\n" );
>>>>         return  0;
>>>>     }
>>>>
>>>> is, if I am not mistaken, free of any undefined behavior.  It can
>>>> be compiled and run, for example by gcc on a 64-bit linux system.
>>>> Yet if we ask clang to compile it on the same system, clang gives
>>>> an error complaining that the array is too large.  Note that the
>>>> same program, except with a one-smaller value of the array
>>>> dimension, can be compiled by clang without complaint, and run
>>>> successfully.  Clearly the clang implementors feel that the C
>>>> standard allows them not to accept this program, and the only
>>>> reason I can see for that is that the program is not strictly
>>>> conforming, because it exceeds a minimum implementation limit.
>>>>
>>>> Long story short:  in how it treats this program, clang agrees
>>>> with my reading of the C standard.  Incidentally, gcc has the
>>>> same behavior as clang, only with a larger value of the array
>>>> dimension.
>>>
>>> Is your conclusion the same if the variable is scrapped and the
>>> printf is given the type instead?
>>
>> The short answer is yes.
>>
>> The lower bound for SIZE_MAX is 65535.  As I read the C standard,
>> any object or any type whose 'sizeof' is bigger than 65535 means
>> the program exceeds a minimum implementation limit, and is
>> therefore not strictly conforming.  Because it is not strictly
>> conforming, implementations are free not to accept it.
>
> There's wording in the standard to support the "object" claim, but
> I'm not seeing direct support for the "type" claim.  Of course, there
> might be a chain of deductions that leads there.

Here is my reasoning.

The sizeof operator works on both expressions (including expressions
that designate objects) and type names.

The result of sizeof has type size_t.

In <stdint.h>, the preprocessor symbol SIZE_MAX gives the maximum
value (for that implementation) of a value of type size_t.  SIZE_MAX
has a lower bound of 65535 (a minimum implementation limit).  So any
type whose size exceeds this value is violating the restriction that
strictly conforming programs not exceed a minimum implementation
limit.  (Sorry if that was belaboring the obvious.)

Or, here is another way to look at it.

Implemenations are allowed to have size_t be a 16-bit type.  If we
wanted to compile a declaration like

    struct foo { char a[20000], b[20000], c[20000], d[20000]; };

on such an implementation, the implementation would have to refuse
the program, because the size cannot be represented in a 16-bit
size_t (types have sizes even if they are never an operand of a
sizeof expressions).  Strictly conforming programs are intended to
be maximally portable.  Because a program with a type whose size
is more than 65535 cannot be accepted by an implementation with
a 16-bit size_t, the program must not be strictly conforming.


>>> clang retains its stance on the concept:
>>>
>>> """
>>> phil@dovespaz:~$ clang -Wall -o crap crap.c
>>> crap.c:11:59: error: array is too large (2305843009213693952 elements)
>>>   printf( "  large has %21zu  bytes\n", sizeof(char[2305843009213693952]));
>>>                                                     ^~~~~~~~~~~~~~~~~~~
>>> 1 error generated.
>>> """
>>>
>>> Is there an "array", /per se/?  I only see a type.
>>
>> An array type, but no array object.  I think most people would say
>> there isn't an array, but just a type.
>
> The standard uses the word "array" as a noun to refer to an array
> object, so I was using the same usage as the standard there.

Looking through the standard, I see that the word array is used both
as an adjective and as a noun.

> And clang
> was using that same word, and it was that usage of the word I was
> calling into question.  Given your similar view, I definitely think the
> clang diagnostic is sloppily worded.

I am shocked, shocked to discover that a C compiler has a sloppily
worded diagnostic message.

But I agree with your assessment. :)

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


#379538

FromPhil Carmody <pc+usenet@asdf.org>
Date2023-11-21 01:29 +0200
Message-ID<87h6lgovfe.fsf@fatphil.org>
In reply to#379512
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
> Phil Carmody <pc+usenet@asdf.org> writes:
>> There's wording in the standard to support the "object" claim, but
>> I'm not seeing direct support for the "type" claim.  Of course, there
>> might be a chain of deductions that leads there.
>
> Here is my reasoning.
>
> The sizeof operator works on both expressions (including expressions
> that designate objects) and type names.
>
> The result of sizeof has type size_t.
>
> In <stdint.h>, the preprocessor symbol SIZE_MAX gives the maximum
> value (for that implementation) of a value of type size_t.  SIZE_MAX
> has a lower bound of 65535 (a minimum implementation limit).  So any
> type whose size exceeds this value is violating the restriction that
> strictly conforming programs not exceed a minimum implementation
> limit.  (Sorry if that was belaboring the obvious.)

Yup, that has no holes, AFAICS.

>>>> clang retains its stance on the concept:
>>>>
>>>> """
>>>> phil@dovespaz:~$ clang -Wall -o crap crap.c
>>>> crap.c:11:59: error: array is too large (2305843009213693952 elements)
>>>>   printf( "  large has %21zu  bytes\n", sizeof(char[2305843009213693952]));
>>>>                                                     ^~~~~~~~~~~~~~~~~~~
>>>> 1 error generated.
>>>> """
>>>>
>>>> Is there an "array", /per se/?  I only see a type.
>>>
>>> An array type, but no array object.  I think most people would say
>>> there isn't an array, but just a type.
>>
>> The standard uses the word "array" as a noun to refer to an array
>> object, so I was using the same usage as the standard there.
>
> Looking through the standard, I see that the word array is used both
> as an adjective and as a noun.

I only looked through about a third of 1570, but I only saw noun uses.
I saw noun+noun compound nouns, with the first noun being "array", but
that doesn't make the word an adjective.

An actual adjectival use could be:
 *The object is array.
(as per "The bus is red.") the likes of which I couldn't find.

Yes, this is more a.u.e. than c.l.c.

Phil
-- 
We are no longer hunters and nomads. No longer awed and frightened, as we have
gained some understanding of the world in which we live. As such, we can cast
aside childish remnants from the dawn of our civilization.
-- NotSanguine on SoylentNews, after Eugen Weber in /The Western Tradition/

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


#379550

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2023-11-21 23:21 -0500
Message-ID<ujjvkl$16u8a$1@dont-email.me>
In reply to#379538
On 11/20/23 18:29, Phil Carmody wrote:
> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
...
>> Looking through the standard, I see that the word array is used both
>> as an adjective and as a noun.
>
> I only looked through about a third of 1570, but I only saw noun uses.
> I saw noun+noun compound nouns, with the first noun being "array", but
> that doesn't make the word an adjective.

In such usages, "array" is technically referred to as a noun adjunct,
attributive noun, qualifying noun, noun (pre)modifier, or apposite noun
- if there are subtle difference between the meanings of those phrases,
Wikipedia fails to explain them. Like an adjective, such a noun is
defined as modifying the following noun, rather than serving as a noun
in it's own right.

I was completely unaware of any of those terms until I studied what
Wikipedia has to say on the issue just now. For most of my life, that is
precisely what I have described as "a noun serving as an adjective",
because at some point someone taught me to refer to it that way. I
suspect that this is precisely what Tim was referring to. Apparently, a
more correct way to to say what he said would be "Looking through the
standard, I see that the word array is used both to modify other nouns,
and as a noun in its own right."

It doesn't matter what grammar term we use to describe such things.
What's important is that we agree on what the meaning is. A train
station is a station for trains - but it is not in any sense itself a
train. Similarly, an array type is a type that describes an array, but
is not in any sense itself an array. Whether we refer to "array" in the
term "array type" as a noun acting as a verb, or as a noun object is
unimportant.

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


#379634

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2023-12-24 11:12 -0800
Message-ID<861qbbv2i7.fsf@linuxsc.com>
In reply to#379538
Phil Carmody <pc+usenet@asdf.org> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Phil Carmody <pc+usenet@asdf.org> writes:
[...]
>>> The standard uses the word "array" as a noun to refer to an array
>>> object, so I was using the same usage as the standard there.
>>
>> Looking through the standard, I see that the word array is used both
>> as an adjective and as a noun.
>
> I only looked through about a third of 1570, but I only saw noun
> uses.  I saw noun+noun compound nouns, with the first noun being
> "array", but that doesn't make the word an adjective.

I concede your point of grammar (noting that there is some
specialized terminology related to noun+noun phrases, but
I won't quibble about that).

That said, your earlier statement "The standard uses the word
'array' as a noun to refer to an array object" isn't exactly right
either, as for example the phrase "array type".  The word array is
functioning as a modifier, whether we want to call it a noun or an
adjective, and it does not refer to any array object.  Furthermore
using an array type (in a way that is well-defined in C) doesn't
necessarily mean that that there is an array object somewhere.  I
think that is the key point here.

> An actual adjectival use could be:
>  *The object is array.
> (as per "The bus is red.") the likes of which I couldn't find.

Not all adjectives are usable in a "The bus is red" construction.
Many and probabaly even most are, but not all are.

> Yes, this is more a.u.e. than c.l.c.

Noted.  I have tried to focus on the C aspects in my response.

[toc] | [prev] | [standalone]


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


csiph-web