Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

There is no distinction between any AI program and some existent game.


devel / comp.lang.c / Re: MCC Compiler

SubjectAuthor
* MCC CompilerBart
+- Re: MCC CompilerBart
`* Re: MCC CompilerTim Rentsch
 `* Re: MCC CompilerBart
  +- Re: MCC CompilerKaz Kylheku
  `* Re: MCC CompilerTim Rentsch
   +* Re: MCC CompilerBart
   |+* Re: MCC CompilerMalcolm McLean
   ||+* Re: MCC CompilerBart
   |||+* Re: MCC CompilerMichael S
   ||||`- Re: MCC CompilerMalcolm McLean
   |||+- Re: MCC CompilerKenny McCormack
   |||`* Re: MCC CompilerDavid Brown
   ||| `- Re: MCC CompilerBart
   ||+* Re: MCC CompilerKenny McCormack
   |||`* Re: MCC CompilerAnton Shepelev
   ||| `- Re: MCC CompilerTim Rentsch
   ||+- Re: MCC CompilerRichard Harnden
   ||`- Re: MCC CompilerTim Rentsch
   |+- Re: MCC CompilerMichael S
   |`- Re: MCC CompilerTim Rentsch
   `* Re: MCC CompilerBart
    `* Re: MCC CompilerTim Rentsch
     +* Re: MCC CompilerBart
     |`* Re: MCC CompilerTim Rentsch
     | `* Re: MCC CompilerBGB
     |  `* Re: MCC CompilerTim Rentsch
     |   `- Re: MCC CompilerBGB
     `* Re: MCC CompilerBart
      +* Re: MCC CompilerBen Bacarisse
      |`- Re: MCC Compilerbart
      `* Re: MCC CompilerKeith Thompson
       +* Re: MCC Compilerbart
       |`* Re: MCC CompilerKeith Thompson
       | +* Re: MCC Compilerbart
       | |`- Re: MCC CompilerDavid Brown
       | `- Re: MCC CompilerKaz Kylheku
       `* Re: MCC CompilerTim Rentsch
        `* Re: MCC CompilerKeith Thompson
         `- Re: MCC CompilerTim Rentsch

Pages:12
Re: MCC Compiler

<uh1bfu$1uo0h$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30012&group=comp.lang.c#30012

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: cr88...@gmail.com (BGB)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Sat, 21 Oct 2023 15:13:44 -0500
Organization: A noiseless patient Spider
Lines: 183
Message-ID: <uh1bfu$1uo0h$1@dont-email.me>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
<ugjb0v$1dkhk$1@dont-email.me> <86jzrh5qk5.fsf@linuxsc.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 21 Oct 2023 20:14:54 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="b555b47492af5e7bf1d8aebb738de29c";
logging-data="2056209"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+x5S3I10AlRLOjb013xBsb"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101
Thunderbird/102.15.1
Cancel-Lock: sha1:Kiyq/gtilPYR55zpIm5zUTrBAFM=
Content-Language: en-US
In-Reply-To: <86jzrh5qk5.fsf@linuxsc.com>
 by: BGB - Sat, 21 Oct 2023 20:13 UTC

On 10/20/2023 9:14 AM, Tim Rentsch wrote:
> Bart <bc@freeuk.com> writes:
>
>> On 16/10/2023 03:26, Tim Rentsch wrote:
>>
>>> Bart <bc@freeuk.com> writes:
>>
>>
>>>> My product compiles a C 'subset' but does not formally
>>>> define what it is.
>>>
>>> An informal definition is a lot better than no description
>>> at all, and at least is something about the C language.
>>> So figure out what the discrepancies are (and only you can
>>> do that), and tell us about it. That's why we're here!
>>
>> OK, an informal definition is the subset of C that I personally
>> use, and that I saw being commonly used on open source projects,
>> at the start of 2017.
>>
>> It would loosely be C99 but missing Complex, VLAs, designated
>> initialisers, compound literals, but with _Generic from C11 (that
>> one could be trivially implemented in about 40 lines of code).
>
> Given that, a good target would be to aim for conformance with
> C11, where Complex and VLAs are optional. Compound literals
> and designated initializers shouldn't be that hard to add, and are
> both very useful. If you can get your compiler up to the level
> of C11 conformance, or at least close enough, I would consider
> trying it with my current project (which is written entirely
> in C). The code in that project uses both compound literals and
> designated initializers. Do you handle bitfields? I use those
> also.
>

FWIW, in my C compiler (BGBCC, as-is):
_Complex exists, but isn't well tested;
VLAs sort of exist, but:
They only work for 1D arrays of primitive types (no structs).
Basically, C89 with parts of the newer standards glued on ad-hoc.
Features were added more "as useful".
Supports some parts of C23 as well.
Supports _BitInt, partial 'auto', ...
Also supports the proposed (C++ style) lambda syntax.
Though, semantics don't exactly match C++ lambdas (1).
Also the new attribute syntax and similar.
Along with UTF-8 strings and similar as well.
Also the 'stdbit.h' stuff, "0b" literals, digit separators, ...
...

Does not support '_Generic()' though as of yet.

*1: alloca, VLAs, and (automatic) lambdas are implemented with automatic
storage being implemented via heap allocation (with automatic freeing
via an implicit linked list). Note that my compiler and ABI design don't
allow for the size of stack-frames to change at runtime.

It is written in C, but currently only targets my own ISA (though,
previously, did target the Hitachi SuperH SH-2 and SH-4 ISA's; but this
hasn't been tested in a while).

The ISA design had distantly evolved out of SH-4, but has now mutated
beyond recognition. It is a LIW/VLIW design with 64 GPRs, 1-3
instructions per bundle, and variable-length instructions (16/32/64/96
or 32/64/96-bit, depending on ISA variant).

But, main reason for a custom C compiler here being mostly that no other
compilers support my ISA design, and trying to add a new target to GCC
or LLVM looked like far more pain than it was worth.

The C dialect supported, as well as the design of the command-line, is
generally more like that of MSVC (it borrows some amount of extension
keywords/attributes from MSVC, including a lot of its "__declspec"
modifiers and similar).

There are various language extensions as well, but mostly as-useful.
Most commonly used are __int128 and similar (which adds 128-bit integer
types), as well as extensions for SIMD vectors and similar (with
notation and semantics loosely derived from the OpenGL shader language /
GLSL).

In this case, borrowing GLSL features being "less awful" than the
"xmmintrin.h" system used by MSVC; and generally more usable than GCC's
vector extension (also partly supported, for a limited selection of
vector sizes and types). Some aspects of MSVC's vector system were
retained, but with different semantics (__m64 and __m128 still exist but
serve as more abstract types for bit-level casting between types and
formats).

So, for example, it is possible to coerce a double to an integer type like:
double f;
unsigned long long fi;
f=3.14159;
fi=(__m64)f;
Which first converts the floating point type to __m64, which then
converted to an integer type, yields the bit-pattern of the
floating-point value (the reverse is also possible).

Note that my compiler isn't terribly smart, and isn't able to optimize
away the memory accesses from more traditional methods, for example:
fi=*(unsigned long long *)(&f);
Will require 'f' to memory and then reloading the value from memory,
whereas the '__m64' cast can sidestep the memory load.

Both 'union' and 'memcpy()' strategies suffer from the same basic
problems as the pointer deref in this case.

Note that in this case, 'double' is defined as using the IEEE Binary64
format.

Where:
double x; //Binary64
float y; //Binary32 (*2)
short float z; //Binary16 (*2)
long double w; //Binary128 (*3)

*2: For small scalar floating point types, typically Binary64 is always
used in registers; in this case, the smaller representation only exists
when the value is stored in memory.

*3: Though, using this is handled by falling back to software emulation,
so 'long double' comes at a significant speed penalty (this differs some
from MSVC behavior, where 'long double' decays to 'double').

Though, more like GCC, 'sizeof(long)'=='sizeof(void *)' in most
contexts, as it seemed more useful to keep 'long' as consistent with the
size of a native pointer, than to keep 'long' as 32 bits.

There is also sometimes used extensions for working with dynamic types.
Technically, it is possible to write C with using more JavaScript-like
types, but this comes with a performance penalty (most operations
involve runtime calls), and the type-systems interact in potentially
rather non-trivial ways in more non-trivial situations (it isn't really
possible to provide a "seamless" integration if mixing data between
them, as the way C types and data structures behave is very different
from how things work as dynamic types).

Many other extensions mostly exist in terms of the C library, such as
support for things like:
zone based memory allocation;
Allocations can be categorized during alloc,
with a bulk free for any memory objects in a given category
Allocation meta categories
Such as for requesting memory with read/write/execute access, ...
"__memlzcpy", which implements overlapping copy as needed for LZ77
Copying memory over itself generating a repeating pattern of bytes.

Say:
unsigned char *arr;
...
__memlzcpy(arr+1, arr, 256)
Behaving similarly to:
memset(arr+1, *arr, 256);

But, supporting arbitrary strides, and trying to "efficiently" implement
the various cases (a naive byte-for-byte copy loop is horribly slow; but
writing these sorts of copy-operations is a way that is efficient, and
works correctly, across targets, tends to be rather ugly and unwieldy).

Note that this is nearly the exact opposite behavior in this case from
something like "memmove()" (when copying memory to a higher address in
the case of overlap). Note that if copying memory to a lower address,
it will behave more like "memmove()" (and will behave more like
"memcpy()" in the case of non-overlap).

There is also "__memlzcpyf()" which does similar, but makes the
optimizing assumption that the user doesn't care about the bytes
directly following the end of the destination (so, we can allow the
following 16 bytes or so to be stomped by the copy; rather than have the
copy be bogged down by trying to copy an exact number of bytes).

....

Re: MCC Compiler

<8634y2672g.fsf@linuxsc.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30021&group=comp.lang.c#30021

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: tr.17...@z991.linuxsc.com (Tim Rentsch)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Sun, 22 Oct 2023 07:54:47 -0700
Organization: A noiseless patient Spider
Lines: 70
Message-ID: <8634y2672g.fsf@linuxsc.com>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com> <uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com> <uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com> <ugjb0v$1dkhk$1@dont-email.me> <86jzrh5qk5.fsf@linuxsc.com> <uh1bfu$1uo0h$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: dont-email.me; posting-host="6dc747ee13145ffb1c38bba62e6e987b";
logging-data="2617441"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/HxYiLdmoiyrLXNooOvepiMAxoXRE64ZE="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:gAlEUyHV2ehQP1eoY0p7DQWLV2M=
sha1:rG0DIFOroICALbLcKVQ6UtI4yns=
 by: Tim Rentsch - Sun, 22 Oct 2023 14:54 UTC

BGB <cr88192@gmail.com> writes:

> On 10/20/2023 9:14 AM, Tim Rentsch wrote:
>
>> Bart <bc@freeuk.com> writes:
>>
>>> On 16/10/2023 03:26, Tim Rentsch wrote:
>>>
>>>> Bart <bc@freeuk.com> writes:
>>>
>>>
>>>>> My product compiles a C 'subset' but does not formally
>>>>> define what it is.
>>>>
>>>> An informal definition is a lot better than no description
>>>> at all, and at least is something about the C language.
>>>> So figure out what the discrepancies are (and only you can
>>>> do that), and tell us about it. That's why we're here!
>>>
>>> OK, an informal definition is the subset of C that I personally
>>> use, and that I saw being commonly used on open source projects,
>>> at the start of 2017.
>>>
>>> It would loosely be C99 but missing Complex, VLAs, designated
>>> initialisers, compound literals, but with _Generic from C11 (that
>>> one could be trivially implemented in about 40 lines of code).
>>
>> Given that, a good target would be to aim for conformance with
>> C11, where Complex and VLAs are optional. Compound literals
>> and designated initializers shouldn't be that hard to add, and are
>> both very useful. If you can get your compiler up to the level
>> of C11 conformance, or at least close enough, I would consider
>> trying it with my current project (which is written entirely
>> in C). The code in that project uses both compound literals and
>> designated initializers. Do you handle bitfields? I use those
>> also.
>
> FWIW, in my C compiler (BGBCC, as-is):
> _Complex exists, but isn't well tested;
> VLAs sort of exist, but:
> They only work for 1D arrays of primitive types (no structs).
> Basically, C89 with parts of the newer standards glued on ad-hoc.
> Features were added more "as useful".
> Supports some parts of C23 as well.
> Supports _BitInt, partial 'auto', ...
> Also supports the proposed (C++ style) lambda syntax.
> Though, semantics don't exactly match C++ lambdas (1).
> Also the new attribute syntax and similar.
> Along with UTF-8 strings and similar as well.
> Also the 'stdbit.h' stuff, "0b" literals, digit separators, ...
> ...
>
> Does not support '_Generic()' though as of yet.

For a compiler to be one I might be able to use, it must

* conform to either the C99 or C11 standard (some
documented shortcomings might be acceptable, depending
on what they are)

* produce .o files in at least one environment I can use
(right now that is only GNU/Linux), including support
for a -fPIC option

* generate code of at least reasonable quality; not
necessarily at the -O2 level of gcc or clang, but
better than -O1

If you get to something roughly or possibly approximating the
list above, please keep the group posted!

Re: MCC Compiler

<uh43i4$2lhk2$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30030&group=comp.lang.c#30030

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: cr88...@gmail.com (BGB)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Sun, 22 Oct 2023 16:16:45 -0500
Organization: A noiseless patient Spider
Lines: 355
Message-ID: <uh43i4$2lhk2$1@dont-email.me>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
<ugjb0v$1dkhk$1@dont-email.me> <86jzrh5qk5.fsf@linuxsc.com>
<uh1bfu$1uo0h$1@dont-email.me> <8634y2672g.fsf@linuxsc.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sun, 22 Oct 2023 21:17:57 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="5a73ac204590050bbdf8df78b2b2ce9f";
logging-data="2803330"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/XnKqWDTpblj2dqMjySh+I"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101
Thunderbird/102.15.1
Cancel-Lock: sha1:120rWFeHrOyHR320ZkOqKyJNGxE=
In-Reply-To: <8634y2672g.fsf@linuxsc.com>
Content-Language: en-US
 by: BGB - Sun, 22 Oct 2023 21:16 UTC

On 10/22/2023 9:54 AM, Tim Rentsch wrote:
> BGB <cr88192@gmail.com> writes:
>
>> On 10/20/2023 9:14 AM, Tim Rentsch wrote:
>>
>>> Bart <bc@freeuk.com> writes:
>>>
>>>> On 16/10/2023 03:26, Tim Rentsch wrote:
>>>>
>>>>> Bart <bc@freeuk.com> writes:
>>>>
>>>>
>>>>>> My product compiles a C 'subset' but does not formally
>>>>>> define what it is.
>>>>>
>>>>> An informal definition is a lot better than no description
>>>>> at all, and at least is something about the C language.
>>>>> So figure out what the discrepancies are (and only you can
>>>>> do that), and tell us about it. That's why we're here!
>>>>
>>>> OK, an informal definition is the subset of C that I personally
>>>> use, and that I saw being commonly used on open source projects,
>>>> at the start of 2017.
>>>>
>>>> It would loosely be C99 but missing Complex, VLAs, designated
>>>> initialisers, compound literals, but with _Generic from C11 (that
>>>> one could be trivially implemented in about 40 lines of code).
>>>
>>> Given that, a good target would be to aim for conformance with
>>> C11, where Complex and VLAs are optional. Compound literals
>>> and designated initializers shouldn't be that hard to add, and are
>>> both very useful. If you can get your compiler up to the level
>>> of C11 conformance, or at least close enough, I would consider
>>> trying it with my current project (which is written entirely
>>> in C). The code in that project uses both compound literals and
>>> designated initializers. Do you handle bitfields? I use those
>>> also.
>>
>> FWIW, in my C compiler (BGBCC, as-is):
>> _Complex exists, but isn't well tested;
>> VLAs sort of exist, but:
>> They only work for 1D arrays of primitive types (no structs).
>> Basically, C89 with parts of the newer standards glued on ad-hoc.
>> Features were added more "as useful".
>> Supports some parts of C23 as well.
>> Supports _BitInt, partial 'auto', ...
>> Also supports the proposed (C++ style) lambda syntax.
>> Though, semantics don't exactly match C++ lambdas (1).
>> Also the new attribute syntax and similar.
>> Along with UTF-8 strings and similar as well.
>> Also the 'stdbit.h' stuff, "0b" literals, digit separators, ...
>> ...
>>
>> Does not support '_Generic()' though as of yet.
>
> For a compiler to be one I might be able to use, it must
>
> * conform to either the C99 or C11 standard (some
> documented shortcomings might be acceptable, depending
> on what they are)
>

It mostly supports roughly the common subset of C99 and C11.
Though, most of the code I have ported to my ISA has been C89, so newer
functionality isn't well tested.

> * produce .o files in at least one environment I can use
> (right now that is only GNU/Linux), including support
> for a -fPIC option
>

At present, generating code on any mainstream targets was not a
priority, as MSVC/GCC/Clang already address these cases fairly effectively.

My previous small-scale attempts at generating code for ARM targets had
given horribly bad performance relative to GCC, so it didn't really seem
worthwhile.

As-is, it produces "RIL3" as its "object file" output, which is a
stack-oriented bytecode along vaguely similar lines to .NET bytecode (it
does the preprocessing and parsing, then translates the resulting AST
into a stack-oriented bytecode; generally using implicit types which are
carried along the with stack, like .NET and unlike JVM, ...).

Though, there are larger scale architectural differences (metadata is
managed differently; and my design assumes a C-like or "bare metal"
environment, rather than a "Managed VM", ...).
Though, actual .NET bytecode would be a crappy way of expressing C and
similar (making it less desirable at the time), and is used mostly as a
stand-in for object files and static libraries (with the final output
being in the form of native-code binaries). Though, one could argue, at
least .NET's bytecode would be "less bad" at representing C than the
JVM's ".class" file-format (in that, at least, doing so is not "comical").

Though, things "could be better", but not come up with any "clearly
better" option (native-code objects and a three-address-code IR are all
tradeoffs); and other factors are mostly matters of data-packaging and
how to best represent the metadata, ...

I had on-off considered whether to consider using IR images and AOT
compiling them per target. Would preferably need a lighter weight
backend though. Current backend loads and unpacks all of the bytecode
and metadata; saving memory would require ability to translate functions
one-at-a-time, and determining things like what is reachable, preferably
without needing to first translate everything into 3-address form, ...

All this would require a fair bit of redesign though (and a different
packaging scheme for the IR bytecode and metadata; as the current
structure is not well suited to random access as it was designed around
the the assumption of a sequential loader). Things like RAM footprint of
reading in and accessing the bytecode images would also need to be
considered, etc. Well, along with the battle over the relative merits of
a stack-machine vs three-address-code representation for the IR, etc.

Note that many aspects of the target machine can be glossed over in the
IR, though things like "sizeof(void *)" and similar remain as thorny
issues (so, if relevant, one may still need to build versions of the
libraries for each potential pointer size).
As-is, it sort of works, but trying to mix/match here mostly tends to
result in a bunch of hairy bugs typically revolving around "#ifdef's"
and "typedef" and similar (which effect other code, even if the C
library itself can be written to be mostly pointer-size agnostic).

Well, and relatedly, there is another "__ifarch(feature)" extension that
mostly allows enabling/disabling functions of blocks of code depending
on target-specific options, however (unlike "#ifdef") requires the code
to be structurally and syntactically valid (and the function signatures
need to match across all ifarch paths, etc). This differing from
"#ifdef" mostly in that it is handled much later in the compiler pipeline.

An example of this would be to allow the same context-switch code to be
used on targets with 32 and 64 GPRs (where half of the registers don't
exist in the 32-register configuration). But, would be annoying to
compile separate versions of the runtime libraries based on things like
whether the configuration is using 32 or 64 GPRs, which variant of the C
ABI is being used, etc.

This feature is generally also available in ASM code and inline ASM and
similar as well (and also can enable or disable the use of ASM versions
of functions vs C counterparts, etc).

The backend then translates this to native code, at present emitting
binaries in a PE/COFF variant (loosely derived from the WinCE/SH
variant); but with some tweaks and typically LZ4 compressed (the LZ4
compression is integrated with the PE/COFF loaders, via the modified
format).

The LZ4 decompression is faster than reading more data from an SDcard
running at 13MHz in SPI mode. Where, I am using 13MHz mostly as I could
not get reliable operation much over this speed (and have not
implemented the logic to support UHS, and even if I did, I couldn't get
much more bandwidth over the existing MMIO bus).

When operating in the LZ4-compressed mode, the PE/COFF checksums also
use a different (slightly stronger) algorithm, as the original PE/COFF
checksum algorithm was insufficient to detect many of the problems a
misbehaving LZ4 decoder could introduce.

The code produced is "mostly" position independent, but does still rely
on "base relocations" for some things. The ABI and format was tweaked
slightly to allow running multiple logical instances of a given binary
within a single shared address space. Effectively, the
'.text'/'.rdata'/etc sections being accessed separately from '.data'/'.bss'.

Where, in this case, modifiable sections are separately allocated and
accessed relative to the "global pointer", with the global pointer
pointing to a lookup table which allows each PE image (EXE or DLL) to
locate its corresponding version of the section (updating the global
pointer to point to its own data section). This global pointer is
callee-save, so on return, the caller's global-pointer is restored.


Click here to read the complete article
Re: MCC Compiler

<uhbc8m$rd1b$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30102&group=comp.lang.c#30102

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!paganini.bofh.team!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Wed, 25 Oct 2023 16:29:26 +0100
Organization: A noiseless patient Spider
Lines: 80
Message-ID: <uhbc8m$rd1b$1@dont-email.me>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 25 Oct 2023 15:29:26 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="5500600aecadc06ec2b44f3e7b50acb0";
logging-data="898091"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18VGMJGy/Hqm7HjbjBiIPMl0QC7bN6+FJI="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:bHOI1+K+F4ITmhijhzva+LbsISE=
Content-Language: en-GB
In-Reply-To: <864jir8fpw.fsf@linuxsc.com>
 by: Bart - Wed, 25 Oct 2023 15:29 UTC

On 16/10/2023 03:26, Tim Rentsch wrote:
> Bart <bc@freeuk.com> writes:
>
>> On 29/09/2023 06:10, Tim Rentsch wrote:

>>> and aren't faithful to
>>> the C language (and it isn't clear whether you don't know that or
>>> if you just don't care).
>>
>> In which ways?
>
> No one knows but you, and it's not even clear if you know.
> Ironically, if you were to go through and make up a list of
> differences between what your compiler accepts and what the
> C standard requires, and present that list here, that WOULD
> be topical, especially if there were reasons related to how
> easy or hard some aspects of C are to compile. For reasons
> beyond understanding you leave out exactly the pieces of
> information that would make it relevant in comp.lang.c. I'm
> at a loss to understand why you do that.

Rather than list all the shortcoming of my compiler, easier to say that
the front-end needs a rewrite.

The overhaul I did in September this year was in replacing the backend,
which addressed some urgent code-gen issues and hopefully made it less
buggy.

At the moment I'm not looking at working on the front-end, and the
project remains a personal one used for C code I write, the C I
generate, and whatever external C I come across that is within its
capabilities. That includes most stuff posted here.

> if there were reasons related to how easy or hard some aspects of C
are to compile

One thing that makes it hard IMO is that a lot of C isn't very
rigorously defined. You can easily have a program that either passes,
fails, or passes with warnings, depending on compiler and options.

Or take this sequence:

int a = 0;
int b = {0};
int c = {{0}};

The first is OK, so is the second (why?), but the third gives a warning
on gcc. (Mcc passes the first two and fails the third.)

I know that when an array/struct is initialised, extra braces are not
allowed, but fewer braces are OK:

int a[2][3] = {1,2,3,4,5,6};
int b[2][3] = {{1,2,3}, {4,5,6}};

Here, gcc passes both, even though the shape of the data doesn't match
the type of 'a'.

There is a some algorithm involved to figure out which braces can be
legally left out. Mcc doesn't use it; it requires braces to exactly
match the type's data structure, so 'a' fails, and 'b' parses.

Here's one more:

static int a;
extern int a;
static int a;

The above is passed by gcc, but this fails (Mcc just passes both);

extern int a;
static int a;
extern int a;

There is tons of this stuff. Somehow I don't think that rewrite is going
to happen. To write a compiler you need have clear rules about what
constitutes a valid program.

C is just too lax amd too open-ended, sorry.

Re: MCC Compiler

<87o7gmxywh.fsf@bsb.me.uk>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30105&group=comp.lang.c#30105

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: ben.use...@bsb.me.uk (Ben Bacarisse)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Wed, 25 Oct 2023 20:52:46 +0100
Organization: A noiseless patient Spider
Lines: 9
Message-ID: <87o7gmxywh.fsf@bsb.me.uk>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
<uhbc8m$rd1b$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="6fe5770c5d67651737bf36005d7426d0";
logging-data="1047949"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/g19diz2ranQsLO9P+okMMMvsfQZFBGK0="
User-Agent: Gnus/5.13 (Gnus v5.13)
Cancel-Lock: sha1:heccI7j18sLWwm9u7zI3RLyQb4A=
sha1:zL+6emkN+Y783fpNRXzP1LMLt94=
X-BSB-Auth: 1.85a951612b319190df76.20231025205246BST.87o7gmxywh.fsf@bsb.me.uk
 by: Ben Bacarisse - Wed, 25 Oct 2023 19:52 UTC

Bart <bc@freeuk.com> writes:

> ... To write a compiler you need have clear rules about what constitutes
> a valid program.

You don't think the rules exist, or you don't consider them to be clear?

--
Ben.

Re: MCC Compiler

<87v8aujuxq.fsf@nosuchdomain.example.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30107&group=comp.lang.c#30107

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Keith.S....@gmail.com (Keith Thompson)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Wed, 25 Oct 2023 13:42:09 -0700
Organization: None to speak of
Lines: 67
Message-ID: <87v8aujuxq.fsf@nosuchdomain.example.com>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
<uhbc8m$rd1b$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="4d3dc32917782594b2126b84973b1030";
logging-data="1076200"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/3UcJZpObTz3vIbOPC+uRy"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux)
Cancel-Lock: sha1:imInE4vht/aJ5WlLgXnwgwCUjQE=
sha1:esqXDwc6erDzTlroh00JJuCrNpc=
 by: Keith Thompson - Wed, 25 Oct 2023 20:42 UTC

Bart <bc@freeuk.com> writes:
[...]
> One thing that makes it hard IMO is that a lot of C isn't very
> rigorously defined. You can easily have a program that either passes,
> fails, or passes with warnings, depending on compiler and options.

Any behavior of a compiler invoked in non-conforming mode (including
most C compilers in their default) is irrelevant to the question of how
rigorously C is defined.

> Or take this sequence:
>
> int a = 0;
> int b = {0};
> int c = {{0}};
>
> The first is OK, so is the second (why?), but the third gives a
> warning on gcc. (Mcc passes the first two and fails the third.)

The first and second are OK because the standard explicitly says so.
N1570 6.7.9p:

The initializer for a scalar shall be a single expression,
optionally enclosed in braces.

As for the third, with "-std=c17 -pedantic-errors", gcc warns "braces
around scalar initializer", while clang gives a fatal error "too many
braces around scalar initializer".

One could argue that "enclosed in braces" allows both {...} and {{...}}.
I don't think I'd make that argument myself. But the requirement is in
the Semantics section, not Constraints, so violating it is not a
constraint violation. IMHO it *should* have been a constraint. I think
clang is incorrect to reject it in conforming mode, though a warning is
certainly appropriate.

So yes, in this specific case the standard is a bit vague about the
validity of `int c = {{0}};`.

> I know that when an array/struct is initialised, extra braces are not
> allowed, but fewer braces are OK:
>
> int a[2][3] = {1,2,3,4,5,6};
> int b[2][3] = {{1,2,3}, {4,5,6}};
>
> Here, gcc passes both, even though the shape of the data doesn't match
> the type of 'a'.
>
> There is a some algorithm involved to figure out which braces can be
> legally left out. Mcc doesn't use it; it requires braces to exactly
> match the type's data structure, so 'a' fails, and 'b' parses.

Other than {{scalar}}, the rules for braces in initializers are
complicated but unambiguous. Allowing nested braces to be omitted lets
{0} be a valid initializer for any object type, which can be very
convenient. (C23 allows {}.)

[...]

> C is just too lax amd too open-ended, sorry.

I don't think it's nearly as lax as you say it is.

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

Re: MCC Compiler

<uhbuqj$2pv5i$1@i2pn2.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30108&group=comp.lang.c#30108

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!.POSTED!not-for-mail
From: bc...@freeuk.com (bart)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Wed, 25 Oct 2023 21:46:12 +0100
Organization: i2pn2 (i2pn.org)
Message-ID: <uhbuqj$2pv5i$1@i2pn2.org>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
<uhbc8m$rd1b$1@dont-email.me> <87o7gmxywh.fsf@bsb.me.uk>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 25 Oct 2023 20:46:11 -0000 (UTC)
Injection-Info: i2pn2.org;
logging-data="2948274"; mail-complaints-to="usenet@i2pn2.org";
posting-account="dVsFrph2cpoFXY+0g13RAVyL1kBF0YjYSsiqIraasbA";
User-Agent: Mozilla Thunderbird
Content-Language: en-GB
In-Reply-To: <87o7gmxywh.fsf@bsb.me.uk>
 by: bart - Wed, 25 Oct 2023 20:46 UTC

On 25/10/2023 20:52, Ben Bacarisse wrote:
> Bart <bc@freeuk.com> writes:
>
>> ... To write a compiler you need have clear rules about what constitutes
>> a valid program.
>
> You don't think the rules exist, or you don't consider them to be clear?
>

The rules probably do their best trying to formalise a messy, untidy
language due to diverse implementations.

But no I don't consider them to be clear.

Re: MCC Compiler

<uhcbvu$2qdm0$1@i2pn2.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30109&group=comp.lang.c#30109

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!.POSTED!not-for-mail
From: bc...@freeuk.com (bart)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Thu, 26 Oct 2023 01:30:55 +0100
Organization: i2pn2 (i2pn.org)
Message-ID: <uhcbvu$2qdm0$1@i2pn2.org>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
<uhbc8m$rd1b$1@dont-email.me> <87v8aujuxq.fsf@nosuchdomain.example.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Thu, 26 Oct 2023 00:30:54 -0000 (UTC)
Injection-Info: i2pn2.org;
logging-data="2963136"; mail-complaints-to="usenet@i2pn2.org";
posting-account="dVsFrph2cpoFXY+0g13RAVyL1kBF0YjYSsiqIraasbA";
User-Agent: Mozilla Thunderbird
Content-Language: en-GB
In-Reply-To: <87v8aujuxq.fsf@nosuchdomain.example.com>
 by: bart - Thu, 26 Oct 2023 00:30 UTC

On 25/10/2023 21:42, Keith Thompson wrote:
> Bart <bc@freeuk.com> writes:
> [...]
>> One thing that makes it hard IMO is that a lot of C isn't very
>> rigorously defined. You can easily have a program that either passes,
>> fails, or passes with warnings, depending on compiler and options.
>
> Any behavior of a compiler invoked in non-conforming mode (including
> most C compilers in their default) is irrelevant to the question of how
> rigorously C is defined.
>
>> Or take this sequence:
>>
>> int a = 0;
>> int b = {0};
>> int c = {{0}};
>>
>> The first is OK, so is the second (why?), but the third gives a
>> warning on gcc. (Mcc passes the first two and fails the third.)
>
> The first and second are OK because the standard explicitly says so.
> N1570 6.7.9p:
>
> The initializer for a scalar shall be a single expression,
> optionally enclosed in braces.
>
> As for the third, with "-std=c17 -pedantic-errors", gcc warns "braces
> around scalar initializer", while clang gives a fatal error "too many
> braces around scalar initializer".
>
> One could argue that "enclosed in braces" allows both {...} and {{...}}.
> I don't think I'd make that argument myself. But the requirement is in
> the Semantics section, not Constraints, so violating it is not a
> constraint violation. IMHO it *should* have been a constraint. I think
> clang is incorrect to reject it in conforming mode, though a warning is
> certainly appropriate.
>
> So yes, in this specific case the standard is a bit vague about the
> validity of `int c = {{0}};`.
>
>> I know that when an array/struct is initialised, extra braces are not
>> allowed, but fewer braces are OK:
>>
>> int a[2][3] = {1,2,3,4,5,6};
>> int b[2][3] = {{1,2,3}, {4,5,6}};
>>
>> Here, gcc passes both, even though the shape of the data doesn't match
>> the type of 'a'.
>>
>> There is a some algorithm involved to figure out which braces can be
>> legally left out. Mcc doesn't use it; it requires braces to exactly
>> match the type's data structure, so 'a' fails, and 'b' parses.
>
> Other than {{scalar}}, the rules for braces in initializers are
> complicated but unambiguous. Allowing nested braces to be omitted lets
> {0} be a valid initializer for any object type, which can be very
> convenient. (C23 allows {}.)

It also allows this:

int a[2][3] = {1,2,4,5,6};

Element '3' has been left out by mistake. Now all elements are out of
step, and the last has value 0 instead of 6.

I couldn't believe it when I discovered this.

(I also wasn't that keen on missing elements being set to zero, when
when the braces are correct, since you can have a similar problem when
elements can be left out by mistake, or a comma omitted: {1,2,34,5,6}.
I'd have prefered a syntax like a trailing ... here to denote padding
with zeros.)

>
> [...]
>
>> C is just too lax amd too open-ended, sorry.
>
> I don't think it's nearly as lax as you say it is.

Perhaps you haven't tried to implement it!

Re: MCC Compiler

<87r0liji60.fsf@nosuchdomain.example.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30110&group=comp.lang.c#30110

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Keith.S....@gmail.com (Keith Thompson)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Wed, 25 Oct 2023 18:17:59 -0700
Organization: None to speak of
Lines: 95
Message-ID: <87r0liji60.fsf@nosuchdomain.example.com>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
<uhbc8m$rd1b$1@dont-email.me>
<87v8aujuxq.fsf@nosuchdomain.example.com> <uhcbvu$2qdm0$1@i2pn2.org>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="3fd89baf230d4414f6c1ba98670a74bd";
logging-data="1221840"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/tbyP8rWu4MbJLvP/Ovl08"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux)
Cancel-Lock: sha1:/BbArOBbZHt8WFf4zebK6t0SKYo=
sha1:HEsK/gxnDjb8lQO6jwXSq9XPSvA=
 by: Keith Thompson - Thu, 26 Oct 2023 01:17 UTC

bart <bc@freeuk.com> writes:
> On 25/10/2023 21:42, Keith Thompson wrote:
>> Bart <bc@freeuk.com> writes:
>> [...]
>>> One thing that makes it hard IMO is that a lot of C isn't very
>>> rigorously defined. You can easily have a program that either passes,
>>> fails, or passes with warnings, depending on compiler and options.
>> Any behavior of a compiler invoked in non-conforming mode (including
>> most C compilers in their default) is irrelevant to the question of how
>> rigorously C is defined.
>>
>>> Or take this sequence:
>>>
>>> int a = 0;
>>> int b = {0};
>>> int c = {{0}};
>>>
>>> The first is OK, so is the second (why?), but the third gives a
>>> warning on gcc. (Mcc passes the first two and fails the third.)
>> The first and second are OK because the standard explicitly says so.
>> N1570 6.7.9p:
>> The initializer for a scalar shall be a single expression,
>> optionally enclosed in braces.
>> As for the third, with "-std=c17 -pedantic-errors", gcc warns
>> "braces
>> around scalar initializer", while clang gives a fatal error "too many
>> braces around scalar initializer".
>> One could argue that "enclosed in braces" allows both {...} and
>> {{...}}.
>> I don't think I'd make that argument myself. But the requirement is in
>> the Semantics section, not Constraints, so violating it is not a
>> constraint violation. IMHO it *should* have been a constraint. I think
>> clang is incorrect to reject it in conforming mode, though a warning is
>> certainly appropriate.
>> So yes, in this specific case the standard is a bit vague about the
>> validity of `int c = {{0}};`.
>>
>>> I know that when an array/struct is initialised, extra braces are not
>>> allowed, but fewer braces are OK:
>>>
>>> int a[2][3] = {1,2,3,4,5,6};
>>> int b[2][3] = {{1,2,3}, {4,5,6}};
>>>
>>> Here, gcc passes both, even though the shape of the data doesn't match
>>> the type of 'a'.
>>>
>>> There is a some algorithm involved to figure out which braces can be
>>> legally left out. Mcc doesn't use it; it requires braces to exactly
>>> match the type's data structure, so 'a' fails, and 'b' parses.
>> Other than {{scalar}}, the rules for braces in initializers are
>> complicated but unambiguous. Allowing nested braces to be omitted lets
>> {0} be a valid initializer for any object type, which can be very
>> convenient. (C23 allows {}.)
>
> It also allows this:
>
> int a[2][3] = {1,2,4,5,6};
>
> Element '3' has been left out by mistake. Now all elements are out of
> step, and the last has value 0 instead of 6.
>
> I couldn't believe it when I discovered this.

C allows something you don't like. You're shocked. Lather, rinse, repeat.

It deliberately allows omitting all but the outer braces, so that a
multi-dimensional array can be initialized with a single brace-enclosed
list of values. Any trailing values (struct members or array elements)
that are not specified are initialized to zero.

It also allows:

int a[2][3] = {42};

which sets a[0][0] to 42 and all other elements to 0, and the universal
initializer:

some_type obj = {0};

falls out of the rules (C++ and C23 allow {}).

If you want to avoid that kind of error, don't omit the inner braces.

Large initializers are likely to be automatically generated, so barring
a bug in the code generator this problem is unlikely to occur.

[...]

Please keep in mind that nobody here is either responsible for the
current rules or in any position to change them.

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

Re: MCC Compiler

<uhdkup$2s00h$1@i2pn2.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30119&group=comp.lang.c#30119

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!.POSTED!not-for-mail
From: bc...@freeuk.com (bart)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Thu, 26 Oct 2023 13:10:02 +0100
Organization: i2pn2 (i2pn.org)
Message-ID: <uhdkup$2s00h$1@i2pn2.org>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
<uhbc8m$rd1b$1@dont-email.me> <87v8aujuxq.fsf@nosuchdomain.example.com>
<uhcbvu$2qdm0$1@i2pn2.org> <87r0liji60.fsf@nosuchdomain.example.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Thu, 26 Oct 2023 12:10:01 -0000 (UTC)
Injection-Info: i2pn2.org;
logging-data="3014673"; mail-complaints-to="usenet@i2pn2.org";
posting-account="dVsFrph2cpoFXY+0g13RAVyL1kBF0YjYSsiqIraasbA";
User-Agent: Mozilla Thunderbird
Content-Language: en-GB
In-Reply-To: <87r0liji60.fsf@nosuchdomain.example.com>
 by: bart - Thu, 26 Oct 2023 12:10 UTC

On 26/10/2023 02:17, Keith Thompson wrote:
> bart <bc@freeuk.com> writes:
>> On 25/10/2023 21:42, Keith Thompson wrote:
>>> Bart <bc@freeuk.com> writes:
>>> [...]
>>>> One thing that makes it hard IMO is that a lot of C isn't very
>>>> rigorously defined. You can easily have a program that either passes,
>>>> fails, or passes with warnings, depending on compiler and options.
>>> Any behavior of a compiler invoked in non-conforming mode (including
>>> most C compilers in their default) is irrelevant to the question of how
>>> rigorously C is defined.
>>>
>>>> Or take this sequence:
>>>>
>>>> int a = 0;
>>>> int b = {0};
>>>> int c = {{0}};
>>>>
>>>> The first is OK, so is the second (why?), but the third gives a
>>>> warning on gcc. (Mcc passes the first two and fails the third.)
>>> The first and second are OK because the standard explicitly says so.
>>> N1570 6.7.9p:
>>> The initializer for a scalar shall be a single expression,
>>> optionally enclosed in braces.
>>> As for the third, with "-std=c17 -pedantic-errors", gcc warns
>>> "braces
>>> around scalar initializer", while clang gives a fatal error "too many
>>> braces around scalar initializer".
>>> One could argue that "enclosed in braces" allows both {...} and
>>> {{...}}.
>>> I don't think I'd make that argument myself. But the requirement is in
>>> the Semantics section, not Constraints, so violating it is not a
>>> constraint violation. IMHO it *should* have been a constraint. I think
>>> clang is incorrect to reject it in conforming mode, though a warning is
>>> certainly appropriate.
>>> So yes, in this specific case the standard is a bit vague about the
>>> validity of `int c = {{0}};`.
>>>
>>>> I know that when an array/struct is initialised, extra braces are not
>>>> allowed, but fewer braces are OK:
>>>>
>>>> int a[2][3] = {1,2,3,4,5,6};
>>>> int b[2][3] = {{1,2,3}, {4,5,6}};
>>>>
>>>> Here, gcc passes both, even though the shape of the data doesn't match
>>>> the type of 'a'.
>>>>
>>>> There is a some algorithm involved to figure out which braces can be
>>>> legally left out. Mcc doesn't use it; it requires braces to exactly
>>>> match the type's data structure, so 'a' fails, and 'b' parses.
>>> Other than {{scalar}}, the rules for braces in initializers are
>>> complicated but unambiguous. Allowing nested braces to be omitted lets
>>> {0} be a valid initializer for any object type, which can be very
>>> convenient. (C23 allows {}.)
>>
>> It also allows this:
>>
>> int a[2][3] = {1,2,4,5,6};
>>
>> Element '3' has been left out by mistake. Now all elements are out of
>> step, and the last has value 0 instead of 6.
>>
>> I couldn't believe it when I discovered this.
>
> C allows something you don't like. You're shocked. Lather, rinse, repeat.

> It deliberately allows omitting all but the outer braces, so that a
> multi-dimensional array can be initialized with a single brace-enclosed
> list of values. Any trailing values (struct members or array elements)
> that are not specified are initialized to zero.
>
> It also allows:
>
> int a[2][3] = {42};
>
> which sets a[0][0] to 42 and all other elements to 0, and the universal
> initializer:
>
> some_type obj = {0};
>
> falls out of the rules (C++ and C23 allow {}).
>
> If you want to avoid that kind of error, don't omit the inner braces.

You've said this kind of thing before; you can't just avoid inadvertent
errors. You might as well take out ALL error checking from a compiler,
and advise users to get around that by never making a mistake!

> Large initializers are likely to be automatically generated, so barring
> a bug in the code generator this problem is unlikely to occur.
>
> [...]
>
> Please keep in mind that nobody here is either responsible for the
> current rules or in any position to change them.

I'm in a position to do that something about that, in a very small way.
Somebody using my compiler /has/ to write {{1,2,3},{4,5,6}} not
{1,2,3,4,5,6}, so that particular error can't get through.

Such code is still valid C compilable anywhere. And that user may get
into the habit of always getting the braces matching the data structure.

At the minute, if you see `= {0}` being used to initialise something in
this strictly typed language, it can be initialsing ANY scalar type, ANY
array of any number of dimensions, any size and any element type, and
ANY struct.

That is not a bit lax? OK..

Re: MCC Compiler

<uhdqql$1ki6t$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30122&group=comp.lang.c#30122

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!news.swapon.de!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: david.br...@hesbynett.no (David Brown)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Thu, 26 Oct 2023 15:50:12 +0200
Organization: A noiseless patient Spider
Lines: 110
Message-ID: <uhdqql$1ki6t$1@dont-email.me>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
<uhbc8m$rd1b$1@dont-email.me> <87v8aujuxq.fsf@nosuchdomain.example.com>
<uhcbvu$2qdm0$1@i2pn2.org> <87r0liji60.fsf@nosuchdomain.example.com>
<uhdkup$2s00h$1@i2pn2.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 26 Oct 2023 13:50:13 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="d771266891dbc98c8f13281839005349";
logging-data="1722589"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+QYWDQEHxNx6bocdkOgy1fy0JJxjxe+og="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101
Thunderbird/102.11.0
Cancel-Lock: sha1:CvtuoZrfomyAzIeD87l9Fy9/hcM=
Content-Language: en-GB
In-Reply-To: <uhdkup$2s00h$1@i2pn2.org>
 by: David Brown - Thu, 26 Oct 2023 13:50 UTC

On 26/10/2023 14:10, bart wrote:
> On 26/10/2023 02:17, Keith Thompson wrote:

>
>> It deliberately allows omitting all but the outer braces, so that a
>> multi-dimensional array can be initialized with a single brace-enclosed
>> list of values.  Any trailing values (struct members or array elements)
>> that are not specified are initialized to zero.
>>
>> It also allows:
>>
>>      int a[2][3] = {42};
>>
>> which sets a[0][0] to 42 and all other elements to 0, and the universal
>> initializer:
>>
>>      some_type obj = {0};
>>
>> falls out of the rules (C++ and C23 allow {}).
>>
>> If you want to avoid that kind of error, don't omit the inner braces.
>
> You've said this kind of thing before; you can't just avoid inadvertent
> errors. You might as well take out ALL error checking from a compiler,
> and advise users to get around that by never making a mistake!
>

In this particular case, you most certainly /can/ avoid inadvertent
errors - and you can avoid omitting the inner braces.

You know the dimensions of the array you are initialising - it's not
hard to get the braces right. You might accidentally get the number of
elements wrong, but the braces are easy.

So how do you avoid getting the number of elements wrong? As Keith
said, for many large initialised arrays, the data is automatically
generated in some way. It is also very common for there to be a layout
pattern that makes errors more obvious. Having too many initialisers is
a constraint error (IIRC) - compilers should complain about that. Too
few initialisers is allowed, and missing initialisers will be filled
with zeros - that's considered a feature in C, not a bug (whether or not
you like it). If I had reason to suspect that I might be missing a
value in my own code, I would probably just add a fake value (so that I
have too many initialisers, assuming there was no missing value) and
check for the error or warning when compiling it.

More commonly, however, I simply don't give the length explicitly for
initialised arrays. So rather than writing:

enum { no_of_elems = 5 };
int xs[no_of_elems] = { 1, 2, 3, 4, 5 };

I'd write :

int xs[] = { 1, 2, 3, 4, 5 };
enum { no_of_elms = sizeof(xs) / sizeof(xs[0])};

And often I'd have a static_assert on "no_of_elms".

That gives pretty much no chance of errors in the number of initialisers.

For your own compiler, you are of course free to add warnings to check
initialiser counts and bracketing. Indeed, I would encourage it - that
helps users keep to a subset of C that you feel is safer. But in the
interests of compiling code from other sources, such warnings need to be
optional (or at least non-fatal).

>
>
>
>> Large initializers are likely to be automatically generated, so barring
>> a bug in the code generator this problem is unlikely to occur.
>>
>> [...]
>>
>> Please keep in mind that nobody here is either responsible for the
>> current rules or in any position to change them.
>
> I'm in a position to do that something about that, in a very small way.
> Somebody using my compiler /has/ to write {{1,2,3},{4,5,6}} not
> {1,2,3,4,5,6}, so that particular error can't get through.
>
> Such code is still valid C compilable anywhere. And that user may get
> into the habit of always getting the braces matching the data structure.
>

That's a good habit (IMHO). But if you are going to accept code from
other people, you need optional warnings rather than fatal errors.

> At the minute, if you see `= {0}` being used to initialise something in
> this strictly typed language, it can be initialsing ANY scalar type, ANY
> array of any number of dimensions, any size and any element type, and
> ANY struct.
>
> That is not a bit lax? OK..
>

You say "lax", others might say "flexible" or "consistent". And Keith
did not say that C was not lax - he merely said he does not think it is
as lax as you said it was.

You might not like the rules (and I would agree with you in this case),
but that does not make the rules bad, unclear or "lax" - it just means
they follow a different set of priorities and design rules that you
personally would prefer.

Re: MCC Compiler

<86zg051gx3.fsf@linuxsc.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30125&group=comp.lang.c#30125

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!rocksolid2!news.neodome.net!news.mixmin.net!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: tr.17...@z991.linuxsc.com (Tim Rentsch)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Thu, 26 Oct 2023 09:34:32 -0700
Organization: A noiseless patient Spider
Lines: 42
Message-ID: <86zg051gx3.fsf@linuxsc.com>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com> <uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com> <uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com> <uhbc8m$rd1b$1@dont-email.me> <87v8aujuxq.fsf@nosuchdomain.example.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: dont-email.me; posting-host="3aed70167cdc0c0f0f06e8d027845ce8";
logging-data="1816019"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/8V9nSJ4bgIRz/cwdm1isLAefism2/bqM="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:uVH2QI95O3ifgZtGee1bIA7DYNw=
sha1:iak04dLQ67+h+NL5lulDY5d5Vmw=
 by: Tim Rentsch - Thu, 26 Oct 2023 16:34 UTC

Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

> Bart <bc@freeuk.com> writes:
> [...]
>
>> Or take this sequence:
>>
>> int a = 0;
>> int b = {0};
>> int c = {{0}};
>>
>> The first is OK, so is the second (why?), but the third gives a
>> warning on gcc. (Mcc passes the first two and fails the third.)
>
> The first and second are OK because the standard explicitly says
> so. N1570 6.7.9p:
>
> The initializer for a scalar shall be a single expression,
> optionally enclosed in braces.
>
> As for the third, with "-std=c17 -pedantic-errors", gcc warns
> "braces around scalar initializer", while clang gives a fatal
> error "too many braces around scalar initializer".
>
> One could argue that "enclosed in braces" allows both {...} and
> {{...}}. I don't think I'd make that argument myself. But the
> requirement is in the Semantics section, not Constraints, so
> violating it is not a constraint violation. IMHO it *should* have
> been a constraint. I think clang is incorrect to reject it in
> conforming mode, [...]

I don't see how you reach the conclusion about clang. If you
think that in 6.7.9p11 the phrase "optionally enclosed in braces"
is meant to allow one pair of braces but not more than one, how
is it that you also think clang is not within its rights to
reject the declaration with two pairs of braces? The two
inferred statements seem inconsistent with respect to each other.
Is it that you think that violating a syntax rule or violating a
constraint are the only things that give an implementation
license to refuse to translate a source file? (Let me exclude
things like #error and #pragma from the discussion here.) I have
to admit to being baffled.

Re: MCC Compiler

<87il6tjjfb.fsf@nosuchdomain.example.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30130&group=comp.lang.c#30130

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Keith.S....@gmail.com (Keith Thompson)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Thu, 26 Oct 2023 12:03:04 -0700
Organization: None to speak of
Lines: 75
Message-ID: <87il6tjjfb.fsf@nosuchdomain.example.com>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
<uhbc8m$rd1b$1@dont-email.me>
<87v8aujuxq.fsf@nosuchdomain.example.com> <86zg051gx3.fsf@linuxsc.com>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Info: dont-email.me; posting-host="3fd89baf230d4414f6c1ba98670a74bd";
logging-data="1897298"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/h5929LSdQFCMHGjq9lb2b"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux)
Cancel-Lock: sha1:1tJIRkNp2F9x4vB612xNxEuAhj8=
sha1:d9jF819ecFtzhZwedGPip3Lm4Tk=
 by: Keith Thompson - Thu, 26 Oct 2023 19:03 UTC

Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>> Bart <bc@freeuk.com> writes:
>> [...]
>>> Or take this sequence:
>>>
>>> int a = 0;
>>> int b = {0};
>>> int c = {{0}};
>>>
>>> The first is OK, so is the second (why?), but the third gives a
>>> warning on gcc. (Mcc passes the first two and fails the third.)
>>
>> The first and second are OK because the standard explicitly says
>> so. N1570 6.7.9p:
>>
>> The initializer for a scalar shall be a single expression,
>> optionally enclosed in braces.
>>
>> As for the third, with "-std=c17 -pedantic-errors", gcc warns
>> "braces around scalar initializer", while clang gives a fatal
>> error "too many braces around scalar initializer".
>>
>> One could argue that "enclosed in braces" allows both {...} and
>> {{...}}. I don't think I'd make that argument myself. But the
>> requirement is in the Semantics section, not Constraints, so
>> violating it is not a constraint violation. IMHO it *should* have
>> been a constraint. I think clang is incorrect to reject it in
>> conforming mode, [...]
>
> I don't see how you reach the conclusion about clang. If you
> think that in 6.7.9p11 the phrase "optionally enclosed in braces"
> is meant to allow one pair of braces but not more than one, how
> is it that you also think clang is not within its rights to
> reject the declaration with two pairs of braces? The two
> inferred statements seem inconsistent with respect to each other.
> Is it that you think that violating a syntax rule or violating a
> constraint are the only things that give an implementation
> license to refuse to translate a source file? (Let me exclude
> things like #error and #pragma from the discussion here.) I have
> to admit to being baffled.

I did miss something. This:

int c = {{0}};

has undefined behavior (assuming that "optionally enclosed in braces"
isn't meant to allow multiple braces). A compiler may reject a program
that has undefined behavior. Or it may successfully translate it, or
make demons fly out of your nose during execution.

The question is why the standard made it UB rather than a constraint
violation. I can't think of any good reason. Perhaps it was meant
to cater to one or more implementations that happen to accept
it; personally, I wouldn't consider that to be a *good* reason.
(Note that this case of UB is explicitly mentioned in Annex J,
which might suggest that it was a deliberate choice.)

It's possible that clang is choosing to reject it because it has
undefined behavior (which raises questions about what happens if it's
enclosed in `if (0) { ... }`, but I won't get into that). My
impression, however, is that clang is treating the requirement
as if it were a constraint.

Do you think that clang is allowed to reject `int c = {{0}};`?

If so, on what basis do you think so?

(To be clear, I'm asking about a basis for rejecting it specifically
because of the extra braces.)

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

Re: MCC Compiler

<20231026134232.632@kylheku.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30133&group=comp.lang.c#30133

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: 864-117-...@kylheku.com (Kaz Kylheku)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Thu, 26 Oct 2023 20:59:12 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 36
Message-ID: <20231026134232.632@kylheku.com>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com>
<uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com>
<uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com>
<uhbc8m$rd1b$1@dont-email.me> <87v8aujuxq.fsf@nosuchdomain.example.com>
<uhcbvu$2qdm0$1@i2pn2.org> <87r0liji60.fsf@nosuchdomain.example.com>
Injection-Date: Thu, 26 Oct 2023 20:59:12 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="8988a328d4b4f50de2dad740a67ca720";
logging-data="1959104"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19obNIPcBc6QQ4KtKtBSfx5t8wqutZxZfk="
User-Agent: slrn/pre1.0.4-9 (Linux)
Cancel-Lock: sha1:f/y7M23sVpBLLJaJhNNgdzfgmMo=
 by: Kaz Kylheku - Thu, 26 Oct 2023 20:59 UTC

On 2023-10-26, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
> bart <bc@freeuk.com> writes:
>> It also allows this:
>>
>> int a[2][3] = {1,2,4,5,6};
>>
>> Element '3' has been left out by mistake. Now all elements are out of
>> step, and the last has value 0 instead of 6.
>>
>> I couldn't believe it when I discovered this.
>
> C allows something you don't like. You're shocked. Lather, rinse, repeat.

If the compilers that I use diagnose something, I don't necessarily care if
that is not required.

$ gcc -Wall -W braces.c
braces.c:1:15: warning: missing braces around initializer [-Wmissing-braces]
int a[2][3] = {1,2,4,5,6};
^
{ }{ }

The situations in which ISO C requires a diagnostic are rather sparse, and
there is no requirement to give any details about what is wrong and where.

A production compiler has to diagnose a lot more than that standard-required
minimum, and in more informative ways. This is a competitive area. If two
compilers optimize about equally well, and are similar in other attributes, you
might choose the one with better diagnostics (more diagnostics, more
configurable diagnostics, ...).

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

Re: MCC Compiler

<86edhd1jzk.fsf@linuxsc.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=30156&group=comp.lang.c#30156

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: tr.17...@z991.linuxsc.com (Tim Rentsch)
Newsgroups: comp.lang.c
Subject: Re: MCC Compiler
Date: Sun, 29 Oct 2023 09:17:19 -0700
Organization: A noiseless patient Spider
Lines: 88
Message-ID: <86edhd1jzk.fsf@linuxsc.com>
References: <uf3n7a$3lfik$1@dont-email.me> <867co9j4jf.fsf@linuxsc.com> <uf51vi$3tg5h$1@dont-email.me> <86pm21h8es.fsf@linuxsc.com> <uf6a2e$809b$1@dont-email.me> <864jir8fpw.fsf@linuxsc.com> <uhbc8m$rd1b$1@dont-email.me> <87v8aujuxq.fsf@nosuchdomain.example.com> <86zg051gx3.fsf@linuxsc.com> <87il6tjjfb.fsf@nosuchdomain.example.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: dont-email.me; posting-host="8287b7f320df8d3a443ae94f1f0ba80f";
logging-data="4176861"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/rPCa0fv+WlS/KMRJ0ipMb8vmLnW3v9Gw="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:gfew6bUfUNO37UiS/NeEqvMeAQo=
sha1:YfaY9f12/kS3JEYbVdeVyw8Pd9c=
 by: Tim Rentsch - Sun, 29 Oct 2023 16:17 UTC

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:
>>
>>> Bart <bc@freeuk.com> writes:
>>> [...]
>>>
>>>> Or take this sequence:
>>>>
>>>> int a = 0;
>>>> int b = {0};
>>>> int c = {{0}};
>>>>
>>>> The first is OK, so is the second (why?), but the third gives a
>>>> warning on gcc. (Mcc passes the first two and fails the third.)
>>>
>>> The first and second are OK because the standard explicitly says
>>> so. N1570 6.7.9p:
>>>
>>> The initializer for a scalar shall be a single expression,
>>> optionally enclosed in braces.
>>>
>>> As for the third, with "-std=c17 -pedantic-errors", gcc warns
>>> "braces around scalar initializer", while clang gives a fatal
>>> error "too many braces around scalar initializer".
>>>
>>> One could argue that "enclosed in braces" allows both {...} and
>>> {{...}}. I don't think I'd make that argument myself. But the
>>> requirement is in the Semantics section, not Constraints, so
>>> violating it is not a constraint violation. IMHO it *should* have
>>> been a constraint. I think clang is incorrect to reject it in
>>> conforming mode, [...]
>>
>> I don't see how you reach the conclusion about clang. If you
>> think that in 6.7.9p11 the phrase "optionally enclosed in braces"
>> is meant to allow one pair of braces but not more than one, how
>> is it that you also think clang is not within its rights to
>> reject the declaration with two pairs of braces? The two
>> inferred statements seem inconsistent with respect to each other.
>> Is it that you think that violating a syntax rule or violating a
>> constraint are the only things that give an implementation
>> license to refuse to translate a source file? (Let me exclude
>> things like #error and #pragma from the discussion here.) I have
>> to admit to being baffled.
>
> I did miss something. This:
>
> int c = {{0}};
>
> has undefined behavior (assuming that "optionally enclosed in braces"
> isn't meant to allow multiple braces). A compiler may reject a program
> that has undefined behavior. Or it may successfully translate it, or
> make demons fly out of your nose during execution.
>
> The question is why the standard made it UB rather than a constraint
> violation. I can't think of any good reason. Perhaps it was meant
> to cater to one or more implementations that happen to accept
> it; personally, I wouldn't consider that to be a *good* reason.
> (Note that this case of UB is explicitly mentioned in Annex J,
> which might suggest that it was a deliberate choice.)
>
> It's possible that clang is choosing to reject it because it has
> undefined behavior (which raises questions about what happens if it's
> enclosed in `if (0) { ... }`, but I won't get into that). My
> impression, however, is that clang is treating the requirement
> as if it were a constraint.
>
> Do you think that clang is allowed to reject `int c = {{0}};`?

I believe the intent of the C standard is that an implementation
may decline to accept a program containing this declaration and
still be conforming.

> If so, on what basis do you think so?

The standard requires implementations to accept any program that
is strictly conforming. Part of the definition of being strictly
conforming is that the program use only those features specified
in the standard. The standard does specify the case without any
braces, and also the case with exactly one pair of braces. I
agree with your reading of the phrase "optionally enclosed in
braces", from which follows the conclusion that the standard does
not specify using two pairs of braces around the '0' in this
declaration. Because the program is using a feature not
specified in the standard, the program is not strictly
conforming, and thus does not have to be accepted.

Pages:12
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor