On 14/05/2026 01:59, Janis Papanagnou wrote:[...]
(The point is that - with the exception of & ^ | - the ranking
makes perfectly sense
It doesn't make sense even then; here are the remaining groups for
binary ops from high to low:
(* / %) (+ -) (<< >>) (< <= >= >) (== !==) (&&) (||) (=)
Why are the shift operators at that spot? This causes chaos in
expressions like 'a << 3 + b' which are parsed as 'a << (3 + b)'.
Why are == and != lower precedence than the other compare operators?
In which circumstances would that be an advantage? This is just a
pointless extra level, as such usage would be so unusual that you'd
use parentheses anyway.
TBF, while other languages may not have as many levels, they also have questionable choices, because there are no standards.
At best it is generally agreed that there are 3 groups (4 including assignment) again arranged from high to low:
1 School arithmetic which everyone knows
2 Comparisons
3 Logical (and, or)
4 (Assignment)
These should be intuitive, all that's left is the ordering within
group 1 and group 3, and also where these extra ops need to go:
<< >> & | ^
In the case if C, it also decided that ?: belongs in this chart of
/binary/ operators. (I supposed you can consider each of ? and : as a
binary operator...)
In article <86pl2yi0n3.fsf@linuxsc.com>,[...]
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
My main point is that "byte" and "octet" are talking about
different kinds of things.
Not really. It has always been understood to refer to the same
kind of thing that "byte" refers to.
The problem was that, at the time the term "octet" was coined,
the size of a byte (measured in bits) varied between different
computers, and sometimes on the same computer. When people
starting getting serious about making computers talk to one
another, this became an issue: hence octet to have standard
nomenclature.
A computer might have 64k bytes of
RAM, but normally I wouldn't (and I think normally other people
wouldn't) say that a computer has 64k octets of RAM.
Some would, though it may sound a bit odd.
At this point, the term "byte" has been standardized by several
different bodies (IEC, ISO) to be synonymous with octet. The
continued use of "octet" by organizations like the IETF is
mostly a legacy curiosity.
Unary operators aren't the problem. It's a mystery why they need to be[...]
in a table at all. Nobody's going to think that '&a + b' means '&(a +
b)'.
On 14/05/2026 03:58, Keith Thompson wrote:[...]
With nested loops, "break" or "continue" always refers to the
innermost loop. With a switch statement inside a loop, "break"
refers to the switch statement, but "continue" refers to the loop.
It's obviously not impossible to deal with, but I find it mildly
annoying.
Break doing the two jobs is a flaw. 'break' and 'continue' being
inconsistent is a further one:
Suppose you have a loop, and within the loop, you have an if-else-if
chain within which are 'break' and 'continue' statements.
You decide that that if-else-if chain is better off as a switch. But
now, while 'continue' continues to do its job, 'break' silently
behaves differently.
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
[...] the issue being discussed was that multiple cases (that may
not be contiguous) depend on the default fallthrough behavior.
case 10:
case 20:
case 30:
whatever();
break;
In a hypothetical C-like language without default fallthrough, it
would make sense to invent a different syntax. For C repeating the
"case" keyword is slightly ugly, but probably not worth fixing.
Both gcc and clang, with options -std=c99 -pedantic -Wall -Wextra,
accept the code below and give no diagnostics:
#include <stdio.h>
#include "cases.h"
int
main( int argc, char *argv[] ){
switch( argc-1 ){
cases( 2, 3, 5, 8 ):
The cases() macro is a fairly straightforward application of variadic
macros, as follows:
#define ARGS_N_(...) \
ARGS_N_X_( __VA_ARGS__, \
09, 08, 07, 06, 05, 04, 03, 02, 01, 00 \
)
#define ARGS_N_X_( dummy, _9, _8, _7, _6, _5, _4, _3, _2, _1, ... ) _1
#define cases(...) casesx_( ARGS_N_( __VA_ARGS__ ), __VA_ARGS__ )
#define casesx_( N, ... ) casesy_( N, __VA_ARGS__ )
#define casesy_( N, ... ) cases_ ## N ## _( __VA_ARGS__ )
#define cases_01_(a) case a
#define cases_02_(a,...) case a : cases_01_( __VA_ARGS__ )
#define cases_03_(a,...) case a : cases_02_( __VA_ARGS__ )
#define cases_04_(a,...) case a : cases_03_( __VA_ARGS__ )
#define cases_05_(a,...) case a : cases_04_( __VA_ARGS__ )
#define cases_06_(a,...) case a : cases_05_( __VA_ARGS__ )
#define cases_07_(a,...) case a : cases_06_( __VA_ARGS__ )
#define cases_08_(a,...) case a : cases_07_( __VA_ARGS__ )
#define cases_09_(a,...) case a : cases_08_( __VA_ARGS__ )
It's easy to see how to extend this definition to allow more cases, if
that is needed.
Personally I would rather have something that works in C99, etc, now,
than to wait for some possible change at some point in the indefinite
future.
Bart <bc@freeuk.com> writes:
On 14/05/2026 01:59, Janis Papanagnou wrote:[...]
(The point is that - with the exception of & ^ | - the ranking
makes perfectly sense
It doesn't make sense even then; here are the remaining groups for
binary ops from high to low:
(* / %) (+ -) (<< >>) (< <= >= >) (== !==) (&&) (||) (=)
Why are the shift operators at that spot? This causes chaos in
expressions like 'a << 3 + b' which are parsed as 'a << (3 + b)'.
I've never heard anyone claim that C's operator precedence rules are
ideal. They aren't. But they can't be changed without breaking
existing code, so there's little point in complaining about it.
TBF, while other languages may not have as many levels, they also have
questionable choices, because there are no standards.
Plenty of other languages have standards.
At best it is generally agreed that there are 3 groups (4 including
assignment) again arranged from high to low:
Agreed by whom?
1 School arithmetic which everyone knows
2 Comparisons
3 Logical (and, or)
4 (Assignment)
Bart <bc@freeuk.com> writes:
Why are == and != lower precedence than the other compare operators?
In which circumstances would that be an advantage? This is just a
pointless extra level, as such usage would be so unusual that you'd
use parentheses anyway.
I suggest that it doesn't matter why. It is what it is. And yes,
I'd add parentheses in the unlikely event that I needed to write
an expression that uses both equality and comparison operators
(unless I were writing deliberately obfuscated code, which I've
been known to do).
[...]
These should be intuitive, all that's left is the ordering within
group 1 and group 3, and also where these extra ops need to go:
<< >> & | ^
[...][...]
Bart <bc@freeuk.com> writes:
[...]
Unary operators aren't the problem. It's a mystery why they need to be[...]
in a table at all. Nobody's going to think that '&a + b' means '&(a +
b)'.
It would be silly for an operator precedence tables to omit the
operators that "everybody knows". If I had a table that didn't
show *all* the operators, I'd look for a better table (like the
one in K&R2).
On 14/05/2026 01:59, Janis Papanagnou wrote:
[...]
(The point is that - with the exception of & ^ | - the ranking
makes perfectly sense
It doesn't make sense even then; [...]
[...]
TBF, while other languages may not have as many levels, they also have questionable choices, because there are no standards.
[...]
In the case if C, it also decided that ?: belongs in this chart of /
binary/ operators. (I supposed you can consider each of ? and : as a
binary operator...)
On 14/05/2026 16:37, Tim Rentsch wrote:
[...]
1. unary operators are always ahead of binary operators, first
those on the right and then those on the left;
Unary operators aren't the problem. It's a mystery why they need to be
in a table at all. [...]
[...]
On 15/05/2026 00:40, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
Unary operators aren't the problem. It's a mystery why they need to be[...]
in a table at all. Nobody's going to think that '&a + b' means '&(a +
b)'.
It would be silly for an operator precedence tables to omit the
operators that "everybody knows". If I had a table that didn't
show *all* the operators, I'd look for a better table (like the
one in K&R2).
Do you need to know the precedence of a unary operator (say applied to
any of these terms) in order to correctly parse this:
a op1 b op2 c
?
'a b c' are terms, and 'op1 op2' are operators. You need to know their relative precedences in order to correctly parse this as either '(a
op1 b) op2 c' or 'a op1 (b op2 c)'. Any unary ops on those terms don't
affect that.
On 14/05/2026 20:19, Bart wrote:
[...]
I certainly agree it would be odd if there were binary arithmetic
operators with higher precedence than unary operators. [...]
On 2026-05-14 20:50, David Brown wrote:
On 14/05/2026 20:19, Bart wrote:
[...]
I certainly agree it would be odd if there were binary arithmetic
operators with higher precedence than unary operators. [...]
I've just posted an example; exponentiation. It depends on the
language. (Below examples from Algol 68 and Awk...)
$ genie -p '-2^4'
+16
$ awk 'BEGIN{print -2^4}'
-16
But (I think; unless that has changed) "C" has no exponentiation
operator, so it doesn't apply here at least.
But if you start with any new language you have to inspect the
documentation about its operators and their precedence rules.
cross@spitfire.i.gajendra.net (Dan Cross) writes:
[...]
At this point, the term "byte" has been standardized by several
different bodies (IEC, ISO) to be synonymous with octet. The
continued use of "octet" by organizations like the IETF is
mostly a legacy curiosity.
Has it? The ISO C and C++ standards certainly do not use "byte"
to mean exactly 8 bits. ISO/IEC 2382 says:
byte
string that consists of a number of bits, treated as a unit, and
usually representing a character or a part of a character
Note 1 to entry: The number of bits in a byte is fixed for a given
data processing system.
Note 2 to entry: The number of bits in a byte is usually 8.
and
octet
8-bit byte
byte that consists of eight bits
<https://www.iso.org/obp/ui/#iso:std:iso-iec:2382:ed-1:v2:en>
The latter implies that you can't have octets on a system with,
say, 16-bit bytes, which doesn't match what I would have expected.
I would think it would be reasonable to say that a system with
16-bit bytes has, say, 32k bytes or 64k octets of memory. But C
doesn't use the word "octet", so this is at best marginally topical.
[...]
It's not really helped by having having a table that combines
precedences of different kinds of operator.
[...]--- Synchronet 3.22a-Linux NewsLink 1.2
Anyone curious about how far C's switch statements can be used or
abused, might like to read about "Protothreads" :
<https://en.wikipedia.org/wiki/Protothread>
This is a conglomeration of Duff's Device on steroids with supporting
macros that gives you a limited type of stackless cooperative
multitasking with extremely low overhead. The library has seen real
usage in small embedded systems. Reactions to the underlying implementation range from thinking it is a hideous abuse of a bad
language design, to elegant and very ingenious.
In article <86pl2yi0n3.fsf@linuxsc.com>,[...]
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
My main point is that "byte" and "octet" are talking about
different kinds of things.
Not really. It has always been understood to refer to the same
kind of thing that "byte" refers to.
I agree, at least for the way I understand the terms. For me,
"octet" and "byte" refer to the same kind of thing. The difference
is that an "octet" is specifically 8 bits, and a "byte" is a
fundamental unit of storage for a given system (commonly 8 bits).
ISO/IEC 2382 happens to agree with me.
The problem was that, at the time the term "octet" was coined,
the size of a byte (measured in bits) varied between different
computers, and sometimes on the same computer. When people
starting getting serious about making computers talk to one
another, this became an issue: hence octet to have standard
nomenclature.
A computer might have 64k bytes of
RAM, but normally I wouldn't (and I think normally other people
wouldn't) say that a computer has 64k octets of RAM.
Some would, though it may sound a bit odd.
Agreed. "64k bytes" is certainly more common, but "64k octets"
means essentially the same thing while being more specific.
Also, the "k" suffix formally means 1000, but is often used to mean
1024, which is why we have "Ki", "kibi" to denote a power of two
explicitly.
[...]]
At this point, the term "byte" has been standardized by several
different bodies (IEC, ISO) to be synonymous with octet. The
continued use of "octet" by organizations like the IETF is
mostly a legacy curiosity.
Has it?
The ISO C and C++ standards certainly do not use "byte"
to mean exactly 8 bits.
ISO/IEC 2382 says:
byte
string that consists of a number of bits, treated as a unit, and
usually representing a character or a part of a character
Note 1 to entry: The number of bits in a byte is fixed for a given
data processing system.
Note 2 to entry: The number of bits in a byte is usually 8.
and
octet
8-bit byte
byte that consists of eight bits
<https://www.iso.org/obp/ui/#iso:std:iso-iec:2382:ed-1:v2:en>
The latter implies that you can't have octets on a system with,
say, 16-bit bytes, which doesn't match what I would have expected.
I would think it would be reasonable to say that a system with
16-bit bytes has, say, 32k bytes or 64k octets of memory. But C
doesn't use the word "octet", so this is at best marginally topical.
It's not really helped by having having a table that combines[...]
precedences of different kinds of operator.
In article <10u5m4m$uo0d$3@kst.eternal-september.org>,[...]
Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
cross@spitfire.i.gajendra.net (Dan Cross) writes:
At this point, the term "byte" has been standardized by several
different bodies (IEC, ISO) to be synonymous with octet. The
continued use of "octet" by organizations like the IETF is
mostly a legacy curiosity.
Has it?
Yes. IEC 80000-13 declares them to be synonyms.
In article <10u5m4m$uo0d$3@kst.eternal-september.org>,[...]
Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >>>cross@spitfire.i.gajendra.net (Dan Cross) writes:
At this point, the term "byte" has been standardized by several
different bodies (IEC, ISO) to be synonymous with octet. The
continued use of "octet" by organizations like the IETF is
mostly a legacy curiosity.
Has it?
Yes. IEC 80000-13 declares them to be synonyms.
Interesting. It's odd that ISO/IEC 2382 and ISO/IEC 80000-13
disagree with each other.
<https://www.iso.org/standard/87648.html>
IEC 80000-13:2025 Quantities and units
Part 13: Information science and technology
I'm not going to spend 115 Swiss Francs (currently
146.39 USD) to get a copy.
If you have a copy, can you quote the relevant wording?
On 2026-05-14 20:50, David Brown wrote:
On 14/05/2026 20:19, Bart wrote:
[...]
I certainly agree it would be odd if there were binary arithmetic
operators with higher precedence than unary operators. [...]
I've just posted an example; exponentiation. It depends on the
language. (Below examples from Algol 68 and Awk...)
$ genie -p '-2^4'
+16
$ awk 'BEGIN{print -2^4}'
-16
But (I think; unless that has changed) "C" has no exponentiation
operator, so it doesn't apply here at least.
But if you start with any new language you have to inspect the
documentation about its operators and their precedence rules.
Janis
On 15/05/2026 00:40, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
Unary operators aren't the problem. It's a mystery why they need to be[...]
in a table at all. Nobody's going to think that '&a + b' means '&(a +
b)'.
It would be silly for an operator precedence tables to omit the
operators that "everybody knows". If I had a table that didn't
show *all* the operators, I'd look for a better table (like the
one in K&R2).
Do you need to know the precedence of a unary operator (say applied to
any of these terms) in order to correctly parse this:
a op1 b op2 c
?
'a b c' are terms, and 'op1 op2' are operators. You need to know their relative precedences in order to correctly parse this as either '(a op1
b) op2 c' or 'a op1 (b op2 c)'. Any unary ops on those terms don't
affect that.
On 15/05/2026 02:31, Bart wrote:[...]
Do you need to know the precedence of a unary operator (say applied
to any of these terms) in order to correctly parse this:
a op1 b op2 c
?
'a b c' are terms, and 'op1 op2' are operators. You need to know
their relative precedences in order to correctly parse this as
either '(a op1 b) op2 c' or 'a op1 (b op2 c)'. Any unary ops on
those terms don't affect that.
That argument makes no sense.
$ awk 'BEGIN{print -2^4}'
-16
On 15/05/2026 02:31, Bart wrote:
On 15/05/2026 00:40, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
Unary operators aren't the problem. It's a mystery why they need to be >>>> in a table at all. Nobody's going to think that '&a + b' means '&(a +[...]
b)'.
It would be silly for an operator precedence tables to omit the
operators that "everybody knows". If I had a table that didn't
show *all* the operators, I'd look for a better table (like the
one in K&R2).
Do you need to know the precedence of a unary operator (say applied to
any of these terms) in order to correctly parse this:
a op1 b op2 c
?
'a b c' are terms, and 'op1 op2' are operators. You need to know their
relative precedences in order to correctly parse this as either '(a
op1 b) op2 c' or 'a op1 (b op2 c)'. Any unary ops on those terms don't
affect that.
That argument makes no sense.
You don't need to know where binary "-" fits in the precedence ordering
in order to correctly parse :
a + b / c
However, I doubt if you would be happy with a table of operators that omitted binary minus.
Yes, it would be possible to draw tables of C operator precedence where
you had separate tables for each type of operator, and then a separate description of how they fit together. But it is a lot simpler, clearer
and easier to use if you have a table that includes them all.
"switch" was originally implemented in a way that, I suspect, was
easier for the compiler to implement
"switch" was originally implemented in a way that, I suspect, was
easier for the compiler to implement
It would also have been familiar from BCPL. When C was designed, switch
would have been recognised as a direct equivalent of BCPL's SWITCHON >construct:
https://archive.org/details/bcpl_20200522/page/19/mode/2up
There's no equivalent of break in that version of BCPL; if you look at >example code from that era (e.g. the Xerox Alto BCPL manuals), the
convention was to use GOTO at the end of each case with a label after
the block. Later versions of BCPL have ENDCASE which works like break:
https://archive.org/details/DTIC_ADA003599/page/41/mode/2up
(and I wonder whether this was influenced by C).
On 15/05/2026 09:32, David Brown wrote:
On 15/05/2026 02:31, Bart wrote:
On 15/05/2026 00:40, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
Unary operators aren't the problem. It's a mystery why they need to be >>>>> in a table at all. Nobody's going to think that '&a + b' means '&(a + >>>>> b)'.[...]
It would be silly for an operator precedence tables to omit the
operators that "everybody knows". If I had a table that didn't
show *all* the operators, I'd look for a better table (like the
one in K&R2).
Do you need to know the precedence of a unary operator (say applied to
any of these terms) in order to correctly parse this:
a op1 b op2 c
?
'a b c' are terms, and 'op1 op2' are operators. You need to know their
relative precedences in order to correctly parse this as either '(a
op1 b) op2 c' or 'a op1 (b op2 c)'. Any unary ops on those terms don't
affect that.
That argument makes no sense.
You don't need to know where binary "-" fits in the precedence ordering
in order to correctly parse :
a + b / c
However, I doubt if you would be happy with a table of operators that
omitted binary minus.
What do you mean by 'binary "-"' and 'binary minus'?
Are they both the
operator in "x - y" or did one or both mean the unary negation operator
in "-z"?
Yes, it would be possible to draw tables of C operator precedence where
you had separate tables for each type of operator, and then a separate
description of how they fit together. But it is a lot simpler, clearer
and easier to use if you have a table that includes them all.
Disagree: in C, the only thing I've used the precedence table for is for
the relative precedence of op1 and op2 in examples like mine.
It's not even useful inside C compilers; you tend to follow the grammar >rather than have it table-driven using such a chart.
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
"switch" was originally implemented in a way that, I suspect, was
easier for the compiler to implement
It would also have been familiar from BCPL. When C was designed, switch
would have been recognised as a direct equivalent of BCPL's SWITCHON construct:
https://archive.org/details/bcpl_20200522/page/19/mode/2up
There's no equivalent of break in that version of BCPL; if you look at example code from that era (e.g. the Xerox Alto BCPL manuals), the
convention was to use GOTO at the end of each case with a label after
the block. Later versions of BCPL have ENDCASE which works like break:
https://archive.org/details/DTIC_ADA003599/page/41/mode/2up
(and I wonder whether this was influenced by C).
In article <10u5m4m$uo0d$3@kst.eternal-september.org>,
Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
cross@spitfire.i.gajendra.net (Dan Cross) writes:
In article <86pl2yi0n3.fsf@linuxsc.com>,[...]
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Also, the "k" suffix formally means 1000, but is often used to mean
1024, which is why we have "Ki", "kibi" to denote a power of two
explicitly.
Yes. K, M, G, etc, have always been the SI indicators for
powers of 10, not powers of 2. The "Ki", "Mi", "Gi", etc, forms
are (as I understand it) relatively new.
[...]]
At this point, the term "byte" has been standardized by several
different bodies (IEC, ISO) to be synonymous with octet. The
continued use of "octet" by organizations like the IETF is
mostly a legacy curiosity.
Has it?
Yes. IEC 80000-13 declares them to be synonyms.
The ISO C and C++ standards certainly do not use "byte"
to mean exactly 8 bits.
Indeed. I don't blame them. I suspect there are some DSP chips
or weird one-off processors with oddball byte sizes, even now.
I would think it would be reasonable to say that a system with
16-bit bytes has, say, 32k bytes or 64k octets of memory. But C
doesn't use the word "octet", so this is at best marginally topical.
I wonder. For word oriented systems, it was common to describe
memory in terms of words (e.g., "the KL-10B processor with
extended addressing supports a maximum of 4 MW of memory...").
Similarly, even for byte-addressed machines, like the PDP-11,
memory capacities were often described in terms of 16-bit words
("this machine has 256 KW of memory", aka, 512 KB). [Of course,
these machines all predate common use if the "Ki" and "Mi"
units). Anyway, there is some precedent for using the machine
specific sizes in discussion, though I agree generally that
using octets makes sense in this context.
None of this has much to do with C, though, as you point out.
- Dan C.
On 15/05/2026 09:32, David Brown wrote:
On 15/05/2026 02:31, Bart wrote:
On 15/05/2026 00:40, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
Unary operators aren't the problem. It's a mystery why they need to be >>>>> in a table at all. Nobody's going to think that '&a + b' means '&(a + >>>>> b)'.[...]
It would be silly for an operator precedence tables to omit the
operators that "everybody knows". If I had a table that didn't
show *all* the operators, I'd look for a better table (like the
one in K&R2).
Do you need to know the precedence of a unary operator (say applied
to any of these terms) in order to correctly parse this:
a op1 b op2 c
?
'a b c' are terms, and 'op1 op2' are operators. You need to know
their relative precedences in order to correctly parse this as either
'(a op1 b) op2 c' or 'a op1 (b op2 c)'. Any unary ops on those terms
don't affect that.
That argument makes no sense.
You don't need to know where binary "-" fits in the precedence
ordering in order to correctly parse :
a + b / c
However, I doubt if you would be happy with a table of operators that
omitted binary minus.
What do you mean by 'binary "-"' and 'binary minus'? Are they both the operator in "x - y" or did one or both mean the unary negation operator
in "-z"?
In my example, 'a b c' each represent arbitrary terms. These are
examples of such terms:
-x
&x
++x[i]
x(i, j)
(x + y)
x.m--
-(+(-(sizeof(x))))
In article <10u6t2n$4mai$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
On 15/05/2026 09:32, David Brown wrote:
On 15/05/2026 02:31, Bart wrote:
On 15/05/2026 00:40, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
Unary operators aren't the problem. It's a mystery why they need to be >>>>>> in a table at all. Nobody's going to think that '&a + b' means '&(a + >>>>>> b)'.[...]
It would be silly for an operator precedence tables to omit the
operators that "everybody knows". If I had a table that didn't
show *all* the operators, I'd look for a better table (like the
one in K&R2).
Do you need to know the precedence of a unary operator (say applied to >>>> any of these terms) in order to correctly parse this:
a op1 b op2 c
?
'a b c' are terms, and 'op1 op2' are operators. You need to know their >>>> relative precedences in order to correctly parse this as either '(a
op1 b) op2 c' or 'a op1 (b op2 c)'. Any unary ops on those terms don't >>>> affect that.
That argument makes no sense.
You don't need to know where binary "-" fits in the precedence ordering
in order to correctly parse :
a + b / c
However, I doubt if you would be happy with a table of operators that
omitted binary minus.
What do you mean by 'binary "-"' and 'binary minus'?
As a binary operator, `-` refers to subtraction. Note that the
expression quoted above does not contain subtraction. Therefore
one does to need to know the precedence of the subtraction
operator to parse that expression.
'binary "-"' and 'binary minus' mean the same thing; in the
former he used a literal `-` character, and in the latter he
substituted the name of the symbol.
Are they both the
operator in "x - y" or did one or both mean the unary negation operator
in "-z"?
It says it right there on the tin, dude. It ain't that hard.
Disagree: in C, the only thing I've used the precedence table for is for
the relative precedence of op1 and op2 in examples like mine.
Not the flex you think it is....
On 15/05/2026 12:38, Bart wrote:
On 15/05/2026 09:32, David Brown wrote:
However, I doubt if you would be happy with a table of operators that
omitted binary minus.
What do you mean by 'binary "-"' and 'binary minus'? Are they both the
operator in "x - y" or did one or both mean the unary negation
operator in "-z"?
I meant "binary minus", written either "minus" or "-". If I had meant unary minus or negation, I would not have written "binary".
In my example, 'a b c' each represent arbitrary terms. These are
examples of such terms:
-x
&x
++x[i]
x(i, j)
(x + y)
x.m--
-(+(-(sizeof(x))))
Yes. So?
What you wrote is that if you have an expression where only the binary operators are of relevance or interest, you only need a table of the
binary operators in order to understand the interaction between them.
I pointed out that the same logic applies if you have an expression
where only some binary operators are used - you only need a table with
those binary operators in order to understand the interactions.
There is no benefit in having multiple tables for the normal operators
in a language - it is simpler and clearer to put them all in one table. Isolating the unary operators is no more logical or useful than
isolating the binary minus operator.
Prefix and Postfix ops together, when clustered around a specific term,
have their own set of rules. They are quite different from binary ops.
scott@slp53.sl.home (Scott Lurndal) writes:
cross@spitfire.i.gajendra.net (Dan Cross) writes:[...]
In article <10u2jpk$2t96p$6@kst.eternal-september.org>,
If C's switch statement were to be
changed, it would have to use something that's currently a syntax >>>>error. Perhaps something like
case 1, case 2, case 3, case 4: whatever();
Sure, that's better.
case 1...4: whatever();
is a typical GCC extension (that we use heavily).
Yes, and the C2y draft adopts that syntax.
(One possible reason it wasn't adopted sooner is that `case 'a'...'z'` >doesn't necessarily work if the letters are not contiguous, for
example in EBCDIC.)
On 15/05/2026 14:54, Bart wrote:
Prefix and Postfix ops together, when clustered around a specific term,
have their own set of rules. They are quite different from binary ops.
I'm going to bail out here. This is not going anywhere.
Either people don't understand the subject, or are pretending not to, or >just want to have a go.
I have quite a bit of knowledge and practical experience of the subject, >even if people here don't like to admit that, but I'm poor at getting
the point across.
I will reconsider my claim that precedence tables don't need to include >anything beyond binary ops, if somebody can give a reference to such a
table in the C standard.
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
[...]
(One possible reason it wasn't adopted sooner is that `case 'a'...'z'`
doesn't necessarily work if the letters are not contiguous, for
example in EBCDIC.)
I think that's a bit far-fetched. Regular expressions
have the same EBCDIC related issues (i.e. the discontinuous
nature of the EBCDIC alpha translations); yet, there are
no other defined characters in the gaps between the
alpha groups in EBCDIC, so [a-z] or "case 'a'...'z':" would
probably work just fine in most cases to match lowercase EBCDIC
alpha text.
Worse case, it could be coded as
case 'a'...'i': /* FALLTHROUGH */
case 'j'...'r': /* FALLTHROUGH */
case 's'...'z':
do something;
break;
On 15/05/2026 14:54, Bart wrote:
Prefix and Postfix ops together, when clustered around a specific
term, have their own set of rules. They are quite different from
binary ops.
I'm going to bail out here. This is not going anywhere.
Either people don't understand the subject, or are pretending not to,
or just want to have a go.
I have quite a bit of knowledge and practical experience of the
subject, even if people here don't like to admit that, but I'm poor at getting the point across.
I will reconsider my claim that precedence tables don't need to
include anything beyond binary ops, if somebody can give a reference
to such a table in the C standard.
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
cross@spitfire.i.gajendra.net (Dan Cross) writes:[...]
In article <10u2jpk$2t96p$6@kst.eternal-september.org>,
If C's switch statement were to be
changed, it would have to use something that's currently a syntax >>>>>error. Perhaps something like
case 1, case 2, case 3, case 4: whatever();
Sure, that's better.
case 1...4: whatever();
is a typical GCC extension (that we use heavily).
Yes, and the C2y draft adopts that syntax.
(One possible reason it wasn't adopted sooner is that `case 'a'...'z'` >>doesn't necessarily work if the letters are not contiguous, for
example in EBCDIC.)
I think that's a bit far-fetched. Regular expressions
have the same EBCDIC related issues (i.e. the discontinuous
nature of the EBCDIC alpha translations); yet, there are
no other defined characters in the gaps between the
alpha groups in EBCDIC, so [a-z] or "case 'a'...'z':" would
probably work just fine in most cases to match lowercase EBCDIC
alpha text.
Worse case, it could be coded as
case 'a'...'i': /* FALLTHROUGH */
case 'j'...'r': /* FALLTHROUGH */
case 's'...'z':
do something;
break;
Bart <bc@freeuk.com> writes:[...]
I will reconsider my claim that precedence tables don't need to
include anything beyond binary ops, if somebody can give a reference
to such a table in the C standard.
That's disingenuous. You know, because you've been told several
times in this thread, that there is precedence table in the C
standard. You also know that there is a precedence table, that
includes unary, postfix, binary, and ternary operators, in K&R2.
gcc and C2Y use "..." rather than ".." because it's an existing token,
used in variadic function declarations. `1..4` is actually a
preprocessing number, resulting in a syntax error when it's
converted to an integer constant.
Bart <bc@freeuk.com> writes:
On 15/05/2026 14:54, Bart wrote:
Prefix and Postfix ops together, when clustered around a specific
term, have their own set of rules. They are quite different from
binary ops.
I'm going to bail out here. This is not going anywhere.
Either people don't understand the subject, or are pretending not to,
or just want to have a go.
I have quite a bit of knowledge and practical experience of the
subject, even if people here don't like to admit that, but I'm poor at
getting the point across.
I think that most of us found your idea that precedence tables
should exclude unary ops to be so bizarre that we weren't sure you
actually meant it.
I will reconsider my claim that precedence tables don't need to
include anything beyond binary ops, if somebody can give a reference
to such a table in the C standard.
That's disingenuous. You know, because you've been told several
times in this thread, that there is precedence table in the C
standard.
You also know that there is a precedence table, that
includes unary, postfix, binary, and ternary operators, in K&R2.
Your personal preference for a precedence table that excludes unary
and postfix operators is perfectly valid for you. Other people's
preference for a table that includes all the operators is perfectly
valid for them. (The evidence so far suggests that the latter
includes everyone but you.)
cross@spitfire.i.gajendra.net (Dan Cross) writes:
In article <10u2jpk$2t96p$6@kst.eternal-september.org>,
Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
cross@spitfire.i.gajendra.net (Dan Cross) writes:
In article <10u0k0k$1l93l$30@dont-email.me>,[...]
It's easy to get wrong. Other languages accommodate both
semantics using alternation in the selector arm. For example,
one might imagine an hypothetical syntax, something like:
switch (a) {
case 1 || 2 || 3 || 4: whatever();
default: other();
}
...with no `break` to end each `case`.
That's already valid syntax.
It wasn't meant to be taken as a serious suggestion!
If C's switch statement were to be
changed, it would have to use something that's currently a syntax
error. Perhaps something like
case 1, case 2, case 3, case 4: whatever();
Sure, that's better.
case 1...4: whatever();
is a typical GCC extension (that we use heavily).
On 15/05/2026 20:23, Keith Thompson wrote:[...]
I think that most of us found your idea that precedence tables
should exclude unary ops to be so bizarre that we weren't sure you
actually meant it.
Well, I find it bizarre that they should!
That's disingenuous. You know, because you've been told several
times in this thread, that there is precedence table in the C
standard.
Whereabouts?
scott@slp53.sl.home (Scott Lurndal) writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
scott@slp53.sl.home (Scott Lurndal) writes:
cross@spitfire.i.gajendra.net (Dan Cross) writes:[...]
In article <10u2jpk$2t96p$6@kst.eternal-september.org>,
If C's switch statement were to be
changed, it would have to use something that's currently a syntax >>>>>>error. Perhaps something like
case 1, case 2, case 3, case 4: whatever();
Sure, that's better.
case 1...4: whatever();
is a typical GCC extension (that we use heavily).
Yes, and the C2y draft adopts that syntax.
(One possible reason it wasn't adopted sooner is that `case 'a'...'z'` >>>doesn't necessarily work if the letters are not contiguous, for
example in EBCDIC.)
I think that's a bit far-fetched. Regular expressions
have the same EBCDIC related issues (i.e. the discontinuous
nature of the EBCDIC alpha translations); yet, there are
no other defined characters in the gaps between the
alpha groups in EBCDIC, so [a-z] or "case 'a'...'z':" would
probably work just fine in most cases to match lowercase EBCDIC
alpha text.
I understand there are different versions of EBCDIC. According to
the table in the Wikipedia article, '~' is between 'r' and 's',
'}' is between 'I' and 'J', and '\\' is between 'R' and 'S'.
In fact EBCDIC, though not mentioned by name, was part of the reason for
not supporting case ranges. Quoting the ANSI C Rationale:
[...]The fewer precedence groups you have the more parentheses you will
This is information about Go [...]
[snip table]
[...]
On 2026-05-15 22:39, Bart wrote:
[...]The fewer precedence groups you have the more parentheses you will
have to use in expressions.
And vice versa. - The actual choice is
a decision of the respective language designers.
Actually, ranges of about ten levels seem to be not uncommon amongst programming languages to provide a sensible, widely accepted grouping. Language designers seem to be trying to avoid a flood of unnecessary parentheses in programs.
And here's a precedence table for another language that facilitates...
that there's no parenthesis at all necessary to obtain unambiguous expressions:
lvl op
---------
1 !!
2 !§
3 !$
61 =/
62 =+
63 =~
64 ==
And here a variant with only one level of operator precedence,
all listed in a single group[*]
!! !§ !$ !% !/ !+ !~ != §! §§ §$ §% §/ §+ §~ §=
$! $§ $$ $% $/ $+ $~ $= %! %§ %$ %% %/ %+ %~ %=
/! /§ /$ /% // /+ /~ /= +! +§ +$ +% +/ ++ +~ +=
~! ~§ ~$ ~% ~/ ~+ ~~ ~= =! =§ =$ =% =/ =+ =~ ==
Bart <bc@freeuk.com> writes:
The one for the ?: operator is particularly obscure, so in an
expression like one of these:
a + b ? c - d : e * f
a ? b ? c : d ? e : f : g
[...]
The lines are not meant to mean anything, just sequences of terms and operators. You can think of them as exercises where you add parentheses
to make them unambiguous.
In the case if C, it also decided that ?: belongs in this chart of /
binary/ operators. (I supposed you can consider each of ? and : as a
binary operator...)
On 2026-05-14 13:32, Bart wrote:
...
In the case if C, it also decided that ?: belongs in this chart of /
binary/ operators. (I supposed you can consider each of ? and : as a
binary operator...)
When and where was that decided? There's a big difference between
putting ?: in a chart along with binary and unary operators (which
happened in section 2.12 of the 1st edition of K&R) and putting it in a
chart of binary operators. To the best of my knowledge, the latter never happened. Could you please identify where it did?
If you read my post again, you'll find that 'this chart' most likely
refers to my suggested chart containing those 4 groups I mentioned.
That chart contains a set of binary (and infix) operators that also
appear in K&R2. I'm saying that whoever put that together in K&R2
decided that ?: belonged in this set.
(Personally I don't, as I don't consider a ?:-like feature to be an
operator,
but even it it was, a 3-way operator is a poor fit when all
the others are 2-way.)
On 11/05/2026 20:06, Waldek Hebisch wrote:
[...] But now hackers from
hostile country can break critical systems (shut down
electricity in whole county, destroy electric plants, stop
vital pipeline from operationg, etc) and goverments got
more serious.
[...]
With these hackers, why are critical systems connected to the public internet in the first place?
On 2026-05-11 22:29, Bart wrote:
On 11/05/2026 20:06, Waldek Hebisch wrote:
[...] But now hackers from
hostile country can break critical systems (shut down
electricity in whole county, destroy electric plants, stop
vital pipeline from operationg, etc) and goverments got
more serious.
Can they do that; generally? - My experience is that it depends
on who has done, and who is accountable for the systems setups.
And it depends on the requested and applied national standards.
[...]
With these hackers, why are critical systems connected to the public
internet in the first place?
Good question; for those systems where that is the case.
The reality looks different. Or, rather; it depends on where you
look into. (Our country is very keen of its security standards.)
But then, there's also critical infrastructure that is inherently
"connected to the public internet", for example because its task
is no connect the public or provide public services.
Nuclear plants (and other critical infrastructure) certainly don't
need their _control system_ be "connected to the public internet".
There's applied and long existing security concepts established.
Alas, contemporary IT-systems' evolution seems to start disrespect
such long existing expertise and wisdom. The good thing is, though,
that there's still instances who have a close look at the evolution.
Janis
Bart <bc@freeuk.com> writes:
[...]
If you read my post again, you'll find that 'this chart' most likely
refers to my suggested chart containing those 4 groups I mentioned.
That chart contains a set of binary (and infix) operators that also
appear in K&R2. I'm saying that whoever put that together in K&R2
decided that ?: belonged in this set.
The ?: operator, which is a ternary operator, belongs in the set
of operators.
You somehow concluded that ?: was being treated as a binary operator.
It very very clearly is not a binary operator. The chart in K&R2
very very clearly does not imply that it is.
(Personally I don't, as I don't consider a ?:-like feature to be an
operator,
It is an operator in C.
but even it it was, a 3-way operator is a poor fit when all
the others are 2-way.)
No, not all the others are 2-way.
Are you now saying that you think ?: *should* be a binary (2-way)
operator? (I'm not going to ask how that would work.
On 19/05/2026 03:22, Keith Thompson wrote:<snip>
Bart <bc@freeuk.com> writes:
Say I'm talking about this set: "+ - * /", binary/infix operators
(ignore that 3 of them also unary/prefix).
This same set is part of the table of 1/2/3-way 'operators' used in K&R2.
I'd remarked that K&R put the ?: 3-way operator amongst the section of
the table which is full of 2-way ops (with the 1-way ops sharing the top
two tiers) and idly speculated whether the '?' and ':' parts of '?:'
were being treated as though each was a 2-way operator.
<snip>You somehow concluded that ?: was being treated as a binary operator.
It very very clearly is not a binary operator. The chart in K&R2
very very clearly does not imply that it is.
(Personally I don't, as I don't consider a ?:-like feature to be an
operator,
It is an operator in C.
but even it it was, a 3-way operator is a poor fit when all
the others are 2-way.)
No, not all the others are 2-way.
Are you now saying that you think ?: *should* be a binary (2-way)
operator? (I'm not going to ask how that would work.
This is the question *I'm* asking! How does a 3-way operator work in
that set-up? Is it still called 'infix'?
Even though this is a poor fit for those like "[]", "()", "?:" and "(T)".
Bart <bc@freeuk.com> wrote:
On 19/05/2026 03:22, Keith Thompson wrote:<snip>
Bart <bc@freeuk.com> writes:
Say I'm talking about this set: "+ - * /", binary/infix operators<snip>
(ignore that 3 of them also unary/prefix).
This same set is part of the table of 1/2/3-way 'operators' used in K&R2.
I'd remarked that K&R put the ?: 3-way operator amongst the section of
the table which is full of 2-way ops (with the 1-way ops sharing the top
two tiers) and idly speculated whether the '?' and ':' parts of '?:'
were being treated as though each was a 2-way operator.
You somehow concluded that ?: was being treated as a binary operator.
It very very clearly is not a binary operator. The chart in K&R2
very very clearly does not imply that it is.
(Personally I don't, as I don't consider a ?:-like feature to be an
operator,
It is an operator in C.
but even it it was, a 3-way operator is a poor fit when all >>>> the others are 2-way.)
No, not all the others are 2-way.
Are you now saying that you think ?: *should* be a binary (2-way)
operator? (I'm not going to ask how that would work.
This is the question *I'm* asking! How does a 3-way operator work in
that set-up? Is it still called 'infix'?
Even though this is a poor fit for those like "[]", "()", "?:" and "(T)".
In late sixties there were concept of "operator precedence grammar"
and related parsing technology. Basicaly, I you wanted systematic
way of parsing there was operator precedence or recursive descent,
otherwise it was more or less ad hoc. In operator precedence
grammar most "interesting" things were operators of varying arity.
If you ask "how does it work?", the answer is that parsers using
that where shift-reduce parsers and priorities are used to choose
between shift and reduce actions. People also realised to
operator precedence can be used together with recursive descent,
leading to small and efficient parsers handling rich language.
Operator precedence alone puts restrictions on the language
(but there were languages specially designed to be parsed using
operator precedence), recursive descent alows more general
languages, but gets messy on constructs well handled by operator
precedence. AFAIK first C compiler used combination of operator
precedence and recursive descent, and for some time there was a
belief that correct and full BNF for C was impossible to give or
too messy. Current gramamr only appeared during ANSI process.
On 2026-05-14 13:32, Bart wrote:[End restored snippage]
...
In the case if C, it also decided that ?: belongs in this chart of /
binary/ operators. (I supposed you can consider each of ? and : as a
binary operator...)
If you read my post again, you'll find that 'this chart' most likelyThat table is preceded by the following description: "The table below summarizes the rules for precedence and associativity of all operators, including those which we have not yet discussed".
refers to my suggested chart containing those 4 groups I mentioned.
That chart contains a set of binary (and infix) operators that also
appear in K&R2. I'm saying that whoever put that together in K&R2
decided that ?: belonged in this set.
(Personally I don't, as I don't consider a ?:-like feature to be an
operator,
but even it it was, a 3-way operator is a poor fit when all
the others are 2-way.)
On 19/05/2026 03:22, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
If you read my post again, you'll find that 'this chart' most likely
refers to my suggested chart containing those 4 groups I mentioned.
That chart contains a set of binary (and infix) operators that also
appear in K&R2. I'm saying that whoever put that together in K&R2
decided that ?: belonged in this set.
The ?: operator, which is a ternary operator, belongs in the set
of operators.
Do we really want to get this pedantic and discuss the intent of every
single choice of word I've made?
Say I'm talking about this set: "+ - * /", binary/infix operators
(ignore that 3 of them also unary/prefix).
This same set is part of the table of 1/2/3-way 'operators' used in K&R2.
I'd remarked that K&R put the ?: 3-way operator amongst the section of
the table which is full of 2-way ops (with the 1-way ops sharing the
top two tiers) and idly speculated whether the '?' and ':' parts of
'?:' were being treated as though each was a 2-way operator.
This is the question *I'm* asking! How does a 3-way operator work in
that set-up? Is it still called 'infix'?
I think it's still a little messy!
This is the question *I'm* asking! How does a 3-way operator work in
that set-up?
Bart <bc@freeuk.com> writes:
...
This is the question *I'm* asking! How does a 3-way operator work in
that set-up?
It doesn't - which is why the C standard uses grammar rules rather that precedence and associativity tables to define how ?: (and all other operators) works.
Bart <bc@freeuk.com> writes:
[...]
And that's not a useful way to look at it.
I think what you're saying is that you want to have 4 separate
operator precedence tables, one each for unary, postfix, binary,
and ternary operators (or something like that). But that doesn't
work well because the language's only ternary operator, "?:",
has a precedence between "||" and the assignment operators.
Pretending that "?:" is somehow binary reminds me of Ptolemy's
epicycles, an added complication that tries to solve a problem
that's better solved by rethinking the whole structure.
[...] You're tying yourself in knots
trying to find a way to use a poor approach that is inconsistent
with the way C's expression syntax is defined.
[...]--- Synchronet 3.22a-Linux NewsLink 1.2
[...] for some time there was a belief that correct and full BNF
for C was impossible to give or too messy.
antispam@fricas.org (Waldek Hebisch) writes:
[...] for some time there was a belief that correct and full BNF
for C was impossible to give or too messy.
I find this statement hard to believe. There is nothing especially
difficult about a syntax for the C language. There is of course the well-known problem with typedef names, but that has long been
understood to be unresolvable in any context-free way (and so cannot
be dealt with in BNF). Earlier versions of C (pre-K&R) had other
syntax for some constructs, and maybe that was the issue. I'm at a
loss to understand how people could have thought a BNF for C, for
the post K&R version of the language, would be challenging or
difficult.
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
antispam@fricas.org (Waldek Hebisch) writes:
[...] for some time there was a belief that correct and full BNF
for C was impossible to give or too messy.
I find this statement hard to believe. There is nothing especially
difficult about a syntax for the C language. There is of course the
well-known problem with typedef names, but that has long been
understood to be unresolvable in any context-free way (and so cannot
be dealt with in BNF). Earlier versions of C (pre-K&R) had other
syntax for some constructs, and maybe that was the issue. I'm at a
loss to understand how people could have thought a BNF for C, for
the post K&R version of the language, would be challenging or
difficult.
I'm having trouble figuring out what you mean here. You acknowledge
that typedefs make a full BNF grammar for C impossible, and then
you say that it's not challenging or difficult.
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
antispam@fricas.org (Waldek Hebisch) writes:
[...] for some time there was a belief that correct and full BNF
for C was impossible to give or too messy.
I find this statement hard to believe. There is nothing especially
difficult about a syntax for the C language. There is of course the
well-known problem with typedef names, but that has long been
understood to be unresolvable in any context-free way (and so cannot
be dealt with in BNF). Earlier versions of C (pre-K&R) had other
syntax for some constructs, and maybe that was the issue. I'm at a
loss to understand how people could have thought a BNF for C, for
the post K&R version of the language, would be challenging or
difficult.
I'm having trouble figuring out what you mean here. You acknowledge
that typedefs make a full BNF grammar for C impossible, and then
you say that it's not challenging or difficult.
Because I think the problem with typedef names is orthogonal to
what Waldek was saying. The problem with typedef names is not
solvable in a context-free grammar, and that is just as true today
as it was 50 years ago. The syntax I am talking about is C syntax
without regard to the problem with typedef names.
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
antispam@fricas.org (Waldek Hebisch) writes:
[...] for some time there was a belief that correct and full BNF
for C was impossible to give or too messy.
I find this statement hard to believe. There is nothing especially
difficult about a syntax for the C language. There is of course the
well-known problem with typedef names, but that has long been
understood to be unresolvable in any context-free way (and so cannot
be dealt with in BNF). Earlier versions of C (pre-K&R) had other
syntax for some constructs, and maybe that was the issue. I'm at a
loss to understand how people could have thought a BNF for C, for
the post K&R version of the language, would be challenging or
difficult.
I'm having trouble figuring out what you mean here. You acknowledge
that typedefs make a full BNF grammar for C impossible, and then
you say that it's not challenging or difficult.
Because I think the problem with typedef names is orthogonal to
what Waldek was saying. The problem with typedef names is not
solvable in a context-free grammar, and that is just as true today
as it was 50 years ago. The syntax I am talking about is C syntax
without regard to the problem with typedef names.
I still don't understand your point. [...]
If you ask "how does it work?", the answer is that parsers using
that where shift-reduce parsers and priorities are used to choose
between shift and reduce actions. People also realised to
operator precedence can be used together with recursive descent,
leading to small and efficient parsers handling rich language.
Operator precedence alone puts restrictions on the language
(but there were languages specially designed to be parsed using
operator precedence), recursive descent alows more general
languages, but gets messy on constructs well handled by operator
precedence. AFAIK first C compiler used combination of operator
precedence and recursive descent, and for some time there was a
belief that correct and full BNF for C was impossible to give or
too messy. Current gramamr only appeared during ANSI process.
| Sysop: | DaiTengu |
|---|---|
| Location: | Appleton, WI |
| Users: | 1,118 |
| Nodes: | 10 (0 / 10) |
| Uptime: | 16:37:12 |
| Calls: | 14,340 |
| Calls today: | 3 |
| Files: | 186,356 |
| D/L today: |
2,558 files (803M bytes) |
| Messages: | 2,532,455 |