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


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

C declarations

Started byBartC <bc@freeuk.com>
First post2017-01-30 13:00 +0000
Last post2017-03-06 11:27 -0800
Articles 20 on this page of 38 — 11 participants

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


Contents

  C declarations BartC <bc@freeuk.com> - 2017-01-30 13:00 +0000
    Re: C declarations David Brown <david.brown@hesbynett.no> - 2017-01-30 14:25 +0100
      Re: C declarations Keith Thompson <kst-u@mib.org> - 2017-01-30 11:42 -0800
    Re: C declarations Andrey Tarasevich <andreytarasevich@hotmail.com> - 2017-01-31 13:46 -0800
      Re: C declarations BartC <bc@freeuk.com> - 2017-01-31 22:13 +0000
        Re: C declarations Andrey Tarasevich <andreytarasevich@hotmail.com> - 2017-01-31 16:43 -0800
          Re: C declarations Andrey Tarasevich <andreytarasevich@hotmail.com> - 2017-01-31 17:06 -0800
        Re: C declarations Ian Collins <ian-news@hotmail.com> - 2017-02-01 17:58 +1300
          Re: C declarations luser droog <luser.droog@gmail.com> - 2017-01-31 22:42 -0800
            Re: C declarations Ian Collins <ian-news@hotmail.com> - 2017-02-01 19:48 +1300
              Re: C declarations Robert Wessel <robertwessel2@yahoo.com> - 2017-02-01 01:18 -0600
              Re: C declarations David Brown <david.brown@hesbynett.no> - 2017-02-01 10:10 +0100
                Re: C declarations BartC <bc@freeuk.com> - 2017-02-01 11:39 +0000
                  Re: C declarations David Brown <david.brown@hesbynett.no> - 2017-02-01 13:55 +0100
                    Re: C declarations BartC <bc@freeuk.com> - 2017-02-01 13:22 +0000
                      Re: C declarations David Brown <david.brown@hesbynett.no> - 2017-02-01 16:30 +0100
                        Re: C declarations Keith Thompson <kst-u@mib.org> - 2017-02-01 08:15 -0800
                          Re: C declarations supercat@casperkitty.com - 2017-02-01 08:44 -0800
                            Re: C declarations David Brown <david.brown@hesbynett.no> - 2017-02-01 20:56 +0100
                        Re: C declarations supercat@casperkitty.com - 2017-02-01 08:29 -0800
                          Re: C declarations BartC <bc@freeuk.com> - 2017-02-01 17:24 +0000
                            Re: C declarations fir <profesor.fir@gmail.com> - 2017-02-01 09:55 -0800
                              Re: C declarations BartC <bc@freeuk.com> - 2017-02-01 18:44 +0000
                                Re: C declarations Keith Thompson <kst-u@mib.org> - 2017-02-01 11:03 -0800
                                Re: C declarations fir <profesor.fir@gmail.com> - 2017-02-01 12:26 -0800
                                  Re: C declarations fir <profesor.fir@gmail.com> - 2017-02-01 13:03 -0800
                                    Re: C declarations fir <profesor.fir@gmail.com> - 2017-02-01 13:12 -0800
                                    Re: C declarations fir <profesor.fir@gmail.com> - 2017-02-03 16:07 -0800
                            Re: C declarations Keith Thompson <kst-u@mib.org> - 2017-02-01 10:44 -0800
                            Re: C declarations jameskuyper@verizon.net - 2017-02-01 11:08 -0800
                          Re: C declarations Keith Thompson <kst-u@mib.org> - 2017-02-01 10:40 -0800
                        Re: C declarations BartC <bc@freeuk.com> - 2017-02-01 17:04 +0000
                          Re: C declarations Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-01 19:58 +0000
                            Re: C declarations BartC <bc@freeuk.com> - 2017-02-01 21:23 +0000
                      Re: C declarations Keith Thompson <kst-u@mib.org> - 2017-02-01 08:08 -0800
                  Re: C declarations Andrey Tarasevich <andreytarasevich@hotmail.com> - 2017-02-01 12:45 -0800
    Re: C declarations Andrey Tarasevich <andreytarasevich@hotmail.com> - 2017-03-06 11:19 -0800
      Re: C declarations Keith Thompson <kst-u@mib.org> - 2017-03-06 11:27 -0800

Page 1 of 2  [1] 2  Next page →


#102748 — C declarations

FromBartC <bc@freeuk.com>
Date2017-01-30 13:00 +0000
SubjectC declarations
Message-ID<o6nd9u$rp1$1@dont-email.me>
I've been studying C's syntax in a bit more detail and trying to match 
up what a compiler allows, with the grammar. Here's one example:

   #include <stdio.h>

   a=10, b=20, c=30;

   int main(void){}

This compiles fine. But not if the declarations are inside a function. I 
can't see where this is specified in the grammar at the back of K&R2, 
which only seems to allow a default type-specifier when a is a function 
definition (and '=10', b, c and the rest wouldn't be allowed). With the 
2011 version in the standard, it isn't allowed at all that I can see.

Then there is this, also outside a function, although more compilers 
complain about it:

   *p = 10;

This presumably declares p to be of type int*, and initialises it to 10.

Furthermore, I can write:

           *p = 10;        // outside a function
and:      *p = 10;        // inside a function

and that will compile (although fewer compilers accept it), using the 
same 'p', but do different things.

If writing a C parser, does one need to accommodate all this stuff or 
not? *p probably be dispensed with, and maybe a=10 too. But I think 
implicit return types for functions still crop up. And they /could/ be 
written like this:

((((main())))){};

but not like this:

((((main(()))))){};

as it's an error!

-- 
bartc

[toc] | [next] | [standalone]


#102753

FromDavid Brown <david.brown@hesbynett.no>
Date2017-01-30 14:25 +0100
Message-ID<o6nepi$1l5$1@dont-email.me>
In reply to#102748
On 30/01/17 14:00, BartC wrote:
> I've been studying C's syntax in a bit more detail and trying to match
> up what a compiler allows, with the grammar. Here's one example:
> 
>   #include <stdio.h>
> 
>   a=10, b=20, c=30;
> 
>   int main(void){}
> 
> This compiles fine. 

By "compiles fine", you mean when you ask the compiler to use a 25 year
old standard and specifically disable default warning messages?

Yes, this is legal in C90 and before.  It is usually considered bad
code, but it is legal AFAIK.

> But not if the declarations are inside a function. I
> can't see where this is specified in the grammar at the back of K&R2,
> which only seems to allow a default type-specifier when a is a function
> definition (and '=10', b, c and the rest wouldn't be allowed). With the
> 2011 version in the standard, it isn't allowed at all that I can see.

"Implicit int" was dropped in C99, in all cases.

In C90, you need /something/ to tell the compiler that "a = 10;" is a
definition and not just using an external symbol.  You can do that with
a type "int a = 10;", or with "auto a = 10;" or "register a = 10;", both
of which make the type "int" by default.

> 
> Then there is this, also outside a function, although more compilers
> complain about it:
> 
>   *p = 10;
> 
> This presumably declares p to be of type int*, and initialises it to 10.

Again, I believe it is legal syntax in C90.  It has undefined behaviour
(due to the conversion from an integer).

> 
> Furthermore, I can write:
> 
>           *p = 10;        // outside a function
> and:      *p = 10;        // inside a function
> 
> and that will compile (although fewer compilers accept it), using the
> same 'p', but do different things.

When you put "*p = 10;" as a declaration, you are initialising "p" to
10.  When you write "*p = 10;" as a statement, it is assigning 10 to the
int pointed to by p.

The standards committee were doing the right thing when they killed off
"implicit int" in C99 !

> 
> If writing a C parser, does one need to accommodate all this stuff or
> not? *p probably be dispensed with, and maybe a=10 too. But I think
> implicit return types for functions still crop up. And they /could/ be
> written like this:
> 
> ((((main())))){};
> 
> but not like this:
> 
> ((((main(()))))){};
> 
> as it's an error!
> 

If you are writing a C parser today, you might want to make it C99 and
C11, and disregard C90 or before.  A good deal of C90 code is also
perfectly valid C99 code - certainly all the C90 code I have written
would be fine as C99.  And I think the key reason for writing C90 (also
known, slightly inaccurately, as "ANSI C") today is for portability -
that includes portability to C99 compilers.

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


#102787

FromKeith Thompson <kst-u@mib.org>
Date2017-01-30 11:42 -0800
Message-ID<lnwpdc9vwe.fsf@kst-u.example.com>
In reply to#102753
David Brown <david.brown@hesbynett.no> writes:
> On 30/01/17 14:00, BartC wrote:
[...]
>> Then there is this, also outside a function, although more compilers
>> complain about it:
>> 
>>   *p = 10;
>> 
>> This presumably declares p to be of type int*, and initialises it to 10.
>
> Again, I believe it is legal syntax in C90.  It has undefined behaviour
> (due to the conversion from an integer).

I believe it's legal syntax, but it's a constraint violation.  There is
no implicit conversion from int to int* (other than the special case of
a null pointer constant).

Pre-ANSI C compilers commonly permitted implicit conversions between
pointers and integers, but C89/C90 did 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]


#102880

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2017-01-31 13:46 -0800
Message-ID<o6r0gj$4di$1@dont-email.me>
In reply to#102748
On 1/30/2017 5:00 AM, BartC wrote:
> I've been studying C's syntax in a bit more detail and trying to match
> up what a compiler allows, with the grammar. Here's one example:
>
>   #include <stdio.h>
>
>   a=10, b=20, c=30;
>
>   int main(void){}
>
> This compiles fine.

I can't say for sure if this was OK in K&R, but in the standard C (even 
in the first C89/90) this is already illegal. The grammar for 
_declaration_ requires at least a storage class specifier, a 
type-specifier or a type qualifier to be present. Which means that if 
you wanted to take advantage of the "implicit int" rule in C89/90, you'd 
have to do at least

     static a = 10, b = 20, c = 30;

or, say,

     const a = 10, b = 20, c = 30;

What you have in your original code is not compliant with C89/90 
requirements.

> But not if the declarations are inside a function.

The requirements are the same for local declarations. There should be no 
difference in this specific regard.

> Then there is this, also outside a function, although more compilers
> complain about it:
>
>   *p = 10;
>
> This presumably declares p to be of type int*, and initialises it to 10.

Same thing. In C89/90 you'd need at least something like

     static *p = 0;

(and, of course, your `10` is not a legal initializer for a pointer).

-- 
Best regards,
Andrey Tarasevich

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


#102885

FromBartC <bc@freeuk.com>
Date2017-01-31 22:13 +0000
Message-ID<o6r22b$ab3$1@dont-email.me>
In reply to#102880
On 31/01/2017 21:46, Andrey Tarasevich wrote:
> On 1/30/2017 5:00 AM, BartC wrote:
>> I've been studying C's syntax in a bit more detail and trying to match
>> up what a compiler allows, with the grammar. Here's one example:
>>
>>   #include <stdio.h>
>>
>>   a=10, b=20, c=30;
>>
>>   int main(void){}
>>
>> This compiles fine.
>
> I can't say for sure if this was OK in K&R, but in the standard C (even
> in the first C89/90) this is already illegal. The grammar for
> _declaration_ requires at least a storage class specifier, a
> type-specifier or a type qualifier to be present. Which means that if
> you wanted to take advantage of the "implicit int" rule in C89/90, you'd
> have to do at least
>
>     static a = 10, b = 20, c = 30;
>
> or, say,
>
>     const a = 10, b = 20, c = 30;
>
> What you have in your original code is not compliant with C89/90
> requirements.

Out of six compilers, three gave a warning about an implicit int, the 
other three said nothing at all. That doesn't suggest to me that they 
consider there to be anything much wrong with it.

>
>> But not if the declarations are inside a function.
>
> The requirements are the same for local declarations. There should be no
> difference in this specific regard.

All six compilers report an error (not a warning) when the same code is 
inside a function. (Undeclared identifier.)

But then, in a function, a=10 looks like an assignment. Outside, it 
can't be an assignment.

-- 
Bartc

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


#102890

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2017-01-31 16:43 -0800
Message-ID<o6ras7$845$1@dont-email.me>
In reply to#102885
On 1/31/2017 2:13 PM, BartC wrote:
>>
>> I can't say for sure if this was OK in K&R, but in the standard C (even
>> in the first C89/90) this is already illegal. The grammar for
>> _declaration_ requires at least a storage class specifier, a
>> type-specifier or a type qualifier to be present. Which means that if
>> you wanted to take advantage of the "implicit int" rule in C89/90, you'd
>> have to do at least
>>
>>     static a = 10, b = 20, c = 30;
>>
>> or, say,
>>
>>     const a = 10, b = 20, c = 30;
>>
>> What you have in your original code is not compliant with C89/90
>> requirements.
>
> Out of six compilers, three gave a warning about an implicit int,

It is already perfectly enough. With C compilers, it is generally your 
responsibility to tell "mere warnings" from "warnings" that indicate 
constraint violations (i.e. "errors").

> the
> other three said nothing at all. That doesn't suggest to me that they
> consider there to be anything much wrong with it.

I wonder what those compilers might be.

I quick experiment with GCC and Clang in `-pedantic-errors` mode shows 
them to report an error

     error: data definition has no type or storage class

and

     error: declaration specifier missing, defaulting to 'int'

respectively.

I was unable to force MSVC to generate an "error", but their warning 
message was clear

     warning C4218: nonstandard extension used: must specify at least a 
storage class or a type

> All six compilers report an error (not a warning) when the same code is
> inside a function. (Undeclared identifier.)

Distinction between "errors" and "warnings" says absolutely nothing 
about the validity of the code in such compilers as GCC and Clang. You 
have to use `-pedantic-errors` mode to make these compilers to report 
all constraint-violation-related "warnings" (and only such "warnings") 
as "errors". It is still not perfect, but it works most of the time.

As you already noticed, most C compilers in existence would allow you to do

     int *p = 10;

That does not mean that this is a valid C initialization.

These compilers are still trying to be compatible with legacy K&R code.

-- 
Best regards,
Andrey Tarasevich

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


#102891

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2017-01-31 17:06 -0800
Message-ID<o6rc79$bpg$1@dont-email.me>
In reply to#102890
On 1/31/2017 4:43 PM, Andrey Tarasevich wrote:
>
> These compilers are still trying to be compatible with legacy K&R code.
>

The C89/90 grammar says

     declaration:
       declaration-specifiers init-declarator-list[opt];

     declaration-specifiers:
       storage-class-specifier declaration-specifiers[opt]
       type-specifier declaration-specifiers[opt]
       type-qualifier declaration-specifiers[opt]

and then

     type-specifier:
       void
       char
       short
       int
       long
       float
       double
       signed
       unsigned
       struct-or-union-specifier
       enum-specifier
       typedef-name

This leaves no possibility of having an empty set of 
'declaration-specifers'. In this grammar there's no way do derive a lone 
'a = 10;' in the middle of the file .

Later in the text it says

     "Each list of type specifiers shall be one of the following sets:
      ...
      - int, signed, signed int, or no type specifiers
      ..."

But even tough it says "or no type specifiers", this does not override 
the requirements of the grammar. The "no type specifiers" part simply 
means that the set of 'type-specifier' sequence can be empty if 
'storage-class-specifier' or 'type-qualifier' is present.

-- 
Best regards,
Andrey Tarasevich

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


#102893

FromIan Collins <ian-news@hotmail.com>
Date2017-02-01 17:58 +1300
Message-ID<efd881FhgsiU1@mid.individual.net>
In reply to#102885
On 02/ 1/17 11:13 AM, BartC wrote:
> On 31/01/2017 21:46, Andrey Tarasevich wrote:
>> On 1/30/2017 5:00 AM, BartC wrote:
>>> I've been studying C's syntax in a bit more detail and trying to match
>>> up what a compiler allows, with the grammar. Here's one example:
>>>
>>>    #include <stdio.h>
>>>
>>>    a=10, b=20, c=30;
>>>
>>>    int main(void){}
>>>
>>> This compiles fine.
>>
>> I can't say for sure if this was OK in K&R, but in the standard C (even
>> in the first C89/90) this is already illegal. The grammar for
>> _declaration_ requires at least a storage class specifier, a
>> type-specifier or a type qualifier to be present. Which means that if
>> you wanted to take advantage of the "implicit int" rule in C89/90, you'd
>> have to do at least
>>
>>      static a = 10, b = 20, c = 30;
>>
>> or, say,
>>
>>      const a = 10, b = 20, c = 30;
>>
>> What you have in your original code is not compliant with C89/90
>> requirements.
>
> Out of six compilers, three gave a warning about an implicit int, the
> other three said nothing at all.

Care to name and shame?

-- 
Ian

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


#102895

Fromluser droog <luser.droog@gmail.com>
Date2017-01-31 22:42 -0800
Message-ID<3fd6c360-cd60-4d22-b7c6-4ac75ab206c3@googlegroups.com>
In reply to#102893
On Tuesday, January 31, 2017 at 10:58:49 PM UTC-6, Ian Collins wrote:
> On 02/ 1/17 11:13 AM, BartC wrote:
> > On 31/01/2017 21:46, Andrey Tarasevich wrote:
> >> On 1/30/2017 5:00 AM, BartC wrote:
> >>> I've been studying C's syntax in a bit more detail and trying to match
> >>> up what a compiler allows, with the grammar. Here's one example:
> >>>
> >>>    #include <stdio.h>
> >>>
> >>>    a=10, b=20, c=30;
> >>>
> >>>    int main(void){}
> >>>
> >>> This compiles fine.
> >>
> >> I can't say for sure if this was OK in K&R, but in the standard C (even
> >> in the first C89/90) this is already illegal. The grammar for
> >> _declaration_ requires at least a storage class specifier, a
> >> type-specifier or a type qualifier to be present. Which means that if
> >> you wanted to take advantage of the "implicit int" rule in C89/90, you'd
> >> have to do at least
> >>
> >>      static a = 10, b = 20, c = 30;
> >>
> >> or, say,
> >>
> >>      const a = 10, b = 20, c = 30;
> >>
> >> What you have in your original code is not compliant with C89/90
> >> requirements.
> >
> > Out of six compilers, three gave a warning about an implicit int, the
> > other three said nothing at all.
> 
> Care to name and shame?
> 

I think we can all see the whodunit that the compilers
were almost certainly invoked in a (default) mode
which does not purport to be strictly standards-conforming.

-- 
wrench library col mustard

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


#102896

FromIan Collins <ian-news@hotmail.com>
Date2017-02-01 19:48 +1300
Message-ID<efdemaFhgsiU2@mid.individual.net>
In reply to#102895
On 02/ 1/17 07:42 PM, luser droog wrote:
> On Tuesday, January 31, 2017 at 10:58:49 PM UTC-6, Ian Collins wrote:
>> On 02/ 1/17 11:13 AM, BartC wrote:
>>> On 31/01/2017 21:46, Andrey Tarasevich wrote:
>>>> On 1/30/2017 5:00 AM, BartC wrote:
>>>>> I've been studying C's syntax in a bit more detail and trying to match
>>>>> up what a compiler allows, with the grammar. Here's one example:
>>>>>
>>>>>     #include <stdio.h>
>>>>>
>>>>>     a=10, b=20, c=30;
>>>>>
>>>>>     int main(void){}
>>>>>
>>>>> This compiles fine.
>>>>
>>>> I can't say for sure if this was OK in K&R, but in the standard C (even
>>>> in the first C89/90) this is already illegal. The grammar for
>>>> _declaration_ requires at least a storage class specifier, a
>>>> type-specifier or a type qualifier to be present. Which means that if
>>>> you wanted to take advantage of the "implicit int" rule in C89/90, you'd
>>>> have to do at least
>>>>
>>>>       static a = 10, b = 20, c = 30;
>>>>
>>>> or, say,
>>>>
>>>>       const a = 10, b = 20, c = 30;
>>>>
>>>> What you have in your original code is not compliant with C89/90
>>>> requirements.
>>>
>>> Out of six compilers, three gave a warning about an implicit int, the
>>> other three said nothing at all.
>>
>> Care to name and shame?
>>
>
> I think we can all see the whodunit that the compilers
> were almost certainly invoked in a (default) mode
> which does not purport to be strictly standards-conforming.

Even unadorned gcc complains...

-- 
Ian

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


#102897

FromRobert Wessel <robertwessel2@yahoo.com>
Date2017-02-01 01:18 -0600
Message-ID<eg239cd8il53hh3i99bdjs1a2mv78d70pl@4ax.com>
In reply to#102896
On Wed, 1 Feb 2017 19:48:42 +1300, Ian Collins <ian-news@hotmail.com>
wrote:

>On 02/ 1/17 07:42 PM, luser droog wrote:
>> On Tuesday, January 31, 2017 at 10:58:49 PM UTC-6, Ian Collins wrote:
>>> On 02/ 1/17 11:13 AM, BartC wrote:
>>>> On 31/01/2017 21:46, Andrey Tarasevich wrote:
>>>>> On 1/30/2017 5:00 AM, BartC wrote:
>>>>>> I've been studying C's syntax in a bit more detail and trying to match
>>>>>> up what a compiler allows, with the grammar. Here's one example:
>>>>>>
>>>>>>     #include <stdio.h>
>>>>>>
>>>>>>     a=10, b=20, c=30;
>>>>>>
>>>>>>     int main(void){}
>>>>>>
>>>>>> This compiles fine.
>>>>>
>>>>> I can't say for sure if this was OK in K&R, but in the standard C (even
>>>>> in the first C89/90) this is already illegal. The grammar for
>>>>> _declaration_ requires at least a storage class specifier, a
>>>>> type-specifier or a type qualifier to be present. Which means that if
>>>>> you wanted to take advantage of the "implicit int" rule in C89/90, you'd
>>>>> have to do at least
>>>>>
>>>>>       static a = 10, b = 20, c = 30;
>>>>>
>>>>> or, say,
>>>>>
>>>>>       const a = 10, b = 20, c = 30;
>>>>>
>>>>> What you have in your original code is not compliant with C89/90
>>>>> requirements.
>>>>
>>>> Out of six compilers, three gave a warning about an implicit int, the
>>>> other three said nothing at all.
>>>
>>> Care to name and shame?
>>>
>>
>> I think we can all see the whodunit that the compilers
>> were almost certainly invoked in a (default) mode
>> which does not purport to be strictly standards-conforming.
>
>Even unadorned gcc complains...


FWIW, MS VS2010 complains at higher warning levels (but not by
default).  Accepting that form appears to date back to at least MSC
5.1 (circa 1988), so I'd guess a default extension* that's been left
enabled for compatibility.

*Or at least now it's an extension, harder to say what to call it in
1988.

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


#102899

FromDavid Brown <david.brown@hesbynett.no>
Date2017-02-01 10:10 +0100
Message-ID<o6s8i9$cuj$1@dont-email.me>
In reply to#102896
On 01/02/17 07:48, Ian Collins wrote:
> On 02/ 1/17 07:42 PM, luser droog wrote:
>> On Tuesday, January 31, 2017 at 10:58:49 PM UTC-6, Ian Collins wrote:
>>> On 02/ 1/17 11:13 AM, BartC wrote:
>>>> On 31/01/2017 21:46, Andrey Tarasevich wrote:
>>>>> On 1/30/2017 5:00 AM, BartC wrote:
>>>>>> I've been studying C's syntax in a bit more detail and trying to
>>>>>> match
>>>>>> up what a compiler allows, with the grammar. Here's one example:
>>>>>>
>>>>>>     #include <stdio.h>
>>>>>>
>>>>>>     a=10, b=20, c=30;
>>>>>>
>>>>>>     int main(void){}
>>>>>>
>>>>>> This compiles fine.
>>>>>
>>>>> I can't say for sure if this was OK in K&R, but in the standard C
>>>>> (even
>>>>> in the first C89/90) this is already illegal. The grammar for
>>>>> _declaration_ requires at least a storage class specifier, a
>>>>> type-specifier or a type qualifier to be present. Which means that if
>>>>> you wanted to take advantage of the "implicit int" rule in C89/90,
>>>>> you'd
>>>>> have to do at least
>>>>>
>>>>>       static a = 10, b = 20, c = 30;
>>>>>
>>>>> or, say,
>>>>>
>>>>>       const a = 10, b = 20, c = 30;
>>>>>
>>>>> What you have in your original code is not compliant with C89/90
>>>>> requirements.
>>>>
>>>> Out of six compilers, three gave a warning about an implicit int, the
>>>> other three said nothing at all.
>>>
>>> Care to name and shame?
>>>
>>
>> I think we can all see the whodunit that the compilers
>> were almost certainly invoked in a (default) mode
>> which does not purport to be strictly standards-conforming.
> 
> Even unadorned gcc complains...
> 

It all depends on what Bart means by "compiles fine".  Unadorned gcc
will happily compile:

a = 10, b = 20, c = 30;

int main(void) { }

It /will/ give a warning "data definition has no type or storage class",
but it will compile the code just as though the missing "int" was there.
 I can't find any way to turn off the warning, which is probably a good
thing.

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


#102901

FromBartC <bc@freeuk.com>
Date2017-02-01 11:39 +0000
Message-ID<o6sha6$a6l$1@dont-email.me>
In reply to#102899
On 01/02/2017 09:10, David Brown wrote:
> On 01/02/17 07:48, Ian Collins wrote:

>>>> Care to name and shame?

The ones that gave warnings without any extra options were Pelles C, 
lccwin, and gcc. The other three that said nothing nothing were DMC, 
Tiny C and MSVC-2008.

>> Even unadorned gcc complains...

It doesn't complain very strongly. I couldn't see from the grammar of 
any C version that 'a=10;' was legal outside of a function.

> It all depends on what Bart means by "compiles fine".  Unadorned gcc
> will happily compile:
>
> a = 10, b = 20, c = 30;
>
> int main(void) { }
>
> It /will/ give a warning "data definition has no type or storage class",
> but it will compile the code just as though the missing "int" was there.
>  I can't find any way to turn off the warning, which is probably a good
> thing.

The problem is this, if you are trying to implement such a parser: do 
you deal with this strictly according to the grammar (and disallow it 
completely)? That sounds a good idea, but then it will reject code that 
will be passed by most other compilers with little problem.

However, the grammar also seems to allow these:

const const const a;          // no initial value
int int int b;

gcc allows the first (but 'implicit int'), and disallows the second 
(more than one type specifier).

(It seems crazy to me that a grammar could be so sloppy and ambiguous, 
requiring masses of notes to clarify what is legal and what isn't. And I 
couldn't even find the notes pertaining to the int int int; I have to 
rely on trial and error using a well-regarded compiler (gcc).

It's so easy to get right. Although C's untidy scheme where 'int' and 
'long' are both independent type-specs, but 'long' can also be a 
modifier to 'int', doesn't help. And 'int static const unsigned const 
long const long volatile' is legal... What a language!)

-- 
Bartc

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


#102904

FromDavid Brown <david.brown@hesbynett.no>
Date2017-02-01 13:55 +0100
Message-ID<o6slob$pkf$1@dont-email.me>
In reply to#102901
On 01/02/17 12:39, BartC wrote:
> On 01/02/2017 09:10, David Brown wrote:
>> On 01/02/17 07:48, Ian Collins wrote:
> 
>>>>> Care to name and shame?
> 
> The ones that gave warnings without any extra options were Pelles C,
> lccwin, and gcc. The other three that said nothing nothing were DMC,
> Tiny C and MSVC-2008.
> 
>>> Even unadorned gcc complains...
> 
> It doesn't complain very strongly. I couldn't see from the grammar of
> any C version that 'a=10;' was legal outside of a function.
> 
>> It all depends on what Bart means by "compiles fine".  Unadorned gcc
>> will happily compile:
>>
>> a = 10, b = 20, c = 30;
>>
>> int main(void) { }
>>
>> It /will/ give a warning "data definition has no type or storage class",
>> but it will compile the code just as though the missing "int" was there.
>>  I can't find any way to turn off the warning, which is probably a good
>> thing.
> 
> The problem is this, if you are trying to implement such a parser: do
> you deal with this strictly according to the grammar (and disallow it
> completely)? That sounds a good idea, but then it will reject code that
> will be passed by most other compilers with little problem.
> 

It is fine to reject something that the grammar does not allow.  It is
also fine to require code that is compatible with modern standards (C99
onwards).  It is not unreasonable to consider accepting something
outside the grammar if it is in common use, supported by other tools,
and it would annoy your users if were /not/ supported by your tool.
However, I really can't see that applying in this case.

> However, the grammar also seems to allow these:
> 
> const const const a;          // no initial value
> int int int b;
> 
> gcc allows the first (but 'implicit int'), and disallows the second
> (more than one type specifier).
> 
> (It seems crazy to me that a grammar could be so sloppy and ambiguous,
> requiring masses of notes to clarify what is legal and what isn't. And I
> couldn't even find the notes pertaining to the int int int; I have to
> rely on trial and error using a well-regarded compiler (gcc).
> 
> It's so easy to get right. Although C's untidy scheme where 'int' and
> 'long' are both independent type-specs, but 'long' can also be a
> modifier to 'int', doesn't help. And 'int static const unsigned const
> long const long volatile' is legal... What a language!)
> 

Section 6.7.2 of N1570 (C11 draft) seems reasonably clear to me.  "int
int" is not allowed - you can have /one/ list of type specifier from the
list given under "constraints".

On the other had, it is perfectly reasonable to allow more than one
"const" or other type qualifier in the same declaration - this allows
you to have "typedef const char cchar;" and then "const cchar c = 'a';".
 Again, it is clear in the standards - section 6.7.3.

If you have been reading Annex A "(Informative) Language syntax summary"
and assuming that the BNF grammar covered all the details, you are bound
to make this sort of mistake.  You have to read the actual standards to
see all the constraints - there is a reason why Annex A is labelled
"Informative".

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


#102905

FromBartC <bc@freeuk.com>
Date2017-02-01 13:22 +0000
Message-ID<o6snb9$v37$1@dont-email.me>
In reply to#102904
On 01/02/2017 12:55, David Brown wrote:
> On 01/02/17 12:39, BartC wrote:


>> (It seems crazy to me that a grammar could be so sloppy and ambiguous,
>> requiring masses of notes to clarify what is legal and what isn't. And I
>> couldn't even find the notes pertaining to the int int int; I have to
>> rely on trial and error using a well-regarded compiler (gcc).
>>
>> It's so easy to get right. Although C's untidy scheme where 'int' and
>> 'long' are both independent type-specs, but 'long' can also be a
>> modifier to 'int', doesn't help. And 'int static const unsigned const
>> long const long volatile' is legal... What a language!)
>>
>
> Section 6.7.2 of N1570 (C11 draft) seems reasonably clear to me.  "int
> int" is not allowed - you can have /one/ list of type specifier from the
> list given under "constraints".

Oh, OK, I didn't get that far! But it has to resort to listing all the 
combinations (but not the permutations) that are allowed. And which may 
be intermixed with other attributes. This is not very elegant (nor 
efficient) to parse and to check.

(I notice you shouldn't use _Complex by itself, but have to combine it 
with float or double, which I hadn't realised. Yet usually you can. More 
laxity on the part of compilers.)

> On the other had, it is perfectly reasonable to allow more than one
> "const" or other type qualifier in the same declaration - this allows
> you to have "typedef const char cchar;" and then "const cchar c = 'a';".
>  Again, it is clear in the standards - section 6.7.3.
>
> If you have been reading Annex A "(Informative) Language syntax summary"
> and assuming that the BNF grammar covered all the details, you are bound
> to make this sort of mistake.  You have to read the actual standards to
> see all the constraints - there is a reason why Annex A is labelled
> "Informative".

So the language /was/ informally thrown together (understandable in 
1970), and only later were attempts made to properly define it. When it 
was presumably a little too late.

-- 
Bartc

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


#102906

FromDavid Brown <david.brown@hesbynett.no>
Date2017-02-01 16:30 +0100
Message-ID<o6suqv$q9r$1@dont-email.me>
In reply to#102905
On 01/02/17 14:22, BartC wrote:
> On 01/02/2017 12:55, David Brown wrote:
>> On 01/02/17 12:39, BartC wrote:
> 
> 
>>> (It seems crazy to me that a grammar could be so sloppy and ambiguous,
>>> requiring masses of notes to clarify what is legal and what isn't. And I
>>> couldn't even find the notes pertaining to the int int int; I have to
>>> rely on trial and error using a well-regarded compiler (gcc).
>>>
>>> It's so easy to get right. Although C's untidy scheme where 'int' and
>>> 'long' are both independent type-specs, but 'long' can also be a
>>> modifier to 'int', doesn't help. And 'int static const unsigned const
>>> long const long volatile' is legal... What a language!)
>>>
>>
>> Section 6.7.2 of N1570 (C11 draft) seems reasonably clear to me.  "int
>> int" is not allowed - you can have /one/ list of type specifier from the
>> list given under "constraints".
> 
> Oh, OK, I didn't get that far! 

How can you be writing a parser, and complaining about what C does and
does not allow, and how other compilers match the standards, when you
haven't even bothered to /read/ the standards?  How are you making
making your code at the moment - by skim-reading a couple of Wikipedia
articles then some trial-and-error runs with a few existing compilers?

> But it has to resort to listing all the
> combinations (but not the permutations) that are allowed. And which may
> be intermixed with other attributes. This is not very elegant (nor
> efficient) to parse and to check.

The language has historical baggage.  This is no surprise - its 40 years
old and has gone through many revisions.  Originally there was only
"int" and "double", and other types had to be added in a way that
allowed existing code to keep working.  The result is a bit less
consistent than if it had been designed with advice from
time-travellers.  You can do better when designing a /new/ language, but
with C you have to live with what we have.

> 
> (I notice you shouldn't use _Complex by itself, but have to combine it
> with float or double, which I hadn't realised. Yet usually you can. More
> laxity on the part of compilers.)

It doesn't /matter/.  Your parser does not need to accept "_Complex" on
its own, because that would be an error.  Or you can choose to accept it
as meaning "_Complex double" like many other compilers.  You are even
free to interpret a plain "_Complex" as the same as "_Bool" if you like
- it would still be conforming to the standards even if it would be
rather unhelpful to users.

> 
>> On the other had, it is perfectly reasonable to allow more than one
>> "const" or other type qualifier in the same declaration - this allows
>> you to have "typedef const char cchar;" and then "const cchar c = 'a';".
>>  Again, it is clear in the standards - section 6.7.3.
>>
>> If you have been reading Annex A "(Informative) Language syntax summary"
>> and assuming that the BNF grammar covered all the details, you are bound
>> to make this sort of mistake.  You have to read the actual standards to
>> see all the constraints - there is a reason why Annex A is labelled
>> "Informative".
> 
> So the language /was/ informally thrown together (understandable in
> 1970), and only later were attempts made to properly define it. When it
> was presumably a little too late.
> 

Yes, the language was used for quite a while before there was a proper
standard.  And the language changed underway while it was in use.  I
know you like to put your fingers in your ears and sing "la, la, la" to
a lot of what people try to tell you about C in this newsgroup, but
surely it cannot be a surprise to you that C is a language with old roots?

But that has nothing to do with the fact that the standards committee
decided to specify the syntax of the language using a combination of BNF
and some constraints, rather than making a significantly more complex
BNF grammar.  The constraints for type specifiers could, I believe, have
been expressed in BNF - but doing so would make it harder to understand.

If you are interested in making a C parser, read current C standards
documents and learn the details.  If you are interested in C history,
read up about that.

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


#102909

FromKeith Thompson <kst-u@mib.org>
Date2017-02-01 08:15 -0800
Message-ID<ln7f5999bi.fsf@kst-u.example.com>
In reply to#102906
David Brown <david.brown@hesbynett.no> writes:
[...]
> But that has nothing to do with the fact that the standards committee
> decided to specify the syntax of the language using a combination of BNF
> and some constraints, rather than making a significantly more complex
> BNF grammar.  The constraints for type specifiers could, I believe, have
> been expressed in BNF - but doing so would make it harder to understand.

Expressing those constraints in BNF would have been tedious and would
have made the grammar substantially larger.  The type "unsigned long"
can also be written as "long unsigned", and there is code that depends
on that.  Rather than permitting only the commonly used orders (whatever
they are), the standard allows any order.

A BNF grammar that permits `long unsigned int long` but forbids
`int unsigned int long` would be unwieldy, especially when other
keywords like const can legally be interspersed.

It probably would have been better to have a more restrictive grammar
from the beginning, but that wasn't practical.

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


#102912

Fromsupercat@casperkitty.com
Date2017-02-01 08:44 -0800
Message-ID<6d66a487-b263-403f-8d05-2474d41ae2b9@googlegroups.com>
In reply to#102909
On Wednesday, February 1, 2017 at 10:14:01 AM UTC-6, Keith Thompson wrote:
> It probably would have been better to have a more restrictive grammar
> from the beginning, but that wasn't practical.

Alternatively, it would have been better to recognize that some languages may
be described much better in terms of parsing steps and states than as a BNF
grammar.  Every grammar which can be matched by a finite or push-down state
machine will have an equivalent BNF grammar, but the BNF form may sometimes
need to be far more complicated, and far less comprehensible, than the state
machine upon which it is based.

A state machine which accepts all inputs that don't contain the word "fnord",
for example, would need six states, five of which have transitions only to
the next state or back to start, and one of which has transitions only to
itself.  Visual inspection of the state machine would make its function
easily apparent.  An equivalent in BNF would be much more complicated, and
even someone who knew that a BNF grammar was *supposed* to match any string
that doesn't contain "fnord" would have to do a lot of work to determine
whether it actually did so.  Perhaps you can suggest a reason why a BNF
description of the language would be more useful than the state-machine
approach, because I really don't see one.

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


#102923

FromDavid Brown <david.brown@hesbynett.no>
Date2017-02-01 20:56 +0100
Message-ID<o6teeo$ofn$1@dont-email.me>
In reply to#102912
On 01/02/17 17:44, supercat@casperkitty.com wrote:
> On Wednesday, February 1, 2017 at 10:14:01 AM UTC-6, Keith Thompson wrote:
>> It probably would have been better to have a more restrictive grammar
>> from the beginning, but that wasn't practical.
>
> Alternatively, it would have been better to recognize that some languages may
> be described much better in terms of parsing steps and states than as a BNF
> grammar.  Every grammar which can be matched by a finite or push-down state
> machine will have an equivalent BNF grammar, but the BNF form may sometimes
> need to be far more complicated, and far less comprehensible, than the state
> machine upon which it is based.
>

Alternatively, it would have been even better to recognize that some 
aspects of a language like C can be best described in BNF form, and 
other aspects can be best described in free text.

Oh, wait - someone's thought of that already.

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


#102910

Fromsupercat@casperkitty.com
Date2017-02-01 08:29 -0800
Message-ID<910e144a-fbc1-43e6-a2d2-59aa44aebb72@googlegroups.com>
In reply to#102906
On Wednesday, February 1, 2017 at 9:30:23 AM UTC-6, David Brown wrote:
> How can you be writing a parser, and complaining about what C does and
> does not allow, and how other compilers match the standards, when you
> haven't even bothered to /read/ the standards?  How are you making
> making your code at the moment - by skim-reading a couple of Wikipedia
> articles then some trial-and-error runs with a few existing compilers?

The language Dennis Ritchie designed was not processed using a formal grammar,
nor is a formal grammar the most efficient way to parse that language.  In
addition, I don't think a formal grammar works well as a human-readable way of
describing it either.

Since some compiler-generation tools are easiest to use when they have a
formal grammar as a starting point, I think it is reasonable for the Standard
to provide a grammar and say that implementations are required to handle the
cases described by the Standard and are not required to handle cases outside
the grammar.  Given the charter of the Committee, however, I really doubt that
the Committee intended that compilers should be required to reject forms that
they had accepted previously and which may be in use by production code.

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


Page 1 of 2  [1] 2  Next page →

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


csiph-web