9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] Undefined Behaviour in C
@ 2015-11-23 10:20 Ramakrishnan Muthukrishnan
  2015-11-23 11:20 ` Vasudev Kamath
                   ` (3 more replies)
  0 siblings, 4 replies; 40+ messages in thread
From: Ramakrishnan Muthukrishnan @ 2015-11-23 10:20 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

Had been reading the SOSP paper:
<https://pdos.csail.mit.edu/papers/stack:sosp13.pdf>

and this blog post that proposes a simpler C:
<http://blog.regehr.org/archives/1180>

I wonder how Plan 9 C compiler, which is a non-ANSI compliant compiler,
treats those parts that the ANSI C standard treats as undefined.

--
  Ramakrishnan



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-23 10:20 [9fans] Undefined Behaviour in C Ramakrishnan Muthukrishnan
@ 2015-11-23 11:20 ` Vasudev Kamath
  2015-11-25 10:27   ` Alexandru Gheorghe
  2015-11-23 11:32 ` Charles Forsyth
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 40+ messages in thread
From: Vasudev Kamath @ 2015-11-23 11:20 UTC (permalink / raw)
  To: Ramakrishnan Muthukrishnan; +Cc: Fans of the OS Plan 9 from Bell Labs

Ramakrishnan Muthukrishnan <ram@rkrishnan.org> writes:

> Had been reading the SOSP paper:
> <https://pdos.csail.mit.edu/papers/stack:sosp13.pdf>
>
> and this blog post that proposes a simpler C:
> <http://blog.regehr.org/archives/1180>

I started reading the paper and its interesting. I didn't knew till date
how optimizations really worked and why they were considered harmful.

Yet to read the blog.

> I wonder how Plan 9 C compiler, which is a non-ANSI compliant compiler,
> treats those parts that the ANSI C standard treats as undefined.

No idea. But Brantley Coile might be able to answer, most of his article
he mentions compiler won't do any magic, I assume those magic are meant
for the optimizations.

Of course others from 9fans/9front might have answers but that name came
to my mind as I read some recent article where he mentioned about plan9
compilers.



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-23 10:20 [9fans] Undefined Behaviour in C Ramakrishnan Muthukrishnan
  2015-11-23 11:20 ` Vasudev Kamath
@ 2015-11-23 11:32 ` Charles Forsyth
  2015-11-23 11:37   ` Charles Forsyth
  2015-11-23 11:50 ` Brantley Coile
  2015-11-23 14:30 ` Charles Forsyth
  3 siblings, 1 reply; 40+ messages in thread
From: Charles Forsyth @ 2015-11-23 11:32 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 5869 bytes --]

There is quite a bit there to work through, but I was struck by one of the
responses to a gcc bug report:

   "you're leading to undefined behaviour - do you understand this simple
fact?
    in such cases compiler can do *anything* with your code."

I've seen similar comments before (about #pragma, I think). I don't think
it was an official response, but it prompts me to discuss
the use of "undefined".

The word "undefined" has historically been used by language definitions as
a technical term.
For instance, by Algol 68:

"1.1.4.3. Undefined
a) If something is left “undefined” or is said to be “undefined”, then this
means that it is not defined by this Report alone and that, for its
definition, information from outside this Report has to be taken into
account. {A distinction must be drawn between the yielding of an undefined
value (whereupon elaboration continues with possibly unpredictable results)
and the complete undefinedness of the further elaboration. The action to be
taken in this latter case is at the discretion of the implementer, and may
be some form of continuation (but not necessarily the same as any other
implementer’s continuation), or some form of interruption (2.1.4.3.h)
brought about by some run-time check.}
b) If some condition is “required” to be satisfied during some elaboration
then, if it is not so satisfied, the further elaboration is undefined."

For example, a computation that uses a value from store that has not
previously been initialised by the program will, at the machine level,
load and use whatever happened to be there, which is especially exciting if
it's used as a pointer or floating-point number;
there will be a similar effect in a language that does not check array
bounds if an index is out of bounds; and so on.
There are more subtle cases where machine arithmetic at one time did differ
in its handling of (say) arithmetic overflow.
Some of the cases are machine-dependent, and others are language-dependent.
Some languages will say things like "the order of evaluation of
subexpressions is undefined" to allow different implementations some
flexibility,
where other languages that emphasise absolute portability might say that
evaluation is (say) strictly left-to-right.
Others will state that dereferencing nil will necessarily produce a trap;
others will leave you with whatever result the machine
and run-time system produce when you do it.

I deliberately did not use the C standard's own definition to emphasise
that it's ancient, and nothing new with C:
Pascal's standard will have some similar concept, as does Ada.
In all cases, however, there has never been any suggestion *whatsoever*
that "undefined" allowed
completely arbitrary, capricious or even whimsical effects. It meant either
that the results might simply depend on an implementation choice
between one or other plausible interpretation of a construction, or they
reflected differences in either the machine operations or its run-time
state (in the case of referencing uninitialised storage).

I refer again to Algol 68: "this means that it is not defined by this
Report alone and that, for its definition, information from outside this
Report has to be taken into account". In the past, that outside information
might include the documentation for the compiler you're using, or the
machine definition.

No sane compiler writer would ever assume it allowed the compiler to "do
*anything" with your code".

The Plan 9 C compiler is firmly in that historical tradition: the compiler
takes advantage of flexibility in evaluation order when it seems helpful,
and tries to avoid making assumptions (ie, "optimisations") that frustrate
a programmer's explicit attempt to get a particular effect (eg
with overflow checks); the compiler doesn't do much non-local optimisation
(which is where many problems arise) above the expression level;
when handling pointers and arithmetic, it very traditionally gives you what
the machine gives you for arithmetic and references to undefined values or
out of range indices, unless the language definition (rarely) defines a
particular effect. It also eliminates several "undefined" effects
in ANSI C, for convenience or portability, notably the state of program
values after longjmp.

One of the examples in the first paper was:

    struct tun_struct *tun = ...;
    struct sock *sk = tun->sk;
    if (!tun)
        return POLLERR; /* write to address based on tun */

and the text described its handling by gcc:

"For example, when gcc first sees the dereference tun->sk, it concludes
that the pointer tun must be non-null, because the C standard states that
dereferencing a null pointer is undefined [24: §6.5.3]. Since tun is
non-null, gcc further determines that the null pointer check is unnecessary
and eliminates the check, making a privilege escalation exploit possible
that would not otherwise be."

I should say, as a compiler writer, that seems to have the reasoning back
to front, by making a perverse appeal to "undefined".
Really, in that text, it's only after the conditional test that one can
conclude
that the pointer is or is not null in the relevant branch of the if-else.
It is what we call "a compiler bug".
Apparently Hoare's "billion dollar mistake" can be made worse by misguided
automated reasoning!

On 23 November 2015 at 10:20, Ramakrishnan Muthukrishnan <ram@rkrishnan.org>
wrote:

> Had been reading the SOSP paper:
> <https://pdos.csail.mit.edu/papers/stack:sosp13.pdf>
>
> and this blog post that proposes a simpler C:
> <http://blog.regehr.org/archives/1180>
>
> I wonder how Plan 9 C compiler, which is a non-ANSI compliant compiler,
> treats those parts that the ANSI C standard treats as undefined.
>
> --
>   Ramakrishnan
>
>

[-- Attachment #2: Type: text/html, Size: 7182 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-23 11:32 ` Charles Forsyth
@ 2015-11-23 11:37   ` Charles Forsyth
  0 siblings, 0 replies; 40+ messages in thread
From: Charles Forsyth @ 2015-11-23 11:37 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 212 bytes --]

On 23 November 2015 at 11:32, Charles Forsyth <charles.forsyth@gmail.com>
wrote:

> The Plan 9 C compiler is firmly in that historical tradition


In short: http://www.terzarima.net/images/careful-now.jpg

[-- Attachment #2: Type: text/html, Size: 692 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-23 10:20 [9fans] Undefined Behaviour in C Ramakrishnan Muthukrishnan
  2015-11-23 11:20 ` Vasudev Kamath
  2015-11-23 11:32 ` Charles Forsyth
@ 2015-11-23 11:50 ` Brantley Coile
  2015-11-23 12:05   ` Charles Forsyth
  2015-11-23 12:09   ` Charles Forsyth
  2015-11-23 14:30 ` Charles Forsyth
  3 siblings, 2 replies; 40+ messages in thread
From: Brantley Coile @ 2015-11-23 11:50 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

This is an interesting issue to me because I'm becoming more and more aware of a fundamental misunderstanding of C which will make it difficult for people to write efficient code in the future. These two documents show a lack of understanding regarding the reason for undefined behavior and a confusion between undefined specification and undefined behavior. 

Efficiency is the reason for undefined specification. The objective of C was to replace assembler language without giving up the ability to write tight, efficient programs. Other languages, such as ALGOL, had defined all the behavior to great detail and as a result was very inefficient on some architectures. C avoided these inefficiencies by letting the machine do what was natural. Loading a character into an integer register is an example. It is undefined in C whether or not it sign extends or not. Some machines do it one way, some another. To force the language to one behavior requires more code on some architectures. 

Leaving these aspects to the local machine was one of the places where Dennis' genius shows through. And it's why they could write and operating system in C and have it run quite well on a tiny minicomputer while Multics with its PL/1 language was dog slow on a huge expensive mainframe. (Okay, it's only one reason.)

Ken's compiler does the right amount of optimizations, limiting them mostly to what the programmer can't fix. The idea that a C compiler can be smarter than a sloppy programmer is causing compilers to be unusable for what I do. These bloated compilers  can never be idiot proof because idiots are so ingenious. The beauty of C is that one can write a simple compiler and create very fast code by being a good programmer. Give me smart programmers and simple compilers and not dumber programmers and idiot savant, and bloat, compilers. 

So C, as it is now defined, is in no need of fixing.

The MIT paper has a confusion between the undefined specification and undefined behavior. If you load a character into an integer, sign behavior is unspecified. But how many people program 8086 large model code any more, the reason for the comment into the standard? I

'm not an expert on gcc, in fact I know more that I really want to about it. But, if it tosses code like buf + len < size, because it might be wrong on some other architecture, it's broke. 

To write fast code one need a simple notation and a simple predictable compiler. Ken's C compiler fits this requirement to a tee. 

Sent from my iPad

> On Nov 23, 2015, at 5:20 AM, Ramakrishnan Muthukrishnan <ram@rkrishnan.org> wrote:
> 
> Had been reading the SOSP paper:
> <https://pdos.csail.mit.edu/papers/stack:sosp13.pdf>
> 
> and this blog post that proposes a simpler C:
> <http://blog.regehr.org/archives/1180>
> 
> I wonder how Plan 9 C compiler, which is a non-ANSI compliant compiler,
> treats those parts that the ANSI C standard treats as undefined.
> 
> -- 
>  Ramakrishnan
> 



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-23 11:50 ` Brantley Coile
@ 2015-11-23 12:05   ` Charles Forsyth
  2015-11-23 12:17     ` Brantley Coile
  2015-11-23 12:09   ` Charles Forsyth
  1 sibling, 1 reply; 40+ messages in thread
From: Charles Forsyth @ 2015-11-23 12:05 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 663 bytes --]

On 23 November 2015 at 11:50, Brantley Coile <brantleycoile@me.com> wrote:

> It is undefined in C whether or not it sign extends or not. Some machines
> do it one way, some another. To force the language to one behavior requires
> more code on some architectures.
>

Ironically for its use as an example, that's another case where Plan 9 C
defines the effect: char is always signed, unsigned char is the only
unsigned form, on all targets, just like int/unsigned int, short/unsigned
short. The abbreviation "uchar" makes it relatively painless.
It's just a pity that string literals must be char*, not uchar*, and all
the str* functions take char*.

[-- Attachment #2: Type: text/html, Size: 1045 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-23 11:50 ` Brantley Coile
  2015-11-23 12:05   ` Charles Forsyth
@ 2015-11-23 12:09   ` Charles Forsyth
  1 sibling, 0 replies; 40+ messages in thread
From: Charles Forsyth @ 2015-11-23 12:09 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 576 bytes --]

On 23 November 2015 at 11:50, Brantley Coile <brantleycoile@me.com> wrote:

> These bloated compilers  can never be idiot proof because idiots are so
> ingenious.


One thing that struck me about that earlier gcc example, where the test for
"tun" is eliminated because of bad compiler reasoning,
is that the same compiler whines interminably until you put parentheses
round nearly everything. Ok, ok, some of the priorities in
C are weird for historical reasons, but it's very tedious wading through
parentheses in cases where the priority is indeed conventional.

[-- Attachment #2: Type: text/html, Size: 929 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-23 12:05   ` Charles Forsyth
@ 2015-11-23 12:17     ` Brantley Coile
  2015-11-23 12:40       ` Charles Forsyth
  0 siblings, 1 reply; 40+ messages in thread
From: Brantley Coile @ 2015-11-23 12:17 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 976 bytes --]

I've lived with the old definition so long that I didn't notice Plan 9's definition, which is not a problem on today's architectures because there are two equally efficient instructions to choose from. 

Sent from my iPad

> On Nov 23, 2015, at 7:05 AM, Charles Forsyth <charles.forsyth@gmail.com> wrote:
> 
> 
>> On 23 November 2015 at 11:50, Brantley Coile <brantleycoile@me.com> wrote:
>> It is undefined in C whether or not it sign extends or not. Some machines do it one way, some another. To force the language to one behavior requires more code on some architectures.
> 
> Ironically for its use as an example, that's another case where Plan 9 C defines the effect: char is always signed, unsigned char is the only unsigned form, on all targets, just like int/unsigned int, short/unsigned short. The abbreviation "uchar" makes it relatively painless.
> It's just a pity that string literals must be char*, not uchar*, and all the str* functions take char*.

[-- Attachment #2: Type: text/html, Size: 1590 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-23 12:17     ` Brantley Coile
@ 2015-11-23 12:40       ` Charles Forsyth
  0 siblings, 0 replies; 40+ messages in thread
From: Charles Forsyth @ 2015-11-23 12:40 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 1031 bytes --]

On 23 November 2015 at 12:17, Brantley Coile <brantleycoile@me.com> wrote:

> I've lived with the old definition so long that I didn't notice Plan 9's
> definition, which is not a problem on today's architectures because there
> are two equally efficient instructions to choose from.


There are a few things in C's definition where things aren't specified as
portably as they might now be,
because they just turned out to be different on different platforms,
especially once there were several compiler implementations.
An early example of the former is "bit fields", which are such a mess that
Plan 9 code never uses them. An example of the latter was the
long argument between "value preserving" and "unsigned preserving" for
choosing the type when unsigned values met signed ones.
"Unsigned preserving" is trivial, and at least easy to understand. ANSI
went for "value preserving" (even though it doesn't really
preserve values, except in the sense of formaldehyde) and the rules are
surprisingly elaborate.

[-- Attachment #2: Type: text/html, Size: 1533 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-23 10:20 [9fans] Undefined Behaviour in C Ramakrishnan Muthukrishnan
                   ` (2 preceding siblings ...)
  2015-11-23 11:50 ` Brantley Coile
@ 2015-11-23 14:30 ` Charles Forsyth
  3 siblings, 0 replies; 40+ messages in thread
From: Charles Forsyth @ 2015-11-23 14:30 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 1513 bytes --]

On 23 November 2015 at 10:20, Ramakrishnan Muthukrishnan <ram@rkrishnan.org>
wrote:

> Had been reading the SOSP paper:
> <https://pdos.csail.mit.edu/papers/stack:sosp13.pdf>
>

As an example of how tricky it can be, one of their examples is

const uint8_t *data = /* buffer head */;
const uint8_t *data_end = /* buffer tail */;
int size = bytestream_get_be16(&data);
if (data + size >= data_end || data + size < data)
   return -1;

They say "A correct fix is to replace data + x >= data_end || data + x <
data with x >= data_end − data, which is simpler and also avoids invoking
undefined behavior; one should also add the check x < 0 if x can be
negative."

Unfortunately, that replacement is itself well-defined only if data and
data_end "point to elements of the same array object, or one past the last
element of the array object" (and there's an implementation-dependent
option for the interpretation of "one past" when ensuring the address can
be represented). It looks from the comments as though that might be true in
this particular case (or it's intended to be understood), but if not,
avoiding the compiler's "optimisation" that messes up one form of undefined
behaviour will lead you to write code that has different undefined states.

Generally, an optimising compiler for a systems language, especially one
 in which pointer values can be manipulated explicitly,
needs to be sure of its ground when second-guessing the effect of a given
statement or expression.

[-- Attachment #2: Type: text/html, Size: 2518 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-23 11:20 ` Vasudev Kamath
@ 2015-11-25 10:27   ` Alexandru Gheorghe
  2015-11-25 10:43     ` Brantley Coile
  0 siblings, 1 reply; 40+ messages in thread
From: Alexandru Gheorghe @ 2015-11-25 10:27 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 1855 bytes --]

On 11/23/2015 01:20 PM, Vasudev Kamath wrote:
> Ramakrishnan Muthukrishnan <ram@rkrishnan.org> writes:
>
>> Had been reading the SOSP paper:
>> <https://pdos.csail.mit.edu/papers/stack:sosp13.pdf>
>>
>> and this blog post that proposes a simpler C:
>> <http://blog.regehr.org/archives/1180>
> I started reading the paper and its interesting. I didn't knew till date
> how optimizations really worked and why they were considered harmful.

They can be quite harmful, the dereference example of *tun->sk* is a
popular example that dates from 2009 regarding the Linux Kernel being
exploited by Spender (Brad Spengler): https://lwn.net/Articles/342330/

    "a NULL pointer was dereferenced before being checked, the check was
    optimized out by the compiler, and the code used the NULL pointer in
    a way which allowed the attacker to take over the system"


Funny because Spengler did try many times to introduce better security
in the Linux Kernel (see his set of patches in collaboration with the
PaX Team: GRSEC) but was refused many times by the community and Linus
in particular due to performance penalties (among other "opinions").
Which again opens the question where exactly is the undefined behavior
problem? Resides on the programmer or on the compiler (and its
programmers)? And how do you deal with the performance side? Because
clearly, if you introduce more security then you will start having
penalties on it; I guess the question is how much are you willing to let
go in preference of more security and stable systems?

It's a very interesting paper, I only read 7 pages but will soon finish
it and go ahead with the references (probably it links the example I
wrote in the beginning of this e-mail).

Thanks for sharing.

--
; Alexandru Gheorghe
;
;       aGlobal
; <alghe.global gmail com>


[-- Attachment #2: Type: text/html, Size: 2826 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-25 10:27   ` Alexandru Gheorghe
@ 2015-11-25 10:43     ` Brantley Coile
  2015-11-25 10:53       ` Brantley Coile
  2015-11-25 12:59       ` Charles Forsyth
  0 siblings, 2 replies; 40+ messages in thread
From: Brantley Coile @ 2015-11-25 10:43 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 2054 bytes --]

Just curious, will Linux not panic when the kernel deterrences a nil pointer?

Sent from my iPad

> On Nov 25, 2015, at 5:27 AM, Alexandru Gheorghe <alghe.global@gmail.com> wrote:
> 
>> On 11/23/2015 01:20 PM, Vasudev Kamath wrote:
>> Ramakrishnan Muthukrishnan <ram@rkrishnan.org> writes:
>> 
>>> Had been reading the SOSP paper:
>>> <https://pdos.csail.mit.edu/papers/stack:sosp13.pdf>
>>> 
>>> and this blog post that proposes a simpler C:
>>> <http://blog.regehr.org/archives/1180>
>> I started reading the paper and its interesting. I didn't knew till date
>> how optimizations really worked and why they were considered harmful.
> 
> They can be quite harmful, the dereference example of tun->sk is a popular example that dates from 2009 regarding the Linux Kernel being exploited by Spender (Brad Spengler): https://lwn.net/Articles/342330/
> "a NULL pointer was dereferenced before being checked, the check was optimized out by the compiler, and the code used the NULL pointer in a way which allowed the attacker to take over the system"
> 
> Funny because Spengler did try many times to introduce better security in the Linux Kernel (see his set of patches in collaboration with the PaX Team: GRSEC) but was refused many times by the community and Linus in particular due to performance penalties (among other "opinions"). Which again opens the question where exactly is the undefined behavior problem? Resides on the programmer or on the compiler (and its programmers)? And how do you deal with the performance side? Because clearly, if you introduce more security then you will start having penalties on it; I guess the question is how much are you willing to let go in preference of more security and stable systems?
> 
> It's a very interesting paper, I only read 7 pages but will soon finish it and go ahead with the references (probably it links the example I wrote in the beginning of this e-mail).
> 
> Thanks for sharing.
> 
> -- 
> ; Alexandru Gheorghe
> ;
> ;       aGlobal
> ; <alghe.global gmail com>

[-- Attachment #2: Type: text/html, Size: 3167 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-25 10:43     ` Brantley Coile
@ 2015-11-25 10:53       ` Brantley Coile
  2015-11-25 12:59       ` Charles Forsyth
  1 sibling, 0 replies; 40+ messages in thread
From: Brantley Coile @ 2015-11-25 10:53 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 2411 bytes --]

My apologies for my iPad's spelling correction and my lack of proof reading. Proof reading is impotent. :)

I meant "dereference". It's an easy matter to have page zero invalid in both user space and kernel space. 

Sent from my iPad

> On Nov 25, 2015, at 5:43 AM, Brantley Coile <brantleycoile@me.com> wrote:
> 
> Just curious, will Linux not panic when the kernel deterrences a nil pointer?
> 
> Sent from my iPad
> 
>> On Nov 25, 2015, at 5:27 AM, Alexandru Gheorghe <alghe.global@gmail.com> wrote:
>> 
>>> On 11/23/2015 01:20 PM, Vasudev Kamath wrote:
>>> Ramakrishnan Muthukrishnan <ram@rkrishnan.org> writes:
>>> 
>>>> Had been reading the SOSP paper:
>>>> <https://pdos.csail.mit.edu/papers/stack:sosp13.pdf>
>>>> 
>>>> and this blog post that proposes a simpler C:
>>>> <http://blog.regehr.org/archives/1180>
>>> I started reading the paper and its interesting. I didn't knew till date
>>> how optimizations really worked and why they were considered harmful.
>> 
>> They can be quite harmful, the dereference example of tun->sk is a popular example that dates from 2009 regarding the Linux Kernel being exploited by Spender (Brad Spengler): https://lwn.net/Articles/342330/
>> "a NULL pointer was dereferenced before being checked, the check was optimized out by the compiler, and the code used the NULL pointer in a way which allowed the attacker to take over the system"
>> 
>> Funny because Spengler did try many times to introduce better security in the Linux Kernel (see his set of patches in collaboration with the PaX Team: GRSEC) but was refused many times by the community and Linus in particular due to performance penalties (among other "opinions"). Which again opens the question where exactly is the undefined behavior problem? Resides on the programmer or on the compiler (and its programmers)? And how do you deal with the performance side? Because clearly, if you introduce more security then you will start having penalties on it; I guess the question is how much are you willing to let go in preference of more security and stable systems?
>> 
>> It's a very interesting paper, I only read 7 pages but will soon finish it and go ahead with the references (probably it links the example I wrote in the beginning of this e-mail).
>> 
>> Thanks for sharing.
>> 
>> -- 
>> ; Alexandru Gheorghe
>> ;
>> ;       aGlobal
>> ; <alghe.global gmail com>

[-- Attachment #2: Type: text/html, Size: 3753 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-25 10:43     ` Brantley Coile
  2015-11-25 10:53       ` Brantley Coile
@ 2015-11-25 12:59       ` Charles Forsyth
  2015-11-25 13:48         ` erik quanstrom
  1 sibling, 1 reply; 40+ messages in thread
From: Charles Forsyth @ 2015-11-25 12:59 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 2569 bytes --]

The link to the lwn.net article explains that using mmap the naughty
application mapped a page to virtual 0, which was then available in kernel
mode in that process, and all they'd need to do is put their own "socket"
structure at 0 + offsetof(struct tun_struct, sk).

On 25 November 2015 at 10:43, Brantley Coile <brantleycoile@me.com> wrote:

> Just curious, will Linux not panic when the kernel deterrences a nil
> pointer?
>
> Sent from my iPad
>
> On Nov 25, 2015, at 5:27 AM, Alexandru Gheorghe <alghe.global@gmail.com>
> wrote:
>
> On 11/23/2015 01:20 PM, Vasudev Kamath wrote:
>
> Ramakrishnan Muthukrishnan <ram@rkrishnan.org> <ram@rkrishnan.org> writes:
>
>
> Had been reading the SOSP paper:<https://pdos.csail.mit.edu/papers/stack:sosp13.pdf> <https://pdos.csail.mit.edu/papers/stack:sosp13.pdf>
>
> and this blog post that proposes a simpler C:<http://blog.regehr.org/archives/1180> <http://blog.regehr.org/archives/1180>
>
> I started reading the paper and its interesting. I didn't knew till date
> how optimizations really worked and why they were considered harmful.
>
>
> They can be quite harmful, the dereference example of *tun->sk* is a
> popular example that dates from 2009 regarding the Linux Kernel being
> exploited by Spender (Brad Spengler): https://lwn.net/Articles/342330/
>
> "a NULL pointer was dereferenced before being checked, the check was
> optimized out by the compiler, and the code used the NULL pointer in a way
> which allowed the attacker to take over the system"
>
>
> Funny because Spengler did try many times to introduce better security in
> the Linux Kernel (see his set of patches in collaboration with the PaX
> Team: GRSEC) but was refused many times by the community and Linus in
> particular due to performance penalties (among other "opinions"). Which
> again opens the question where exactly is the undefined behavior problem?
> Resides on the programmer or on the compiler (and its programmers)? And how
> do you deal with the performance side? Because clearly, if you introduce
> more security then you will start having penalties on it; I guess the
> question is how much are you willing to let go in preference of more
> security and stable systems?
>
> It's a very interesting paper, I only read 7 pages but will soon finish it
> and go ahead with the references (probably it links the example I wrote in
> the beginning of this e-mail).
>
> Thanks for sharing.
>
> --
> ; Alexandru Gheorghe
> ;
> ;       aGlobal
> ; <alghe.global gmail com>
>
>

[-- Attachment #2: Type: text/html, Size: 3624 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-25 12:59       ` Charles Forsyth
@ 2015-11-25 13:48         ` erik quanstrom
  2015-11-25 14:25           ` Brantley Coile
  0 siblings, 1 reply; 40+ messages in thread
From: erik quanstrom @ 2015-11-25 13:48 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/html, Size: 3800 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-25 13:48         ` erik quanstrom
@ 2015-11-25 14:25           ` Brantley Coile
  2015-11-25 14:31             ` Brantley Coile
  2015-11-25 16:03             ` plannine
  0 siblings, 2 replies; 40+ messages in thread
From: Brantley Coile @ 2015-11-25 14:25 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

Insert various complaints about unwise complexities and their unindented consequences here. 

Just my personal taste, but I didn’t like shared libraries when the Unix world in the 1980’s were copying Window’s DLLs, and could never see the reason for linking the file system and paging system. Most thought it was neat that one could leverage the paging code to just mmap a file into their address space and just read it. At the time Dennis observed that storage was still larger than the address space of machines. This didn’t dissuade people to do that anyway, forever making the file system block size linked to the paging system on Unix-like systems.

Interesting that it is still causing problems.

Of course Plan 9 has neither shared libraries nor mmap. That’s a good thing.


> On Nov 25, 2015, at 8:48 AM, erik quanstrom <quanstro@quanstro.net> wrote:
> 
> so to answer bwc's question, no.  not always. 
> 
> On Nov 25, 2015 4:59 AM, Charles Forsyth <charles.forsyth@gmail.com> wrote:
> The link to the lwn.net article explains that using mmap the naughty application mapped a page to virtual 0, which was then available in kernel mode in that process, and all they'd need to do is put their own "socket" structure at 0 + offsetof(struct tun_struct, sk).
> 
> On 25 November 2015 at 10:43, Brantley Coile <brantleycoile@me.com> wrote:
> Just curious, will Linux not panic when the kernel deterrences a nil pointer?
> 
> Sent from my iPad
> 
> On Nov 25, 2015, at 5:27 AM, Alexandru Gheorghe <alghe.global@gmail.com> wrote:
> 
> On 11/23/2015 01:20 PM, Vasudev Kamath wrote:
> Ramakrishnan Muthukrishnan <ram@rkrishnan.org>
>  writes:
> 
> 
> Had been reading the SOSP paper:
> 
> <https://pdos.csail.mit.edu/papers/stack:sosp13.pdf>
> 
> 
> and this blog post that proposes a simpler C:
> 
> <http://blog.regehr.org/archives/1180>
> I started reading the paper and its interesting. I didn't knew till date
> how optimizations really worked and why they were considered harmful.
> 
> 
> They can be quite harmful, the dereference example of tun->sk is a popular example that dates from 2009 regarding the Linux Kernel being exploited by Spender (Brad Spengler): https://lwn.net/Articles/342330/
> "a NULL pointer was dereferenced before being checked, the check was optimized out by the compiler, and the code used the NULL pointer in a way which allowed the attacker to take over the system"
> 
> Funny because Spengler did try many times to introduce better security in the Linux Kernel (see his set of patches in collaboration with the PaX Team: GRSEC) but was refused many times by the community and Linus in particular due to performance penalties (among other "opinions"). Which again opens the question where exactly is the undefined behavior problem? Resides on the programmer or on the compiler (and its programmers)? And how do you deal with the performance side? Because clearly, if you introduce more security then you will start having penalties on it; I guess the question is how much are you willing to let go in preference of more security and stable systems?
> 
> It's a very interesting paper, I only read 7 pages but will soon finish it and go ahead with the references (probably it links the example I wrote in the beginning of this e-mail).
> 
> Thanks for sharing.
> 
> -- 
> ; Alexandru Gheorghe
> ;
> ;       aGlobal
> ; <alghe.global gmail com>
> 
> 




^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-25 14:25           ` Brantley Coile
@ 2015-11-25 14:31             ` Brantley Coile
  2015-11-25 16:03             ` plannine
  1 sibling, 0 replies; 40+ messages in thread
From: Brantley Coile @ 2015-11-25 14:31 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

Dang it! I basically suck at proof reading! unintended consequences!

> On Nov 25, 2015, at 9:25 AM, Brantley Coile <brantleycoile@me.com> wrote:
> 
> Insert various complaints about unwise complexities and their unindented consequences here. 




^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-25 14:25           ` Brantley Coile
  2015-11-25 14:31             ` Brantley Coile
@ 2015-11-25 16:03             ` plannine
  2015-11-25 17:13               ` Ryan Gonzalez
  2015-11-25 19:19               ` Steffen Nurpmeso
  1 sibling, 2 replies; 40+ messages in thread
From: plannine @ 2015-11-25 16:03 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
> unindented consequences

Is that a class of Python bugs or an awesome name for a Nerdcore band?



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-25 16:03             ` plannine
@ 2015-11-25 17:13               ` Ryan Gonzalez
  2015-11-25 18:41                 ` Brantley Coile
  2015-11-25 19:19               ` Steffen Nurpmeso
  1 sibling, 1 reply; 40+ messages in thread
From: Ryan Gonzalez @ 2015-11-25 17:13 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 7693 bytes --]

Neither! It's what happens when you run sed 's/^\s*//' on your whole code
base, yielding results like (from cmd/yacc.c):


void
setup(int argc, char *argv[])
{
long c, t;
int i, j, fd, lev, ty, ytab, *p;
int vflag, dflag, stem;
char actnm[8], *stemc, *s, dirbuf[128];
Biobuf *fout;

ytab = 0;
vflag = 0;
dflag = 0;
stem = 0;
stemc = "y";
foutput = 0;
fdefine = 0;
fdebug = 0;
ARGBEGIN{
case 'v':
case 'V':
vflag++;
break;
case 'D':
yydebug = ARGF();
break;
case 'a':
yyarg = 1;
break;
case 'd':
dflag++;
break;
case 'l':
yyline = 0;
break;
case 'o':
ytab++;
ytabc = ARGF();
break;
case 's':
stem++;
stemc = ARGF();
break;
case 'S':
parser = PARSERS;
break;
default:
error("illegal option: %c", ARGC());
}ARGEND
openup(stemc, dflag, vflag, ytab, ytabc);
fout = dflag?fdefine:ftable;
if(yyarg){
Bprint(ftable, "#define\tYYARG\t1\n\n");
}
if((fd = mkstemp(ttempname)) >= 0){
tempname = ttempname;
ftemp = Bfdopen(fd, OWRITE);
}
if((fd = mkstemp(tactname)) >= 0){
actname = tactname;
faction = Bfdopen(fd, OWRITE);
}
if(ftemp == 0 || faction == 0)
error("cannot open temp file");
if(argc < 1)
error("no input file");
infile = argv[0];
if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
i = strlen(infile)+1+strlen(dirbuf)+1+10;
s = malloc(i);
if(s != nil){
snprint(s, i, "%s/%s", dirbuf, infile);
cleanname(s);
infile = s;
}
}
finput = Bopen(infile, OREAD);
if(finput == 0)
error("cannot open '%s'", argv[0]);
cnamp = cnames;

defin(0, "$end");
extval = PRIVATE; /* tokens start in unicode 'private use' */
defin(0, "error");
defin(1, "$accept");
defin(0, "$unk");
mem = mem0;
i = 0;

for(t = gettok(); t != MARK && t != ENDFILE;)
switch(t) {
case ';':
t = gettok();
break;

case START:
if(gettok() != IDENTIFIER)
error("bad %%start construction");
start = chfind(1, tokname);
t = gettok();
continue;

case TYPEDEF:
if(gettok() != TYPENAME)
error("bad syntax in %%type");
ty = numbval;
for(;;) {
t = gettok();
switch(t) {
case IDENTIFIER:
if((t=chfind(1, tokname)) < NTBASE) {
j = TYPE(toklev[t]);
if(j != 0 && j != ty)
error("type redeclaration of token %s",
tokset[t].name);
else
SETTYPE(toklev[t], ty);
} else {
j = nontrst[t-NTBASE].value;
if(j != 0 && j != ty)
error("type redeclaration of nonterminal %s",
nontrst[t-NTBASE].name );
else
nontrst[t-NTBASE].value = ty;
}
case ',':
continue;
case ';':
t = gettok();
default:
break;
}
break;
}
continue;

case UNION:
/* copy the union declaration to the output */
cpyunion();
t = gettok();
continue;

case LEFT:
case BINARY:
case RIGHT:
i++;

case TERM:
/* nonzero means new prec. and assoc. */
lev = t-TERM;
ty = 0;

/* get identifiers so defined */
t = gettok();

/* there is a type defined */
if(t == TYPENAME) {
ty = numbval;
t = gettok();
}
for(;;) {
switch(t) {
case ',':
t = gettok();
continue;

case ';':
break;

case IDENTIFIER:
j = chfind(0, tokname);
if(j >= NTBASE)
error("%s defined earlier as nonterminal", tokname);
if(lev) {
if(ASSOC(toklev[j]))
error("redeclaration of precedence of %s", tokname);
SETASC(toklev[j], lev);
SETPLEV(toklev[j], i);
}
if(ty) {
if(TYPE(toklev[j]))
error("redeclaration of type of %s", tokname);
SETTYPE(toklev[j],ty);
}
t = gettok();
if(t == NUMBER) {
tokset[j].value = numbval;
if(j < ndefout && j > 3)
error("please define type number of %s earlier",
tokset[j].name);
t = gettok();
}
continue;
}
break;
}
continue;

case LCURLY:
defout(0);
cpycode();
t = gettok();
continue;

default:
error("syntax error");
}
if(t == ENDFILE)
error("unexpected EOF before %%");

/* t is MARK */
if(!yyarg)
Bprint(ftable, "extern int yyerrflag;\n");
Bprint(ftable, "#ifndef YYMAXDEPTH\n");
Bprint(ftable, "#define YYMAXDEPTH 150\n");
Bprint(ftable, "#endif\n" );
if(!ntypes) {
Bprint(ftable, "#ifndef YYSTYPE\n");
Bprint(ftable, "#define YYSTYPE int\n");
Bprint(ftable, "#endif\n");
}
if(!yyarg){
Bprint(ftable, "YYSTYPE yylval;\n");
Bprint(ftable, "YYSTYPE yyval;\n");
}else{
if(dflag)
Bprint(ftable, "#include \"%s.%s\"\n\n", stemc, FILED);
Bprint(fout, "struct Yyarg {\n");
Bprint(fout, "\tint\tyynerrs;\n");
Bprint(fout, "\tint\tyyerrflag;\n");
Bprint(fout, "\tvoid*\targ;\n");
Bprint(fout, "\tYYSTYPE\tyyval;\n");
Bprint(fout, "\tYYSTYPE\tyylval;\n");
Bprint(fout, "};\n\n");
}
prdptr[0] = mem;

/* added production */
*mem++ = NTBASE;

/* if start is 0, we will overwrite with the lhs of the first rule */
*mem++ = start;
*mem++ = 1;
*mem++ = 0;
prdptr[1] = mem;
while((t=gettok()) == LCURLY)
cpycode();
if(t != IDENTCOLON)
error("bad syntax on first rule");

if(!start)
prdptr[0][1] = chfind(1, tokname);

/* read rules */
while(t != MARK && t != ENDFILE) {
/* process a rule */
rlines[nprod] = lineno;
if(t == '|')
*mem++ = *prdptr[nprod-1];
else
if(t == IDENTCOLON) {
*mem = chfind(1, tokname);
if(*mem < NTBASE)
error("token illegal on LHS of grammar rule");
mem++;
} else
error("illegal rule: missing semicolon or | ?");
/* read rule body */
t = gettok();

more_rule:
while(t == IDENTIFIER) {
*mem = chfind(1, tokname);
if(*mem < NTBASE)
levprd[nprod] = toklev[*mem];
mem++;
t = gettok();
}
if(t == PREC) {
if(gettok() != IDENTIFIER)
error("illegal %%prec syntax");
j = chfind(2, tokname);
if(j >= NTBASE)
error("nonterminal %s illegal after %%prec",
nontrst[j-NTBASE].name);
levprd[nprod] = toklev[j];
t = gettok();
}
if(t == '=') {
levprd[nprod] |= ACTFLAG;
Bprint(faction, "\ncase %d:", nprod);
cpyact(mem-prdptr[nprod]-1);
Bprint(faction, " break;");
if((t=gettok()) == IDENTIFIER) {

/* action within rule... */
sprint(actnm, "$$%d", nprod);

/* make it a nonterminal */
j = chfind(1, actnm);

/*
* the current rule will become rule number nprod+1
* move the contents down, and make room for the null
*/
for(p = mem; p >= prdptr[nprod]; --p)
p[2] = *p;
mem += 2;

/* enter null production for action */
p = prdptr[nprod];
*p++ = j;
*p++ = -nprod;

/* update the production information */
levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
levprd[nprod] = ACTFLAG;
if(++nprod >= NPROD)
error("more than %d rules", NPROD);
prdptr[nprod] = p;

/* make the action appear in the original rule */
*mem++ = j;

/* get some more of the rule */
goto more_rule;
}
}

while(t == ';')
t = gettok();
*mem++ = -nprod;

/* check that default action is reasonable */
if(ntypes && !(levprd[nprod]&ACTFLAG) &&
nontrst[*prdptr[nprod]-NTBASE].value) {

/* no explicit action, LHS has value */
int tempty;

tempty = prdptr[nprod][1];
if(tempty < 0)
error("must return a value, since LHS has a type");
else
if(tempty >= NTBASE)
tempty = nontrst[tempty-NTBASE].value;
else
tempty = TYPE(toklev[tempty]);
if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
error("default action causes potential type clash");
}
nprod++;
if(nprod >= NPROD)
error("more than %d rules", NPROD);
prdptr[nprod] = mem;
levprd[nprod] = 0;
}

/* end of all rules */
defout(1);

finact();
if(t == MARK) {
Bprint(ftable, "\n");
if(yyline)
Bprint(ftable, "#line\t%d\t\"%s\"\n", lineno, infile);
while((c=Bgetrune(finput)) != Beof)
Bputrune(ftable, c);
}
Bterm(finput);
}


On Wed, Nov 25, 2015 at 10:03 AM, <plannine@sigint.cs.purdue.edu> wrote:

> On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
> > unindented consequences
>
> Is that a class of Python bugs or an awesome name for a Nerdcore band?
>
>


-- 
Ryan
[ERROR]: Your autotools build scripts are 200 lines longer than your
program. Something’s wrong.
http://kirbyfan64.github.io/

[-- Attachment #2: Type: text/html, Size: 13177 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-25 17:13               ` Ryan Gonzalez
@ 2015-11-25 18:41                 ` Brantley Coile
  2015-11-26  2:04                   ` Prof Brucee
  0 siblings, 1 reply; 40+ messages in thread
From: Brantley Coile @ 2015-11-25 18:41 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 8627 bytes --]

Align it to column 7 and it looks like all the code I saw when I started. 

iPhone email

> On Nov 25, 2015, at 12:13 PM, Ryan Gonzalez <rymg19@gmail.com> wrote:
> 
> Neither! It's what happens when you run sed 's/^\s*//' on your whole code base, yielding results like (from cmd/yacc.c):
> 
> 
> void
> setup(int argc, char *argv[])
> {
> long c, t;
> int i, j, fd, lev, ty, ytab, *p;
> int vflag, dflag, stem;
> char actnm[8], *stemc, *s, dirbuf[128];
> Biobuf *fout;
> 
> ytab = 0;
> vflag = 0;
> dflag = 0;
> stem = 0;
> stemc = "y";
> foutput = 0;
> fdefine = 0;
> fdebug = 0;
> ARGBEGIN{
> case 'v':
> case 'V':
> vflag++;
> break;
> case 'D':
> yydebug = ARGF();
> break;
> case 'a':
> yyarg = 1;
> break;
> case 'd':
> dflag++;
> break;
> case 'l':
> yyline = 0;
> break;
> case 'o':
> ytab++;
> ytabc = ARGF();
> break;
> case 's':
> stem++;
> stemc = ARGF();
> break;
> case 'S':
> parser = PARSERS;
> break;
> default:
> error("illegal option: %c", ARGC());
> }ARGEND
> openup(stemc, dflag, vflag, ytab, ytabc);
> fout = dflag?fdefine:ftable;
> if(yyarg){
> Bprint(ftable, "#define\tYYARG\t1\n\n");
> }
> if((fd = mkstemp(ttempname)) >= 0){
> tempname = ttempname;
> ftemp = Bfdopen(fd, OWRITE);
> }
> if((fd = mkstemp(tactname)) >= 0){
> actname = tactname;
> faction = Bfdopen(fd, OWRITE);
> }
> if(ftemp == 0 || faction == 0)
> error("cannot open temp file");
> if(argc < 1)
> error("no input file");
> infile = argv[0];
> if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
> i = strlen(infile)+1+strlen(dirbuf)+1+10;
> s = malloc(i);
> if(s != nil){
> snprint(s, i, "%s/%s", dirbuf, infile);
> cleanname(s);
> infile = s;
> }
> }
> finput = Bopen(infile, OREAD);
> if(finput == 0)
> error("cannot open '%s'", argv[0]);
> cnamp = cnames;
> 
> defin(0, "$end");
> extval = PRIVATE;	/* tokens start in unicode 'private use' */
> defin(0, "error");
> defin(1, "$accept");
> defin(0, "$unk");
> mem = mem0;
> i = 0;
> 
> for(t = gettok(); t != MARK && t != ENDFILE;)
> switch(t) {
> case ';':
> t = gettok();
> break;
> 
> case START:
> if(gettok() != IDENTIFIER)
> error("bad %%start construction");
> start = chfind(1, tokname);
> t = gettok();
> continue;
> 
> case TYPEDEF:
> if(gettok() != TYPENAME)
> error("bad syntax in %%type");
> ty = numbval;
> for(;;) {
> t = gettok();
> switch(t) {
> case IDENTIFIER:
> if((t=chfind(1, tokname)) < NTBASE) {
> j = TYPE(toklev[t]);
> if(j != 0 && j != ty)
> error("type redeclaration of token %s",
> tokset[t].name);
> else
> SETTYPE(toklev[t], ty);
> } else {
> j = nontrst[t-NTBASE].value;
> if(j != 0 && j != ty)
> error("type redeclaration of nonterminal %s",
> nontrst[t-NTBASE].name );
> else
> nontrst[t-NTBASE].value = ty;
> }
> case ',':
> continue;
> case ';':
> t = gettok();
> default:
> break;
> }
> break;
> }
> continue;
> 
> case UNION:
> /* copy the union declaration to the output */
> cpyunion();
> t = gettok();
> continue;
> 
> case LEFT:
> case BINARY:
> case RIGHT:
> i++;
> 
> case TERM:
> /* nonzero means new prec. and assoc. */
> lev = t-TERM;
> ty = 0;
> 
> /* get identifiers so defined */
> t = gettok();
> 
> /* there is a type defined */
> if(t == TYPENAME) {
> ty = numbval;
> t = gettok();
> }
> for(;;) {
> switch(t) {
> case ',':
> t = gettok();
> continue;
> 
> case ';':
> break;
> 
> case IDENTIFIER:
> j = chfind(0, tokname);
> if(j >= NTBASE)
> error("%s defined earlier as nonterminal", tokname);
> if(lev) {
> if(ASSOC(toklev[j]))
> error("redeclaration of precedence of %s", tokname);
> SETASC(toklev[j], lev);
> SETPLEV(toklev[j], i);
> }
> if(ty) {
> if(TYPE(toklev[j]))
> error("redeclaration of type of %s", tokname);
> SETTYPE(toklev[j],ty);
> }
> t = gettok();
> if(t == NUMBER) {
> tokset[j].value = numbval;
> if(j < ndefout && j > 3)
> error("please define type number of %s earlier",
> tokset[j].name);
> t = gettok();
> }
> continue;
> }
> break;
> }
> continue;
> 
> case LCURLY:
> defout(0);
> cpycode();
> t = gettok();
> continue;
> 
> default:
> error("syntax error");
> }
> if(t == ENDFILE)
> error("unexpected EOF before %%");
> 
> /* t is MARK */
> if(!yyarg)
> Bprint(ftable, "extern	int	yyerrflag;\n");
> Bprint(ftable, "#ifndef	YYMAXDEPTH\n");
> Bprint(ftable, "#define	YYMAXDEPTH	150\n");
> Bprint(ftable, "#endif\n" );
> if(!ntypes) {
> Bprint(ftable, "#ifndef	YYSTYPE\n");
> Bprint(ftable, "#define	YYSTYPE	int\n");
> Bprint(ftable, "#endif\n");
> }
> if(!yyarg){
> Bprint(ftable, "YYSTYPE	yylval;\n");
> Bprint(ftable, "YYSTYPE	yyval;\n");
> }else{
> if(dflag)
> Bprint(ftable, "#include \"%s.%s\"\n\n", stemc, FILED);
> Bprint(fout, "struct Yyarg {\n");
> Bprint(fout, "\tint\tyynerrs;\n");
> Bprint(fout, "\tint\tyyerrflag;\n");
> Bprint(fout, "\tvoid*\targ;\n");
> Bprint(fout, "\tYYSTYPE\tyyval;\n");
> Bprint(fout, "\tYYSTYPE\tyylval;\n");
> Bprint(fout, "};\n\n");
> }
> prdptr[0] = mem;
> 
> /* added production */
> *mem++ = NTBASE;
> 
> /* if start is 0, we will overwrite with the lhs of the first rule */
> *mem++ = start;
> *mem++ = 1;
> *mem++ = 0;
> prdptr[1] = mem;
> while((t=gettok()) == LCURLY)
> cpycode();
> if(t != IDENTCOLON)
> error("bad syntax on first rule");
> 
> if(!start)
> prdptr[0][1] = chfind(1, tokname);
> 
> /* read rules */
> while(t != MARK && t != ENDFILE) {
> /* process a rule */
> rlines[nprod] = lineno;
> if(t == '|')
> *mem++ = *prdptr[nprod-1];
> else
> if(t == IDENTCOLON) {
> *mem = chfind(1, tokname);
> if(*mem < NTBASE)
> error("token illegal on LHS of grammar rule");
> mem++;
> } else
> error("illegal rule: missing semicolon or | ?");
> /* read rule body */
> t = gettok();
> 
> more_rule:
> while(t == IDENTIFIER) {
> *mem = chfind(1, tokname);
> if(*mem < NTBASE)
> levprd[nprod] = toklev[*mem];
> mem++;
> t = gettok();
> }
> if(t == PREC) {
> if(gettok() != IDENTIFIER)
> error("illegal %%prec syntax");
> j = chfind(2, tokname);
> if(j >= NTBASE)
> error("nonterminal %s illegal after %%prec",
> nontrst[j-NTBASE].name);
> levprd[nprod] = toklev[j];
> t = gettok();
> }
> if(t == '=') {
> levprd[nprod] |= ACTFLAG;
> Bprint(faction, "\ncase %d:", nprod);
> cpyact(mem-prdptr[nprod]-1);
> Bprint(faction, " break;");
> if((t=gettok()) == IDENTIFIER) {
> 
> /* action within rule... */
> sprint(actnm, "$$%d", nprod);
> 
> /* make it a nonterminal */
> j = chfind(1, actnm);
> 
> /*
> * the current rule will become rule number nprod+1
> * move the contents down, and make room for the null
> */
> for(p = mem; p >= prdptr[nprod]; --p)
> p[2] = *p;
> mem += 2;
> 
> /* enter null production for action */
> p = prdptr[nprod];
> *p++ = j;
> *p++ = -nprod;
> 
> /* update the production information */
> levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
> levprd[nprod] = ACTFLAG;
> if(++nprod >= NPROD)
> error("more than %d rules", NPROD);
> prdptr[nprod] = p;
> 
> /* make the action appear in the original rule */
> *mem++ = j;
> 
> /* get some more of the rule */
> goto more_rule;
> }
> }
> 
> while(t == ';')
> t = gettok();
> *mem++ = -nprod;
> 
> /* check that default action is reasonable */
> if(ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].value) {
> 
> /* no explicit action, LHS has value */
> int tempty;
> 
> tempty = prdptr[nprod][1];
> if(tempty < 0)
> error("must return a value, since LHS has a type");
> else
> if(tempty >= NTBASE)
> tempty = nontrst[tempty-NTBASE].value;
> else
> tempty = TYPE(toklev[tempty]);
> if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
> error("default action causes potential type clash");
> }
> nprod++;
> if(nprod >= NPROD)
> error("more than %d rules", NPROD);
> prdptr[nprod] = mem;
> levprd[nprod] = 0;
> }
> 
> /* end of all rules */
> defout(1);
> 
> finact();
> if(t == MARK) {
> Bprint(ftable, "\n");
> if(yyline)
> Bprint(ftable, "#line\t%d\t\"%s\"\n", lineno, infile);
> while((c=Bgetrune(finput)) != Beof)
> Bputrune(ftable, c);
> }
> Bterm(finput);
> }
> 
> 
>> On Wed, Nov 25, 2015 at 10:03 AM,  <plannine@sigint.cs.purdue.edu> wrote:
>> On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
>> > unindented consequences
>> 
>> Is that a class of Python bugs or an awesome name for a Nerdcore band?
> 
> 
> 
> -- 
> Ryan
> [ERROR]: Your autotools build scripts are 200 lines longer than your program. Something’s wrong.
> http://kirbyfan64.github.io/ 

[-- Attachment #2: Type: text/html, Size: 12943 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-25 16:03             ` plannine
  2015-11-25 17:13               ` Ryan Gonzalez
@ 2015-11-25 19:19               ` Steffen Nurpmeso
  1 sibling, 0 replies; 40+ messages in thread
From: Steffen Nurpmeso @ 2015-11-25 19:19 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

plannine@sigint.cs.purdue.edu wrote:
 |On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
 |> unindented consequences
 |
 |Is that a class of Python bugs or an awesome name for a Nerdcore band?

all that new C stuff and sequencing is shit.  imho :)

--steffen



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-25 18:41                 ` Brantley Coile
@ 2015-11-26  2:04                   ` Prof Brucee
  2015-11-26  2:43                     ` Brantley Coile
  2015-11-26  7:27                     ` Bakul Shah
  0 siblings, 2 replies; 40+ messages in thread
From: Prof Brucee @ 2015-11-26  2:04 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 8869 bytes --]

gcc is indeed a very sad tome. The mmap of 0 is disgusting. I like kenc. It
just works. My behaviour this afternoon will be undefined but not as stupid
as that of some programmers.
On 26/11/2015 5:43 AM, "Brantley Coile" <brantleycoile@me.com> wrote:

> Align it to column 7 and it looks like all the code I saw when I started.
>
> iPhone email
>
> On Nov 25, 2015, at 12:13 PM, Ryan Gonzalez <rymg19@gmail.com> wrote:
>
> Neither! It's what happens when you run sed 's/^\s*//' on your whole code
> base, yielding results like (from cmd/yacc.c):
>
>
> void
> setup(int argc, char *argv[])
> {
> long c, t;
> int i, j, fd, lev, ty, ytab, *p;
> int vflag, dflag, stem;
> char actnm[8], *stemc, *s, dirbuf[128];
> Biobuf *fout;
>
> ytab = 0;
> vflag = 0;
> dflag = 0;
> stem = 0;
> stemc = "y";
> foutput = 0;
> fdefine = 0;
> fdebug = 0;
> ARGBEGIN{
> case 'v':
> case 'V':
> vflag++;
> break;
> case 'D':
> yydebug = ARGF();
> break;
> case 'a':
> yyarg = 1;
> break;
> case 'd':
> dflag++;
> break;
> case 'l':
> yyline = 0;
> break;
> case 'o':
> ytab++;
> ytabc = ARGF();
> break;
> case 's':
> stem++;
> stemc = ARGF();
> break;
> case 'S':
> parser = PARSERS;
> break;
> default:
> error("illegal option: %c", ARGC());
> }ARGEND
> openup(stemc, dflag, vflag, ytab, ytabc);
> fout = dflag?fdefine:ftable;
> if(yyarg){
> Bprint(ftable, "#define\tYYARG\t1\n\n");
> }
> if((fd = mkstemp(ttempname)) >= 0){
> tempname = ttempname;
> ftemp = Bfdopen(fd, OWRITE);
> }
> if((fd = mkstemp(tactname)) >= 0){
> actname = tactname;
> faction = Bfdopen(fd, OWRITE);
> }
> if(ftemp == 0 || faction == 0)
> error("cannot open temp file");
> if(argc < 1)
> error("no input file");
> infile = argv[0];
> if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
> i = strlen(infile)+1+strlen(dirbuf)+1+10;
> s = malloc(i);
> if(s != nil){
> snprint(s, i, "%s/%s", dirbuf, infile);
> cleanname(s);
> infile = s;
> }
> }
> finput = Bopen(infile, OREAD);
> if(finput == 0)
> error("cannot open '%s'", argv[0]);
> cnamp = cnames;
>
> defin(0, "$end");
> extval = PRIVATE; /* tokens start in unicode 'private use' */
> defin(0, "error");
> defin(1, "$accept");
> defin(0, "$unk");
> mem = mem0;
> i = 0;
>
> for(t = gettok(); t != MARK && t != ENDFILE;)
> switch(t) {
> case ';':
> t = gettok();
> break;
>
> case START:
> if(gettok() != IDENTIFIER)
> error("bad %%start construction");
> start = chfind(1, tokname);
> t = gettok();
> continue;
>
> case TYPEDEF:
> if(gettok() != TYPENAME)
> error("bad syntax in %%type");
> ty = numbval;
> for(;;) {
> t = gettok();
> switch(t) {
> case IDENTIFIER:
> if((t=chfind(1, tokname)) < NTBASE) {
> j = TYPE(toklev[t]);
> if(j != 0 && j != ty)
> error("type redeclaration of token %s",
> tokset[t].name);
> else
> SETTYPE(toklev[t], ty);
> } else {
> j = nontrst[t-NTBASE].value;
> if(j != 0 && j != ty)
> error("type redeclaration of nonterminal %s",
> nontrst[t-NTBASE].name );
> else
> nontrst[t-NTBASE].value = ty;
> }
> case ',':
> continue;
> case ';':
> t = gettok();
> default:
> break;
> }
> break;
> }
> continue;
>
> case UNION:
> /* copy the union declaration to the output */
> cpyunion();
> t = gettok();
> continue;
>
> case LEFT:
> case BINARY:
> case RIGHT:
> i++;
>
> case TERM:
> /* nonzero means new prec. and assoc. */
> lev = t-TERM;
> ty = 0;
>
> /* get identifiers so defined */
> t = gettok();
>
> /* there is a type defined */
> if(t == TYPENAME) {
> ty = numbval;
> t = gettok();
> }
> for(;;) {
> switch(t) {
> case ',':
> t = gettok();
> continue;
>
> case ';':
> break;
>
> case IDENTIFIER:
> j = chfind(0, tokname);
> if(j >= NTBASE)
> error("%s defined earlier as nonterminal", tokname);
> if(lev) {
> if(ASSOC(toklev[j]))
> error("redeclaration of precedence of %s", tokname);
> SETASC(toklev[j], lev);
> SETPLEV(toklev[j], i);
> }
> if(ty) {
> if(TYPE(toklev[j]))
> error("redeclaration of type of %s", tokname);
> SETTYPE(toklev[j],ty);
> }
> t = gettok();
> if(t == NUMBER) {
> tokset[j].value = numbval;
> if(j < ndefout && j > 3)
> error("please define type number of %s earlier",
> tokset[j].name);
> t = gettok();
> }
> continue;
> }
> break;
> }
> continue;
>
> case LCURLY:
> defout(0);
> cpycode();
> t = gettok();
> continue;
>
> default:
> error("syntax error");
> }
> if(t == ENDFILE)
> error("unexpected EOF before %%");
>
> /* t is MARK */
> if(!yyarg)
> Bprint(ftable, "extern int yyerrflag;\n");
> Bprint(ftable, "#ifndef YYMAXDEPTH\n");
> Bprint(ftable, "#define YYMAXDEPTH 150\n");
> Bprint(ftable, "#endif\n" );
> if(!ntypes) {
> Bprint(ftable, "#ifndef YYSTYPE\n");
> Bprint(ftable, "#define YYSTYPE int\n");
> Bprint(ftable, "#endif\n");
> }
> if(!yyarg){
> Bprint(ftable, "YYSTYPE yylval;\n");
> Bprint(ftable, "YYSTYPE yyval;\n");
> }else{
> if(dflag)
> Bprint(ftable, "#include \"%s.%s\"\n\n", stemc, FILED);
> Bprint(fout, "struct Yyarg {\n");
> Bprint(fout, "\tint\tyynerrs;\n");
> Bprint(fout, "\tint\tyyerrflag;\n");
> Bprint(fout, "\tvoid*\targ;\n");
> Bprint(fout, "\tYYSTYPE\tyyval;\n");
> Bprint(fout, "\tYYSTYPE\tyylval;\n");
> Bprint(fout, "};\n\n");
> }
> prdptr[0] = mem;
>
> /* added production */
> *mem++ = NTBASE;
>
> /* if start is 0, we will overwrite with the lhs of the first rule */
> *mem++ = start;
> *mem++ = 1;
> *mem++ = 0;
> prdptr[1] = mem;
> while((t=gettok()) == LCURLY)
> cpycode();
> if(t != IDENTCOLON)
> error("bad syntax on first rule");
>
> if(!start)
> prdptr[0][1] = chfind(1, tokname);
>
> /* read rules */
> while(t != MARK && t != ENDFILE) {
> /* process a rule */
> rlines[nprod] = lineno;
> if(t == '|')
> *mem++ = *prdptr[nprod-1];
> else
> if(t == IDENTCOLON) {
> *mem = chfind(1, tokname);
> if(*mem < NTBASE)
> error("token illegal on LHS of grammar rule");
> mem++;
> } else
> error("illegal rule: missing semicolon or | ?");
> /* read rule body */
> t = gettok();
>
> more_rule:
> while(t == IDENTIFIER) {
> *mem = chfind(1, tokname);
> if(*mem < NTBASE)
> levprd[nprod] = toklev[*mem];
> mem++;
> t = gettok();
> }
> if(t == PREC) {
> if(gettok() != IDENTIFIER)
> error("illegal %%prec syntax");
> j = chfind(2, tokname);
> if(j >= NTBASE)
> error("nonterminal %s illegal after %%prec",
> nontrst[j-NTBASE].name);
> levprd[nprod] = toklev[j];
> t = gettok();
> }
> if(t == '=') {
> levprd[nprod] |= ACTFLAG;
> Bprint(faction, "\ncase %d:", nprod);
> cpyact(mem-prdptr[nprod]-1);
> Bprint(faction, " break;");
> if((t=gettok()) == IDENTIFIER) {
>
> /* action within rule... */
> sprint(actnm, "$$%d", nprod);
>
> /* make it a nonterminal */
> j = chfind(1, actnm);
>
> /*
> * the current rule will become rule number nprod+1
> * move the contents down, and make room for the null
> */
> for(p = mem; p >= prdptr[nprod]; --p)
> p[2] = *p;
> mem += 2;
>
> /* enter null production for action */
> p = prdptr[nprod];
> *p++ = j;
> *p++ = -nprod;
>
> /* update the production information */
> levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
> levprd[nprod] = ACTFLAG;
> if(++nprod >= NPROD)
> error("more than %d rules", NPROD);
> prdptr[nprod] = p;
>
> /* make the action appear in the original rule */
> *mem++ = j;
>
> /* get some more of the rule */
> goto more_rule;
> }
> }
>
> while(t == ';')
> t = gettok();
> *mem++ = -nprod;
>
> /* check that default action is reasonable */
> if(ntypes && !(levprd[nprod]&ACTFLAG) &&
> nontrst[*prdptr[nprod]-NTBASE].value) {
>
> /* no explicit action, LHS has value */
> int tempty;
>
> tempty = prdptr[nprod][1];
> if(tempty < 0)
> error("must return a value, since LHS has a type");
> else
> if(tempty >= NTBASE)
> tempty = nontrst[tempty-NTBASE].value;
> else
> tempty = TYPE(toklev[tempty]);
> if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
> error("default action causes potential type clash");
> }
> nprod++;
> if(nprod >= NPROD)
> error("more than %d rules", NPROD);
> prdptr[nprod] = mem;
> levprd[nprod] = 0;
> }
>
> /* end of all rules */
> defout(1);
>
> finact();
> if(t == MARK) {
> Bprint(ftable, "\n");
> if(yyline)
> Bprint(ftable, "#line\t%d\t\"%s\"\n", lineno, infile);
> while((c=Bgetrune(finput)) != Beof)
> Bputrune(ftable, c);
> }
> Bterm(finput);
> }
>
>
> On Wed, Nov 25, 2015 at 10:03 AM, <plannine@sigint.cs.purdue.edu> wrote:
>
>> On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
>> > unindented consequences
>>
>> Is that a class of Python bugs or an awesome name for a Nerdcore band?
>>
>>
>
>
> --
> Ryan
> [ERROR]: Your autotools build scripts are 200 lines longer than your
> program. Something’s wrong.
> http://kirbyfan64.github.io/
>
>
>

[-- Attachment #2: Type: text/html, Size: 13996 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26  2:04                   ` Prof Brucee
@ 2015-11-26  2:43                     ` Brantley Coile
  2015-11-26  2:57                       ` Prof Brucee
  2015-11-26  7:27                     ` Bakul Shah
  1 sibling, 1 reply; 40+ messages in thread
From: Brantley Coile @ 2015-11-26  2:43 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 9811 bytes --]

Bruce's law: undefined != stupid

Sent from my iPad

> On Nov 25, 2015, at 9:04 PM, Prof Brucee <prof.brucee@gmail.com> wrote:
> 
> gcc is indeed a very sad tome. The mmap of 0 is disgusting. I like kenc. It just works. My behaviour this afternoon will be undefined but not as stupid as that of some programmers.
> 
>> On 26/11/2015 5:43 AM, "Brantley Coile" <brantleycoile@me.com> wrote:
>> Align it to column 7 and it looks like all the code I saw when I started. 
>> 
>> iPhone email
>> 
>>> On Nov 25, 2015, at 12:13 PM, Ryan Gonzalez <rymg19@gmail.com> wrote:
>>> 
>>> Neither! It's what happens when you run sed 's/^\s*//' on your whole code base, yielding results like (from cmd/yacc.c):
>>> 
>>> 
>>> void
>>> setup(int argc, char *argv[])
>>> {
>>> long c, t;
>>> int i, j, fd, lev, ty, ytab, *p;
>>> int vflag, dflag, stem;
>>> char actnm[8], *stemc, *s, dirbuf[128];
>>> Biobuf *fout;
>>> 
>>> ytab = 0;
>>> vflag = 0;
>>> dflag = 0;
>>> stem = 0;
>>> stemc = "y";
>>> foutput = 0;
>>> fdefine = 0;
>>> fdebug = 0;
>>> ARGBEGIN{
>>> case 'v':
>>> case 'V':
>>> vflag++;
>>> break;
>>> case 'D':
>>> yydebug = ARGF();
>>> break;
>>> case 'a':
>>> yyarg = 1;
>>> break;
>>> case 'd':
>>> dflag++;
>>> break;
>>> case 'l':
>>> yyline = 0;
>>> break;
>>> case 'o':
>>> ytab++;
>>> ytabc = ARGF();
>>> break;
>>> case 's':
>>> stem++;
>>> stemc = ARGF();
>>> break;
>>> case 'S':
>>> parser = PARSERS;
>>> break;
>>> default:
>>> error("illegal option: %c", ARGC());
>>> }ARGEND
>>> openup(stemc, dflag, vflag, ytab, ytabc);
>>> fout = dflag?fdefine:ftable;
>>> if(yyarg){
>>> Bprint(ftable, "#define\tYYARG\t1\n\n");
>>> }
>>> if((fd = mkstemp(ttempname)) >= 0){
>>> tempname = ttempname;
>>> ftemp = Bfdopen(fd, OWRITE);
>>> }
>>> if((fd = mkstemp(tactname)) >= 0){
>>> actname = tactname;
>>> faction = Bfdopen(fd, OWRITE);
>>> }
>>> if(ftemp == 0 || faction == 0)
>>> error("cannot open temp file");
>>> if(argc < 1)
>>> error("no input file");
>>> infile = argv[0];
>>> if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
>>> i = strlen(infile)+1+strlen(dirbuf)+1+10;
>>> s = malloc(i);
>>> if(s != nil){
>>> snprint(s, i, "%s/%s", dirbuf, infile);
>>> cleanname(s);
>>> infile = s;
>>> }
>>> }
>>> finput = Bopen(infile, OREAD);
>>> if(finput == 0)
>>> error("cannot open '%s'", argv[0]);
>>> cnamp = cnames;
>>> 
>>> defin(0, "$end");
>>> extval = PRIVATE;	/* tokens start in unicode 'private use' */
>>> defin(0, "error");
>>> defin(1, "$accept");
>>> defin(0, "$unk");
>>> mem = mem0;
>>> i = 0;
>>> 
>>> for(t = gettok(); t != MARK && t != ENDFILE;)
>>> switch(t) {
>>> case ';':
>>> t = gettok();
>>> break;
>>> 
>>> case START:
>>> if(gettok() != IDENTIFIER)
>>> error("bad %%start construction");
>>> start = chfind(1, tokname);
>>> t = gettok();
>>> continue;
>>> 
>>> case TYPEDEF:
>>> if(gettok() != TYPENAME)
>>> error("bad syntax in %%type");
>>> ty = numbval;
>>> for(;;) {
>>> t = gettok();
>>> switch(t) {
>>> case IDENTIFIER:
>>> if((t=chfind(1, tokname)) < NTBASE) {
>>> j = TYPE(toklev[t]);
>>> if(j != 0 && j != ty)
>>> error("type redeclaration of token %s",
>>> tokset[t].name);
>>> else
>>> SETTYPE(toklev[t], ty);
>>> } else {
>>> j = nontrst[t-NTBASE].value;
>>> if(j != 0 && j != ty)
>>> error("type redeclaration of nonterminal %s",
>>> nontrst[t-NTBASE].name );
>>> else
>>> nontrst[t-NTBASE].value = ty;
>>> }
>>> case ',':
>>> continue;
>>> case ';':
>>> t = gettok();
>>> default:
>>> break;
>>> }
>>> break;
>>> }
>>> continue;
>>> 
>>> case UNION:
>>> /* copy the union declaration to the output */
>>> cpyunion();
>>> t = gettok();
>>> continue;
>>> 
>>> case LEFT:
>>> case BINARY:
>>> case RIGHT:
>>> i++;
>>> 
>>> case TERM:
>>> /* nonzero means new prec. and assoc. */
>>> lev = t-TERM;
>>> ty = 0;
>>> 
>>> /* get identifiers so defined */
>>> t = gettok();
>>> 
>>> /* there is a type defined */
>>> if(t == TYPENAME) {
>>> ty = numbval;
>>> t = gettok();
>>> }
>>> for(;;) {
>>> switch(t) {
>>> case ',':
>>> t = gettok();
>>> continue;
>>> 
>>> case ';':
>>> break;
>>> 
>>> case IDENTIFIER:
>>> j = chfind(0, tokname);
>>> if(j >= NTBASE)
>>> error("%s defined earlier as nonterminal", tokname);
>>> if(lev) {
>>> if(ASSOC(toklev[j]))
>>> error("redeclaration of precedence of %s", tokname);
>>> SETASC(toklev[j], lev);
>>> SETPLEV(toklev[j], i);
>>> }
>>> if(ty) {
>>> if(TYPE(toklev[j]))
>>> error("redeclaration of type of %s", tokname);
>>> SETTYPE(toklev[j],ty);
>>> }
>>> t = gettok();
>>> if(t == NUMBER) {
>>> tokset[j].value = numbval;
>>> if(j < ndefout && j > 3)
>>> error("please define type number of %s earlier",
>>> tokset[j].name);
>>> t = gettok();
>>> }
>>> continue;
>>> }
>>> break;
>>> }
>>> continue;
>>> 
>>> case LCURLY:
>>> defout(0);
>>> cpycode();
>>> t = gettok();
>>> continue;
>>> 
>>> default:
>>> error("syntax error");
>>> }
>>> if(t == ENDFILE)
>>> error("unexpected EOF before %%");
>>> 
>>> /* t is MARK */
>>> if(!yyarg)
>>> Bprint(ftable, "extern	int	yyerrflag;\n");
>>> Bprint(ftable, "#ifndef	YYMAXDEPTH\n");
>>> Bprint(ftable, "#define	YYMAXDEPTH	150\n");
>>> Bprint(ftable, "#endif\n" );
>>> if(!ntypes) {
>>> Bprint(ftable, "#ifndef	YYSTYPE\n");
>>> Bprint(ftable, "#define	YYSTYPE	int\n");
>>> Bprint(ftable, "#endif\n");
>>> }
>>> if(!yyarg){
>>> Bprint(ftable, "YYSTYPE	yylval;\n");
>>> Bprint(ftable, "YYSTYPE	yyval;\n");
>>> }else{
>>> if(dflag)
>>> Bprint(ftable, "#include \"%s.%s\"\n\n", stemc, FILED);
>>> Bprint(fout, "struct Yyarg {\n");
>>> Bprint(fout, "\tint\tyynerrs;\n");
>>> Bprint(fout, "\tint\tyyerrflag;\n");
>>> Bprint(fout, "\tvoid*\targ;\n");
>>> Bprint(fout, "\tYYSTYPE\tyyval;\n");
>>> Bprint(fout, "\tYYSTYPE\tyylval;\n");
>>> Bprint(fout, "};\n\n");
>>> }
>>> prdptr[0] = mem;
>>> 
>>> /* added production */
>>> *mem++ = NTBASE;
>>> 
>>> /* if start is 0, we will overwrite with the lhs of the first rule */
>>> *mem++ = start;
>>> *mem++ = 1;
>>> *mem++ = 0;
>>> prdptr[1] = mem;
>>> while((t=gettok()) == LCURLY)
>>> cpycode();
>>> if(t != IDENTCOLON)
>>> error("bad syntax on first rule");
>>> 
>>> if(!start)
>>> prdptr[0][1] = chfind(1, tokname);
>>> 
>>> /* read rules */
>>> while(t != MARK && t != ENDFILE) {
>>> /* process a rule */
>>> rlines[nprod] = lineno;
>>> if(t == '|')
>>> *mem++ = *prdptr[nprod-1];
>>> else
>>> if(t == IDENTCOLON) {
>>> *mem = chfind(1, tokname);
>>> if(*mem < NTBASE)
>>> error("token illegal on LHS of grammar rule");
>>> mem++;
>>> } else
>>> error("illegal rule: missing semicolon or | ?");
>>> /* read rule body */
>>> t = gettok();
>>> 
>>> more_rule:
>>> while(t == IDENTIFIER) {
>>> *mem = chfind(1, tokname);
>>> if(*mem < NTBASE)
>>> levprd[nprod] = toklev[*mem];
>>> mem++;
>>> t = gettok();
>>> }
>>> if(t == PREC) {
>>> if(gettok() != IDENTIFIER)
>>> error("illegal %%prec syntax");
>>> j = chfind(2, tokname);
>>> if(j >= NTBASE)
>>> error("nonterminal %s illegal after %%prec",
>>> nontrst[j-NTBASE].name);
>>> levprd[nprod] = toklev[j];
>>> t = gettok();
>>> }
>>> if(t == '=') {
>>> levprd[nprod] |= ACTFLAG;
>>> Bprint(faction, "\ncase %d:", nprod);
>>> cpyact(mem-prdptr[nprod]-1);
>>> Bprint(faction, " break;");
>>> if((t=gettok()) == IDENTIFIER) {
>>> 
>>> /* action within rule... */
>>> sprint(actnm, "$$%d", nprod);
>>> 
>>> /* make it a nonterminal */
>>> j = chfind(1, actnm);
>>> 
>>> /*
>>> * the current rule will become rule number nprod+1
>>> * move the contents down, and make room for the null
>>> */
>>> for(p = mem; p >= prdptr[nprod]; --p)
>>> p[2] = *p;
>>> mem += 2;
>>> 
>>> /* enter null production for action */
>>> p = prdptr[nprod];
>>> *p++ = j;
>>> *p++ = -nprod;
>>> 
>>> /* update the production information */
>>> levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
>>> levprd[nprod] = ACTFLAG;
>>> if(++nprod >= NPROD)
>>> error("more than %d rules", NPROD);
>>> prdptr[nprod] = p;
>>> 
>>> /* make the action appear in the original rule */
>>> *mem++ = j;
>>> 
>>> /* get some more of the rule */
>>> goto more_rule;
>>> }
>>> }
>>> 
>>> while(t == ';')
>>> t = gettok();
>>> *mem++ = -nprod;
>>> 
>>> /* check that default action is reasonable */
>>> if(ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].value) {
>>> 
>>> /* no explicit action, LHS has value */
>>> int tempty;
>>> 
>>> tempty = prdptr[nprod][1];
>>> if(tempty < 0)
>>> error("must return a value, since LHS has a type");
>>> else
>>> if(tempty >= NTBASE)
>>> tempty = nontrst[tempty-NTBASE].value;
>>> else
>>> tempty = TYPE(toklev[tempty]);
>>> if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
>>> error("default action causes potential type clash");
>>> }
>>> nprod++;
>>> if(nprod >= NPROD)
>>> error("more than %d rules", NPROD);
>>> prdptr[nprod] = mem;
>>> levprd[nprod] = 0;
>>> }
>>> 
>>> /* end of all rules */
>>> defout(1);
>>> 
>>> finact();
>>> if(t == MARK) {
>>> Bprint(ftable, "\n");
>>> if(yyline)
>>> Bprint(ftable, "#line\t%d\t\"%s\"\n", lineno, infile);
>>> while((c=Bgetrune(finput)) != Beof)
>>> Bputrune(ftable, c);
>>> }
>>> Bterm(finput);
>>> }
>>> 
>>> 
>>>> On Wed, Nov 25, 2015 at 10:03 AM, <plannine@sigint.cs.purdue.edu> wrote:
>>>> On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
>>>> > unindented consequences
>>>> 
>>>> Is that a class of Python bugs or an awesome name for a Nerdcore band?
>>> 
>>> 
>>> 
>>> -- 
>>> Ryan
>>> [ERROR]: Your autotools build scripts are 200 lines longer than your program. Something’s wrong.
>>> http://kirbyfan64.github.io/

[-- Attachment #2: Type: text/html, Size: 13658 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26  2:43                     ` Brantley Coile
@ 2015-11-26  2:57                       ` Prof Brucee
  2015-11-26  3:48                         ` Ryan Gonzalez
  0 siblings, 1 reply; 40+ messages in thread
From: Prof Brucee @ 2015-11-26  2:57 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 9704 bytes --]

I am still fascinated by the VAX architecture manual which designates as
"unpredictable" many things with consequences  including machine crash.
Pissed that I can't get my vaxen to crash or burst into flames.
On 26/11/2015 1:46 PM, "Brantley Coile" <brantleycoile@me.com> wrote:

> Bruce's law: undefined != stupid
>
> Sent from my iPad
>
> On Nov 25, 2015, at 9:04 PM, Prof Brucee <prof.brucee@gmail.com> wrote:
>
> gcc is indeed a very sad tome. The mmap of 0 is disgusting. I like kenc.
> It just works. My behaviour this afternoon will be undefined but not as
> stupid as that of some programmers.
> On 26/11/2015 5:43 AM, "Brantley Coile" <brantleycoile@me.com> wrote:
>
>> Align it to column 7 and it looks like all the code I saw when I started.
>>
>> iPhone email
>>
>> On Nov 25, 2015, at 12:13 PM, Ryan Gonzalez <rymg19@gmail.com> wrote:
>>
>> Neither! It's what happens when you run sed 's/^\s*//' on your whole code
>> base, yielding results like (from cmd/yacc.c):
>>
>>
>> void
>> setup(int argc, char *argv[])
>> {
>> long c, t;
>> int i, j, fd, lev, ty, ytab, *p;
>> int vflag, dflag, stem;
>> char actnm[8], *stemc, *s, dirbuf[128];
>> Biobuf *fout;
>>
>> ytab = 0;
>> vflag = 0;
>> dflag = 0;
>> stem = 0;
>> stemc = "y";
>> foutput = 0;
>> fdefine = 0;
>> fdebug = 0;
>> ARGBEGIN{
>> case 'v':
>> case 'V':
>> vflag++;
>> break;
>> case 'D':
>> yydebug = ARGF();
>> break;
>> case 'a':
>> yyarg = 1;
>> break;
>> case 'd':
>> dflag++;
>> break;
>> case 'l':
>> yyline = 0;
>> break;
>> case 'o':
>> ytab++;
>> ytabc = ARGF();
>> break;
>> case 's':
>> stem++;
>> stemc = ARGF();
>> break;
>> case 'S':
>> parser = PARSERS;
>> break;
>> default:
>> error("illegal option: %c", ARGC());
>> }ARGEND
>> openup(stemc, dflag, vflag, ytab, ytabc);
>> fout = dflag?fdefine:ftable;
>> if(yyarg){
>> Bprint(ftable, "#define\tYYARG\t1\n\n");
>> }
>> if((fd = mkstemp(ttempname)) >= 0){
>> tempname = ttempname;
>> ftemp = Bfdopen(fd, OWRITE);
>> }
>> if((fd = mkstemp(tactname)) >= 0){
>> actname = tactname;
>> faction = Bfdopen(fd, OWRITE);
>> }
>> if(ftemp == 0 || faction == 0)
>> error("cannot open temp file");
>> if(argc < 1)
>> error("no input file");
>> infile = argv[0];
>> if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
>> i = strlen(infile)+1+strlen(dirbuf)+1+10;
>> s = malloc(i);
>> if(s != nil){
>> snprint(s, i, "%s/%s", dirbuf, infile);
>> cleanname(s);
>> infile = s;
>> }
>> }
>> finput = Bopen(infile, OREAD);
>> if(finput == 0)
>> error("cannot open '%s'", argv[0]);
>> cnamp = cnames;
>>
>> defin(0, "$end");
>> extval = PRIVATE; /* tokens start in unicode 'private use' */
>> defin(0, "error");
>> defin(1, "$accept");
>> defin(0, "$unk");
>> mem = mem0;
>> i = 0;
>>
>> for(t = gettok(); t != MARK && t != ENDFILE;)
>> switch(t) {
>> case ';':
>> t = gettok();
>> break;
>>
>> case START:
>> if(gettok() != IDENTIFIER)
>> error("bad %%start construction");
>> start = chfind(1, tokname);
>> t = gettok();
>> continue;
>>
>> case TYPEDEF:
>> if(gettok() != TYPENAME)
>> error("bad syntax in %%type");
>> ty = numbval;
>> for(;;) {
>> t = gettok();
>> switch(t) {
>> case IDENTIFIER:
>> if((t=chfind(1, tokname)) < NTBASE) {
>> j = TYPE(toklev[t]);
>> if(j != 0 && j != ty)
>> error("type redeclaration of token %s",
>> tokset[t].name);
>> else
>> SETTYPE(toklev[t], ty);
>> } else {
>> j = nontrst[t-NTBASE].value;
>> if(j != 0 && j != ty)
>> error("type redeclaration of nonterminal %s",
>> nontrst[t-NTBASE].name );
>> else
>> nontrst[t-NTBASE].value = ty;
>> }
>> case ',':
>> continue;
>> case ';':
>> t = gettok();
>> default:
>> break;
>> }
>> break;
>> }
>> continue;
>>
>> case UNION:
>> /* copy the union declaration to the output */
>> cpyunion();
>> t = gettok();
>> continue;
>>
>> case LEFT:
>> case BINARY:
>> case RIGHT:
>> i++;
>>
>> case TERM:
>> /* nonzero means new prec. and assoc. */
>> lev = t-TERM;
>> ty = 0;
>>
>> /* get identifiers so defined */
>> t = gettok();
>>
>> /* there is a type defined */
>> if(t == TYPENAME) {
>> ty = numbval;
>> t = gettok();
>> }
>> for(;;) {
>> switch(t) {
>> case ',':
>> t = gettok();
>> continue;
>>
>> case ';':
>> break;
>>
>> case IDENTIFIER:
>> j = chfind(0, tokname);
>> if(j >= NTBASE)
>> error("%s defined earlier as nonterminal", tokname);
>> if(lev) {
>> if(ASSOC(toklev[j]))
>> error("redeclaration of precedence of %s", tokname);
>> SETASC(toklev[j], lev);
>> SETPLEV(toklev[j], i);
>> }
>> if(ty) {
>> if(TYPE(toklev[j]))
>> error("redeclaration of type of %s", tokname);
>> SETTYPE(toklev[j],ty);
>> }
>> t = gettok();
>> if(t == NUMBER) {
>> tokset[j].value = numbval;
>> if(j < ndefout && j > 3)
>> error("please define type number of %s earlier",
>> tokset[j].name);
>> t = gettok();
>> }
>> continue;
>> }
>> break;
>> }
>> continue;
>>
>> case LCURLY:
>> defout(0);
>> cpycode();
>> t = gettok();
>> continue;
>>
>> default:
>> error("syntax error");
>> }
>> if(t == ENDFILE)
>> error("unexpected EOF before %%");
>>
>> /* t is MARK */
>> if(!yyarg)
>> Bprint(ftable, "extern int yyerrflag;\n");
>> Bprint(ftable, "#ifndef YYMAXDEPTH\n");
>> Bprint(ftable, "#define YYMAXDEPTH 150\n");
>> Bprint(ftable, "#endif\n" );
>> if(!ntypes) {
>> Bprint(ftable, "#ifndef YYSTYPE\n");
>> Bprint(ftable, "#define YYSTYPE int\n");
>> Bprint(ftable, "#endif\n");
>> }
>> if(!yyarg){
>> Bprint(ftable, "YYSTYPE yylval;\n");
>> Bprint(ftable, "YYSTYPE yyval;\n");
>> }else{
>> if(dflag)
>> Bprint(ftable, "#include \"%s.%s\"\n\n", stemc, FILED);
>> Bprint(fout, "struct Yyarg {\n");
>> Bprint(fout, "\tint\tyynerrs;\n");
>> Bprint(fout, "\tint\tyyerrflag;\n");
>> Bprint(fout, "\tvoid*\targ;\n");
>> Bprint(fout, "\tYYSTYPE\tyyval;\n");
>> Bprint(fout, "\tYYSTYPE\tyylval;\n");
>> Bprint(fout, "};\n\n");
>> }
>> prdptr[0] = mem;
>>
>> /* added production */
>> *mem++ = NTBASE;
>>
>> /* if start is 0, we will overwrite with the lhs of the first rule */
>> *mem++ = start;
>> *mem++ = 1;
>> *mem++ = 0;
>> prdptr[1] = mem;
>> while((t=gettok()) == LCURLY)
>> cpycode();
>> if(t != IDENTCOLON)
>> error("bad syntax on first rule");
>>
>> if(!start)
>> prdptr[0][1] = chfind(1, tokname);
>>
>> /* read rules */
>> while(t != MARK && t != ENDFILE) {
>> /* process a rule */
>> rlines[nprod] = lineno;
>> if(t == '|')
>> *mem++ = *prdptr[nprod-1];
>> else
>> if(t == IDENTCOLON) {
>> *mem = chfind(1, tokname);
>> if(*mem < NTBASE)
>> error("token illegal on LHS of grammar rule");
>> mem++;
>> } else
>> error("illegal rule: missing semicolon or | ?");
>> /* read rule body */
>> t = gettok();
>>
>> more_rule:
>> while(t == IDENTIFIER) {
>> *mem = chfind(1, tokname);
>> if(*mem < NTBASE)
>> levprd[nprod] = toklev[*mem];
>> mem++;
>> t = gettok();
>> }
>> if(t == PREC) {
>> if(gettok() != IDENTIFIER)
>> error("illegal %%prec syntax");
>> j = chfind(2, tokname);
>> if(j >= NTBASE)
>> error("nonterminal %s illegal after %%prec",
>> nontrst[j-NTBASE].name);
>> levprd[nprod] = toklev[j];
>> t = gettok();
>> }
>> if(t == '=') {
>> levprd[nprod] |= ACTFLAG;
>> Bprint(faction, "\ncase %d:", nprod);
>> cpyact(mem-prdptr[nprod]-1);
>> Bprint(faction, " break;");
>> if((t=gettok()) == IDENTIFIER) {
>>
>> /* action within rule... */
>> sprint(actnm, "$$%d", nprod);
>>
>> /* make it a nonterminal */
>> j = chfind(1, actnm);
>>
>> /*
>> * the current rule will become rule number nprod+1
>> * move the contents down, and make room for the null
>> */
>> for(p = mem; p >= prdptr[nprod]; --p)
>> p[2] = *p;
>> mem += 2;
>>
>> /* enter null production for action */
>> p = prdptr[nprod];
>> *p++ = j;
>> *p++ = -nprod;
>>
>> /* update the production information */
>> levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
>> levprd[nprod] = ACTFLAG;
>> if(++nprod >= NPROD)
>> error("more than %d rules", NPROD);
>> prdptr[nprod] = p;
>>
>> /* make the action appear in the original rule */
>> *mem++ = j;
>>
>> /* get some more of the rule */
>> goto more_rule;
>> }
>> }
>>
>> while(t == ';')
>> t = gettok();
>> *mem++ = -nprod;
>>
>> /* check that default action is reasonable */
>> if(ntypes && !(levprd[nprod]&ACTFLAG) &&
>> nontrst[*prdptr[nprod]-NTBASE].value) {
>>
>> /* no explicit action, LHS has value */
>> int tempty;
>>
>> tempty = prdptr[nprod][1];
>> if(tempty < 0)
>> error("must return a value, since LHS has a type");
>> else
>> if(tempty >= NTBASE)
>> tempty = nontrst[tempty-NTBASE].value;
>> else
>> tempty = TYPE(toklev[tempty]);
>> if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
>> error("default action causes potential type clash");
>> }
>> nprod++;
>> if(nprod >= NPROD)
>> error("more than %d rules", NPROD);
>> prdptr[nprod] = mem;
>> levprd[nprod] = 0;
>> }
>>
>> /* end of all rules */
>> defout(1);
>>
>> finact();
>> if(t == MARK) {
>> Bprint(ftable, "\n");
>> if(yyline)
>> Bprint(ftable, "#line\t%d\t\"%s\"\n", lineno, infile);
>> while((c=Bgetrune(finput)) != Beof)
>> Bputrune(ftable, c);
>> }
>> Bterm(finput);
>> }
>>
>>
>> On Wed, Nov 25, 2015 at 10:03 AM, <plannine@sigint.cs.purdue.edu> wrote:
>>
>>> On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
>>> > unindented consequences
>>>
>>> Is that a class of Python bugs or an awesome name for a Nerdcore band?
>>>
>>>
>>
>>
>> --
>> Ryan
>> [ERROR]: Your autotools build scripts are 200 lines longer than your
>> program. Something’s wrong.
>> http://kirbyfan64.github.io/
>>
>>
>>

[-- Attachment #2: Type: text/html, Size: 14853 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26  2:57                       ` Prof Brucee
@ 2015-11-26  3:48                         ` Ryan Gonzalez
  0 siblings, 0 replies; 40+ messages in thread
From: Ryan Gonzalez @ 2015-11-26  3:48 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs, Prof Brucee

[-- Attachment #1: Type: text/plain, Size: 10614 bytes --]

I remember reading Jack Crenshaw's Let's Build a Compiler. In part 16, he mentioned that compiling an empty C source file on the VAX took 60 seconds and generated a 50K object file.

Link (just search for the text "vax"): http://compilers.iecc.com/crenshaw/tutor16.txt

(BTW, what exactly do you mean by "mmap of 0"?)

On November 25, 2015 8:57:11 PM CST, Prof Brucee <prof.brucee@gmail.com> wrote:
>I am still fascinated by the VAX architecture manual which designates
>as
>"unpredictable" many things with consequences  including machine crash.
>Pissed that I can't get my vaxen to crash or burst into flames.
>On 26/11/2015 1:46 PM, "Brantley Coile" <brantleycoile@me.com> wrote:
>
>> Bruce's law: undefined != stupid
>>
>> Sent from my iPad
>>
>> On Nov 25, 2015, at 9:04 PM, Prof Brucee <prof.brucee@gmail.com>
>wrote:
>>
>> gcc is indeed a very sad tome. The mmap of 0 is disgusting. I like
>kenc.
>> It just works. My behaviour this afternoon will be undefined but not
>as
>> stupid as that of some programmers.
>> On 26/11/2015 5:43 AM, "Brantley Coile" <brantleycoile@me.com> wrote:
>>
>>> Align it to column 7 and it looks like all the code I saw when I
>started.
>>>
>>> iPhone email
>>>
>>> On Nov 25, 2015, at 12:13 PM, Ryan Gonzalez <rymg19@gmail.com>
>wrote:
>>>
>>> Neither! It's what happens when you run sed 's/^\s*//' on your whole
>code
>>> base, yielding results like (from cmd/yacc.c):
>>>
>>>
>>> void
>>> setup(int argc, char *argv[])
>>> {
>>> long c, t;
>>> int i, j, fd, lev, ty, ytab, *p;
>>> int vflag, dflag, stem;
>>> char actnm[8], *stemc, *s, dirbuf[128];
>>> Biobuf *fout;
>>>
>>> ytab = 0;
>>> vflag = 0;
>>> dflag = 0;
>>> stem = 0;
>>> stemc = "y";
>>> foutput = 0;
>>> fdefine = 0;
>>> fdebug = 0;
>>> ARGBEGIN{
>>> case 'v':
>>> case 'V':
>>> vflag++;
>>> break;
>>> case 'D':
>>> yydebug = ARGF();
>>> break;
>>> case 'a':
>>> yyarg = 1;
>>> break;
>>> case 'd':
>>> dflag++;
>>> break;
>>> case 'l':
>>> yyline = 0;
>>> break;
>>> case 'o':
>>> ytab++;
>>> ytabc = ARGF();
>>> break;
>>> case 's':
>>> stem++;
>>> stemc = ARGF();
>>> break;
>>> case 'S':
>>> parser = PARSERS;
>>> break;
>>> default:
>>> error("illegal option: %c", ARGC());
>>> }ARGEND
>>> openup(stemc, dflag, vflag, ytab, ytabc);
>>> fout = dflag?fdefine:ftable;
>>> if(yyarg){
>>> Bprint(ftable, "#define\tYYARG\t1\n\n");
>>> }
>>> if((fd = mkstemp(ttempname)) >= 0){
>>> tempname = ttempname;
>>> ftemp = Bfdopen(fd, OWRITE);
>>> }
>>> if((fd = mkstemp(tactname)) >= 0){
>>> actname = tactname;
>>> faction = Bfdopen(fd, OWRITE);
>>> }
>>> if(ftemp == 0 || faction == 0)
>>> error("cannot open temp file");
>>> if(argc < 1)
>>> error("no input file");
>>> infile = argv[0];
>>> if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
>>> i = strlen(infile)+1+strlen(dirbuf)+1+10;
>>> s = malloc(i);
>>> if(s != nil){
>>> snprint(s, i, "%s/%s", dirbuf, infile);
>>> cleanname(s);
>>> infile = s;
>>> }
>>> }
>>> finput = Bopen(infile, OREAD);
>>> if(finput == 0)
>>> error("cannot open '%s'", argv[0]);
>>> cnamp = cnames;
>>>
>>> defin(0, "$end");
>>> extval = PRIVATE; /* tokens start in unicode 'private use' */
>>> defin(0, "error");
>>> defin(1, "$accept");
>>> defin(0, "$unk");
>>> mem = mem0;
>>> i = 0;
>>>
>>> for(t = gettok(); t != MARK && t != ENDFILE;)
>>> switch(t) {
>>> case ';':
>>> t = gettok();
>>> break;
>>>
>>> case START:
>>> if(gettok() != IDENTIFIER)
>>> error("bad %%start construction");
>>> start = chfind(1, tokname);
>>> t = gettok();
>>> continue;
>>>
>>> case TYPEDEF:
>>> if(gettok() != TYPENAME)
>>> error("bad syntax in %%type");
>>> ty = numbval;
>>> for(;;) {
>>> t = gettok();
>>> switch(t) {
>>> case IDENTIFIER:
>>> if((t=chfind(1, tokname)) < NTBASE) {
>>> j = TYPE(toklev[t]);
>>> if(j != 0 && j != ty)
>>> error("type redeclaration of token %s",
>>> tokset[t].name);
>>> else
>>> SETTYPE(toklev[t], ty);
>>> } else {
>>> j = nontrst[t-NTBASE].value;
>>> if(j != 0 && j != ty)
>>> error("type redeclaration of nonterminal %s",
>>> nontrst[t-NTBASE].name );
>>> else
>>> nontrst[t-NTBASE].value = ty;
>>> }
>>> case ',':
>>> continue;
>>> case ';':
>>> t = gettok();
>>> default:
>>> break;
>>> }
>>> break;
>>> }
>>> continue;
>>>
>>> case UNION:
>>> /* copy the union declaration to the output */
>>> cpyunion();
>>> t = gettok();
>>> continue;
>>>
>>> case LEFT:
>>> case BINARY:
>>> case RIGHT:
>>> i++;
>>>
>>> case TERM:
>>> /* nonzero means new prec. and assoc. */
>>> lev = t-TERM;
>>> ty = 0;
>>>
>>> /* get identifiers so defined */
>>> t = gettok();
>>>
>>> /* there is a type defined */
>>> if(t == TYPENAME) {
>>> ty = numbval;
>>> t = gettok();
>>> }
>>> for(;;) {
>>> switch(t) {
>>> case ',':
>>> t = gettok();
>>> continue;
>>>
>>> case ';':
>>> break;
>>>
>>> case IDENTIFIER:
>>> j = chfind(0, tokname);
>>> if(j >= NTBASE)
>>> error("%s defined earlier as nonterminal", tokname);
>>> if(lev) {
>>> if(ASSOC(toklev[j]))
>>> error("redeclaration of precedence of %s", tokname);
>>> SETASC(toklev[j], lev);
>>> SETPLEV(toklev[j], i);
>>> }
>>> if(ty) {
>>> if(TYPE(toklev[j]))
>>> error("redeclaration of type of %s", tokname);
>>> SETTYPE(toklev[j],ty);
>>> }
>>> t = gettok();
>>> if(t == NUMBER) {
>>> tokset[j].value = numbval;
>>> if(j < ndefout && j > 3)
>>> error("please define type number of %s earlier",
>>> tokset[j].name);
>>> t = gettok();
>>> }
>>> continue;
>>> }
>>> break;
>>> }
>>> continue;
>>>
>>> case LCURLY:
>>> defout(0);
>>> cpycode();
>>> t = gettok();
>>> continue;
>>>
>>> default:
>>> error("syntax error");
>>> }
>>> if(t == ENDFILE)
>>> error("unexpected EOF before %%");
>>>
>>> /* t is MARK */
>>> if(!yyarg)
>>> Bprint(ftable, "extern int yyerrflag;\n");
>>> Bprint(ftable, "#ifndef YYMAXDEPTH\n");
>>> Bprint(ftable, "#define YYMAXDEPTH 150\n");
>>> Bprint(ftable, "#endif\n" );
>>> if(!ntypes) {
>>> Bprint(ftable, "#ifndef YYSTYPE\n");
>>> Bprint(ftable, "#define YYSTYPE int\n");
>>> Bprint(ftable, "#endif\n");
>>> }
>>> if(!yyarg){
>>> Bprint(ftable, "YYSTYPE yylval;\n");
>>> Bprint(ftable, "YYSTYPE yyval;\n");
>>> }else{
>>> if(dflag)
>>> Bprint(ftable, "#include \"%s.%s\"\n\n", stemc, FILED);
>>> Bprint(fout, "struct Yyarg {\n");
>>> Bprint(fout, "\tint\tyynerrs;\n");
>>> Bprint(fout, "\tint\tyyerrflag;\n");
>>> Bprint(fout, "\tvoid*\targ;\n");
>>> Bprint(fout, "\tYYSTYPE\tyyval;\n");
>>> Bprint(fout, "\tYYSTYPE\tyylval;\n");
>>> Bprint(fout, "};\n\n");
>>> }
>>> prdptr[0] = mem;
>>>
>>> /* added production */
>>> *mem++ = NTBASE;
>>>
>>> /* if start is 0, we will overwrite with the lhs of the first rule
>*/
>>> *mem++ = start;
>>> *mem++ = 1;
>>> *mem++ = 0;
>>> prdptr[1] = mem;
>>> while((t=gettok()) == LCURLY)
>>> cpycode();
>>> if(t != IDENTCOLON)
>>> error("bad syntax on first rule");
>>>
>>> if(!start)
>>> prdptr[0][1] = chfind(1, tokname);
>>>
>>> /* read rules */
>>> while(t != MARK && t != ENDFILE) {
>>> /* process a rule */
>>> rlines[nprod] = lineno;
>>> if(t == '|')
>>> *mem++ = *prdptr[nprod-1];
>>> else
>>> if(t == IDENTCOLON) {
>>> *mem = chfind(1, tokname);
>>> if(*mem < NTBASE)
>>> error("token illegal on LHS of grammar rule");
>>> mem++;
>>> } else
>>> error("illegal rule: missing semicolon or | ?");
>>> /* read rule body */
>>> t = gettok();
>>>
>>> more_rule:
>>> while(t == IDENTIFIER) {
>>> *mem = chfind(1, tokname);
>>> if(*mem < NTBASE)
>>> levprd[nprod] = toklev[*mem];
>>> mem++;
>>> t = gettok();
>>> }
>>> if(t == PREC) {
>>> if(gettok() != IDENTIFIER)
>>> error("illegal %%prec syntax");
>>> j = chfind(2, tokname);
>>> if(j >= NTBASE)
>>> error("nonterminal %s illegal after %%prec",
>>> nontrst[j-NTBASE].name);
>>> levprd[nprod] = toklev[j];
>>> t = gettok();
>>> }
>>> if(t == '=') {
>>> levprd[nprod] |= ACTFLAG;
>>> Bprint(faction, "\ncase %d:", nprod);
>>> cpyact(mem-prdptr[nprod]-1);
>>> Bprint(faction, " break;");
>>> if((t=gettok()) == IDENTIFIER) {
>>>
>>> /* action within rule... */
>>> sprint(actnm, "$$%d", nprod);
>>>
>>> /* make it a nonterminal */
>>> j = chfind(1, actnm);
>>>
>>> /*
>>> * the current rule will become rule number nprod+1
>>> * move the contents down, and make room for the null
>>> */
>>> for(p = mem; p >= prdptr[nprod]; --p)
>>> p[2] = *p;
>>> mem += 2;
>>>
>>> /* enter null production for action */
>>> p = prdptr[nprod];
>>> *p++ = j;
>>> *p++ = -nprod;
>>>
>>> /* update the production information */
>>> levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
>>> levprd[nprod] = ACTFLAG;
>>> if(++nprod >= NPROD)
>>> error("more than %d rules", NPROD);
>>> prdptr[nprod] = p;
>>>
>>> /* make the action appear in the original rule */
>>> *mem++ = j;
>>>
>>> /* get some more of the rule */
>>> goto more_rule;
>>> }
>>> }
>>>
>>> while(t == ';')
>>> t = gettok();
>>> *mem++ = -nprod;
>>>
>>> /* check that default action is reasonable */
>>> if(ntypes && !(levprd[nprod]&ACTFLAG) &&
>>> nontrst[*prdptr[nprod]-NTBASE].value) {
>>>
>>> /* no explicit action, LHS has value */
>>> int tempty;
>>>
>>> tempty = prdptr[nprod][1];
>>> if(tempty < 0)
>>> error("must return a value, since LHS has a type");
>>> else
>>> if(tempty >= NTBASE)
>>> tempty = nontrst[tempty-NTBASE].value;
>>> else
>>> tempty = TYPE(toklev[tempty]);
>>> if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
>>> error("default action causes potential type clash");
>>> }
>>> nprod++;
>>> if(nprod >= NPROD)
>>> error("more than %d rules", NPROD);
>>> prdptr[nprod] = mem;
>>> levprd[nprod] = 0;
>>> }
>>>
>>> /* end of all rules */
>>> defout(1);
>>>
>>> finact();
>>> if(t == MARK) {
>>> Bprint(ftable, "\n");
>>> if(yyline)
>>> Bprint(ftable, "#line\t%d\t\"%s\"\n", lineno, infile);
>>> while((c=Bgetrune(finput)) != Beof)
>>> Bputrune(ftable, c);
>>> }
>>> Bterm(finput);
>>> }
>>>
>>>
>>> On Wed, Nov 25, 2015 at 10:03 AM, <plannine@sigint.cs.purdue.edu>
>wrote:
>>>
>>>> On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
>>>> > unindented consequences
>>>>
>>>> Is that a class of Python bugs or an awesome name for a Nerdcore
>band?
>>>>
>>>>
>>>
>>>
>>> --
>>> Ryan
>>> [ERROR]: Your autotools build scripts are 200 lines longer than your
>>> program. Something’s wrong.
>>> http://kirbyfan64.github.io/
>>>
>>>
>>>

-- 
Sent from my Nexus 5 with K-9 Mail. Please excuse my brevity.

[-- Attachment #2: Type: text/html, Size: 15795 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26  2:04                   ` Prof Brucee
  2015-11-26  2:43                     ` Brantley Coile
@ 2015-11-26  7:27                     ` Bakul Shah
  2015-11-26 11:22                       ` Brantley Coile
  1 sibling, 1 reply; 40+ messages in thread
From: Bakul Shah @ 2015-11-26  7:27 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 9835 bytes --]

Using 0xfff...f instead of 0 for a null ptr might've been less "disgusting"! 

> On Nov 25, 2015, at 6:04 PM, Prof Brucee <prof.brucee@gmail.com> wrote:
> 
> gcc is indeed a very sad tome. The mmap of 0 is disgusting. I like kenc. It just works. My behaviour this afternoon will be undefined but not as stupid as that of some programmers.
> 
>> On 26/11/2015 5:43 AM, "Brantley Coile" <brantleycoile@me.com> wrote:
>> Align it to column 7 and it looks like all the code I saw when I started. 
>> 
>> iPhone email
>> 
>>> On Nov 25, 2015, at 12:13 PM, Ryan Gonzalez <rymg19@gmail.com> wrote:
>>> 
>>> Neither! It's what happens when you run sed 's/^\s*//' on your whole code base, yielding results like (from cmd/yacc.c):
>>> 
>>> 
>>> void
>>> setup(int argc, char *argv[])
>>> {
>>> long c, t;
>>> int i, j, fd, lev, ty, ytab, *p;
>>> int vflag, dflag, stem;
>>> char actnm[8], *stemc, *s, dirbuf[128];
>>> Biobuf *fout;
>>> 
>>> ytab = 0;
>>> vflag = 0;
>>> dflag = 0;
>>> stem = 0;
>>> stemc = "y";
>>> foutput = 0;
>>> fdefine = 0;
>>> fdebug = 0;
>>> ARGBEGIN{
>>> case 'v':
>>> case 'V':
>>> vflag++;
>>> break;
>>> case 'D':
>>> yydebug = ARGF();
>>> break;
>>> case 'a':
>>> yyarg = 1;
>>> break;
>>> case 'd':
>>> dflag++;
>>> break;
>>> case 'l':
>>> yyline = 0;
>>> break;
>>> case 'o':
>>> ytab++;
>>> ytabc = ARGF();
>>> break;
>>> case 's':
>>> stem++;
>>> stemc = ARGF();
>>> break;
>>> case 'S':
>>> parser = PARSERS;
>>> break;
>>> default:
>>> error("illegal option: %c", ARGC());
>>> }ARGEND
>>> openup(stemc, dflag, vflag, ytab, ytabc);
>>> fout = dflag?fdefine:ftable;
>>> if(yyarg){
>>> Bprint(ftable, "#define\tYYARG\t1\n\n");
>>> }
>>> if((fd = mkstemp(ttempname)) >= 0){
>>> tempname = ttempname;
>>> ftemp = Bfdopen(fd, OWRITE);
>>> }
>>> if((fd = mkstemp(tactname)) >= 0){
>>> actname = tactname;
>>> faction = Bfdopen(fd, OWRITE);
>>> }
>>> if(ftemp == 0 || faction == 0)
>>> error("cannot open temp file");
>>> if(argc < 1)
>>> error("no input file");
>>> infile = argv[0];
>>> if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
>>> i = strlen(infile)+1+strlen(dirbuf)+1+10;
>>> s = malloc(i);
>>> if(s != nil){
>>> snprint(s, i, "%s/%s", dirbuf, infile);
>>> cleanname(s);
>>> infile = s;
>>> }
>>> }
>>> finput = Bopen(infile, OREAD);
>>> if(finput == 0)
>>> error("cannot open '%s'", argv[0]);
>>> cnamp = cnames;
>>> 
>>> defin(0, "$end");
>>> extval = PRIVATE;	/* tokens start in unicode 'private use' */
>>> defin(0, "error");
>>> defin(1, "$accept");
>>> defin(0, "$unk");
>>> mem = mem0;
>>> i = 0;
>>> 
>>> for(t = gettok(); t != MARK && t != ENDFILE;)
>>> switch(t) {
>>> case ';':
>>> t = gettok();
>>> break;
>>> 
>>> case START:
>>> if(gettok() != IDENTIFIER)
>>> error("bad %%start construction");
>>> start = chfind(1, tokname);
>>> t = gettok();
>>> continue;
>>> 
>>> case TYPEDEF:
>>> if(gettok() != TYPENAME)
>>> error("bad syntax in %%type");
>>> ty = numbval;
>>> for(;;) {
>>> t = gettok();
>>> switch(t) {
>>> case IDENTIFIER:
>>> if((t=chfind(1, tokname)) < NTBASE) {
>>> j = TYPE(toklev[t]);
>>> if(j != 0 && j != ty)
>>> error("type redeclaration of token %s",
>>> tokset[t].name);
>>> else
>>> SETTYPE(toklev[t], ty);
>>> } else {
>>> j = nontrst[t-NTBASE].value;
>>> if(j != 0 && j != ty)
>>> error("type redeclaration of nonterminal %s",
>>> nontrst[t-NTBASE].name );
>>> else
>>> nontrst[t-NTBASE].value = ty;
>>> }
>>> case ',':
>>> continue;
>>> case ';':
>>> t = gettok();
>>> default:
>>> break;
>>> }
>>> break;
>>> }
>>> continue;
>>> 
>>> case UNION:
>>> /* copy the union declaration to the output */
>>> cpyunion();
>>> t = gettok();
>>> continue;
>>> 
>>> case LEFT:
>>> case BINARY:
>>> case RIGHT:
>>> i++;
>>> 
>>> case TERM:
>>> /* nonzero means new prec. and assoc. */
>>> lev = t-TERM;
>>> ty = 0;
>>> 
>>> /* get identifiers so defined */
>>> t = gettok();
>>> 
>>> /* there is a type defined */
>>> if(t == TYPENAME) {
>>> ty = numbval;
>>> t = gettok();
>>> }
>>> for(;;) {
>>> switch(t) {
>>> case ',':
>>> t = gettok();
>>> continue;
>>> 
>>> case ';':
>>> break;
>>> 
>>> case IDENTIFIER:
>>> j = chfind(0, tokname);
>>> if(j >= NTBASE)
>>> error("%s defined earlier as nonterminal", tokname);
>>> if(lev) {
>>> if(ASSOC(toklev[j]))
>>> error("redeclaration of precedence of %s", tokname);
>>> SETASC(toklev[j], lev);
>>> SETPLEV(toklev[j], i);
>>> }
>>> if(ty) {
>>> if(TYPE(toklev[j]))
>>> error("redeclaration of type of %s", tokname);
>>> SETTYPE(toklev[j],ty);
>>> }
>>> t = gettok();
>>> if(t == NUMBER) {
>>> tokset[j].value = numbval;
>>> if(j < ndefout && j > 3)
>>> error("please define type number of %s earlier",
>>> tokset[j].name);
>>> t = gettok();
>>> }
>>> continue;
>>> }
>>> break;
>>> }
>>> continue;
>>> 
>>> case LCURLY:
>>> defout(0);
>>> cpycode();
>>> t = gettok();
>>> continue;
>>> 
>>> default:
>>> error("syntax error");
>>> }
>>> if(t == ENDFILE)
>>> error("unexpected EOF before %%");
>>> 
>>> /* t is MARK */
>>> if(!yyarg)
>>> Bprint(ftable, "extern	int	yyerrflag;\n");
>>> Bprint(ftable, "#ifndef	YYMAXDEPTH\n");
>>> Bprint(ftable, "#define	YYMAXDEPTH	150\n");
>>> Bprint(ftable, "#endif\n" );
>>> if(!ntypes) {
>>> Bprint(ftable, "#ifndef	YYSTYPE\n");
>>> Bprint(ftable, "#define	YYSTYPE	int\n");
>>> Bprint(ftable, "#endif\n");
>>> }
>>> if(!yyarg){
>>> Bprint(ftable, "YYSTYPE	yylval;\n");
>>> Bprint(ftable, "YYSTYPE	yyval;\n");
>>> }else{
>>> if(dflag)
>>> Bprint(ftable, "#include \"%s.%s\"\n\n", stemc, FILED);
>>> Bprint(fout, "struct Yyarg {\n");
>>> Bprint(fout, "\tint\tyynerrs;\n");
>>> Bprint(fout, "\tint\tyyerrflag;\n");
>>> Bprint(fout, "\tvoid*\targ;\n");
>>> Bprint(fout, "\tYYSTYPE\tyyval;\n");
>>> Bprint(fout, "\tYYSTYPE\tyylval;\n");
>>> Bprint(fout, "};\n\n");
>>> }
>>> prdptr[0] = mem;
>>> 
>>> /* added production */
>>> *mem++ = NTBASE;
>>> 
>>> /* if start is 0, we will overwrite with the lhs of the first rule */
>>> *mem++ = start;
>>> *mem++ = 1;
>>> *mem++ = 0;
>>> prdptr[1] = mem;
>>> while((t=gettok()) == LCURLY)
>>> cpycode();
>>> if(t != IDENTCOLON)
>>> error("bad syntax on first rule");
>>> 
>>> if(!start)
>>> prdptr[0][1] = chfind(1, tokname);
>>> 
>>> /* read rules */
>>> while(t != MARK && t != ENDFILE) {
>>> /* process a rule */
>>> rlines[nprod] = lineno;
>>> if(t == '|')
>>> *mem++ = *prdptr[nprod-1];
>>> else
>>> if(t == IDENTCOLON) {
>>> *mem = chfind(1, tokname);
>>> if(*mem < NTBASE)
>>> error("token illegal on LHS of grammar rule");
>>> mem++;
>>> } else
>>> error("illegal rule: missing semicolon or | ?");
>>> /* read rule body */
>>> t = gettok();
>>> 
>>> more_rule:
>>> while(t == IDENTIFIER) {
>>> *mem = chfind(1, tokname);
>>> if(*mem < NTBASE)
>>> levprd[nprod] = toklev[*mem];
>>> mem++;
>>> t = gettok();
>>> }
>>> if(t == PREC) {
>>> if(gettok() != IDENTIFIER)
>>> error("illegal %%prec syntax");
>>> j = chfind(2, tokname);
>>> if(j >= NTBASE)
>>> error("nonterminal %s illegal after %%prec",
>>> nontrst[j-NTBASE].name);
>>> levprd[nprod] = toklev[j];
>>> t = gettok();
>>> }
>>> if(t == '=') {
>>> levprd[nprod] |= ACTFLAG;
>>> Bprint(faction, "\ncase %d:", nprod);
>>> cpyact(mem-prdptr[nprod]-1);
>>> Bprint(faction, " break;");
>>> if((t=gettok()) == IDENTIFIER) {
>>> 
>>> /* action within rule... */
>>> sprint(actnm, "$$%d", nprod);
>>> 
>>> /* make it a nonterminal */
>>> j = chfind(1, actnm);
>>> 
>>> /*
>>> * the current rule will become rule number nprod+1
>>> * move the contents down, and make room for the null
>>> */
>>> for(p = mem; p >= prdptr[nprod]; --p)
>>> p[2] = *p;
>>> mem += 2;
>>> 
>>> /* enter null production for action */
>>> p = prdptr[nprod];
>>> *p++ = j;
>>> *p++ = -nprod;
>>> 
>>> /* update the production information */
>>> levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
>>> levprd[nprod] = ACTFLAG;
>>> if(++nprod >= NPROD)
>>> error("more than %d rules", NPROD);
>>> prdptr[nprod] = p;
>>> 
>>> /* make the action appear in the original rule */
>>> *mem++ = j;
>>> 
>>> /* get some more of the rule */
>>> goto more_rule;
>>> }
>>> }
>>> 
>>> while(t == ';')
>>> t = gettok();
>>> *mem++ = -nprod;
>>> 
>>> /* check that default action is reasonable */
>>> if(ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].value) {
>>> 
>>> /* no explicit action, LHS has value */
>>> int tempty;
>>> 
>>> tempty = prdptr[nprod][1];
>>> if(tempty < 0)
>>> error("must return a value, since LHS has a type");
>>> else
>>> if(tempty >= NTBASE)
>>> tempty = nontrst[tempty-NTBASE].value;
>>> else
>>> tempty = TYPE(toklev[tempty]);
>>> if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
>>> error("default action causes potential type clash");
>>> }
>>> nprod++;
>>> if(nprod >= NPROD)
>>> error("more than %d rules", NPROD);
>>> prdptr[nprod] = mem;
>>> levprd[nprod] = 0;
>>> }
>>> 
>>> /* end of all rules */
>>> defout(1);
>>> 
>>> finact();
>>> if(t == MARK) {
>>> Bprint(ftable, "\n");
>>> if(yyline)
>>> Bprint(ftable, "#line\t%d\t\"%s\"\n", lineno, infile);
>>> while((c=Bgetrune(finput)) != Beof)
>>> Bputrune(ftable, c);
>>> }
>>> Bterm(finput);
>>> }
>>> 
>>> 
>>>> On Wed, Nov 25, 2015 at 10:03 AM, <plannine@sigint.cs.purdue.edu> wrote:
>>>> On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
>>>> > unindented consequences
>>>> 
>>>> Is that a class of Python bugs or an awesome name for a Nerdcore band?
>>> 
>>> 
>>> 
>>> -- 
>>> Ryan
>>> [ERROR]: Your autotools build scripts are 200 lines longer than your program. Something’s wrong.
>>> http://kirbyfan64.github.io/

[-- Attachment #2: Type: text/html, Size: 13694 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26  7:27                     ` Bakul Shah
@ 2015-11-26 11:22                       ` Brantley Coile
  2015-11-26 11:37                         ` tlaronde
                                           ` (3 more replies)
  0 siblings, 4 replies; 40+ messages in thread
From: Brantley Coile @ 2015-11-26 11:22 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 10799 bytes --]

Hi Bakul.  Long time since our Bay Area plan 9 hacking sessions. I've avoided the valley all together for a year and a half now. Not quite long enough yet. 

I thought the same thing, using ~0 for nil, but realized two things. First, that's a valid address on the PDP11 where the convention developed. It's the unibus space. Second, ~0 + member offest is still in page zero. 

By the way, are there any structs more than 4K in Linux? Are there any in plan 9?

Sent from my iPad

> On Nov 26, 2015, at 2:27 AM, Bakul Shah <bakul@bitblocks.com> wrote:
> 
> Using 0xfff...f instead of 0 for a null ptr might've been less "disgusting"! 
> 
>> On Nov 25, 2015, at 6:04 PM, Prof Brucee <prof.brucee@gmail.com> wrote:
>> 
>> gcc is indeed a very sad tome. The mmap of 0 is disgusting. I like kenc. It just works. My behaviour this afternoon will be undefined but not as stupid as that of some programmers.
>> 
>>> On 26/11/2015 5:43 AM, "Brantley Coile" <brantleycoile@me.com> wrote:
>>> Align it to column 7 and it looks like all the code I saw when I started. 
>>> 
>>> iPhone email
>>> 
>>>> On Nov 25, 2015, at 12:13 PM, Ryan Gonzalez <rymg19@gmail.com> wrote:
>>>> 
>>>> Neither! It's what happens when you run sed 's/^\s*//' on your whole code base, yielding results like (from cmd/yacc.c):
>>>> 
>>>> 
>>>> void
>>>> setup(int argc, char *argv[])
>>>> {
>>>> long c, t;
>>>> int i, j, fd, lev, ty, ytab, *p;
>>>> int vflag, dflag, stem;
>>>> char actnm[8], *stemc, *s, dirbuf[128];
>>>> Biobuf *fout;
>>>> 
>>>> ytab = 0;
>>>> vflag = 0;
>>>> dflag = 0;
>>>> stem = 0;
>>>> stemc = "y";
>>>> foutput = 0;
>>>> fdefine = 0;
>>>> fdebug = 0;
>>>> ARGBEGIN{
>>>> case 'v':
>>>> case 'V':
>>>> vflag++;
>>>> break;
>>>> case 'D':
>>>> yydebug = ARGF();
>>>> break;
>>>> case 'a':
>>>> yyarg = 1;
>>>> break;
>>>> case 'd':
>>>> dflag++;
>>>> break;
>>>> case 'l':
>>>> yyline = 0;
>>>> break;
>>>> case 'o':
>>>> ytab++;
>>>> ytabc = ARGF();
>>>> break;
>>>> case 's':
>>>> stem++;
>>>> stemc = ARGF();
>>>> break;
>>>> case 'S':
>>>> parser = PARSERS;
>>>> break;
>>>> default:
>>>> error("illegal option: %c", ARGC());
>>>> }ARGEND
>>>> openup(stemc, dflag, vflag, ytab, ytabc);
>>>> fout = dflag?fdefine:ftable;
>>>> if(yyarg){
>>>> Bprint(ftable, "#define\tYYARG\t1\n\n");
>>>> }
>>>> if((fd = mkstemp(ttempname)) >= 0){
>>>> tempname = ttempname;
>>>> ftemp = Bfdopen(fd, OWRITE);
>>>> }
>>>> if((fd = mkstemp(tactname)) >= 0){
>>>> actname = tactname;
>>>> faction = Bfdopen(fd, OWRITE);
>>>> }
>>>> if(ftemp == 0 || faction == 0)
>>>> error("cannot open temp file");
>>>> if(argc < 1)
>>>> error("no input file");
>>>> infile = argv[0];
>>>> if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
>>>> i = strlen(infile)+1+strlen(dirbuf)+1+10;
>>>> s = malloc(i);
>>>> if(s != nil){
>>>> snprint(s, i, "%s/%s", dirbuf, infile);
>>>> cleanname(s);
>>>> infile = s;
>>>> }
>>>> }
>>>> finput = Bopen(infile, OREAD);
>>>> if(finput == 0)
>>>> error("cannot open '%s'", argv[0]);
>>>> cnamp = cnames;
>>>> 
>>>> defin(0, "$end");
>>>> extval = PRIVATE;	/* tokens start in unicode 'private use' */
>>>> defin(0, "error");
>>>> defin(1, "$accept");
>>>> defin(0, "$unk");
>>>> mem = mem0;
>>>> i = 0;
>>>> 
>>>> for(t = gettok(); t != MARK && t != ENDFILE;)
>>>> switch(t) {
>>>> case ';':
>>>> t = gettok();
>>>> break;
>>>> 
>>>> case START:
>>>> if(gettok() != IDENTIFIER)
>>>> error("bad %%start construction");
>>>> start = chfind(1, tokname);
>>>> t = gettok();
>>>> continue;
>>>> 
>>>> case TYPEDEF:
>>>> if(gettok() != TYPENAME)
>>>> error("bad syntax in %%type");
>>>> ty = numbval;
>>>> for(;;) {
>>>> t = gettok();
>>>> switch(t) {
>>>> case IDENTIFIER:
>>>> if((t=chfind(1, tokname)) < NTBASE) {
>>>> j = TYPE(toklev[t]);
>>>> if(j != 0 && j != ty)
>>>> error("type redeclaration of token %s",
>>>> tokset[t].name);
>>>> else
>>>> SETTYPE(toklev[t], ty);
>>>> } else {
>>>> j = nontrst[t-NTBASE].value;
>>>> if(j != 0 && j != ty)
>>>> error("type redeclaration of nonterminal %s",
>>>> nontrst[t-NTBASE].name );
>>>> else
>>>> nontrst[t-NTBASE].value = ty;
>>>> }
>>>> case ',':
>>>> continue;
>>>> case ';':
>>>> t = gettok();
>>>> default:
>>>> break;
>>>> }
>>>> break;
>>>> }
>>>> continue;
>>>> 
>>>> case UNION:
>>>> /* copy the union declaration to the output */
>>>> cpyunion();
>>>> t = gettok();
>>>> continue;
>>>> 
>>>> case LEFT:
>>>> case BINARY:
>>>> case RIGHT:
>>>> i++;
>>>> 
>>>> case TERM:
>>>> /* nonzero means new prec. and assoc. */
>>>> lev = t-TERM;
>>>> ty = 0;
>>>> 
>>>> /* get identifiers so defined */
>>>> t = gettok();
>>>> 
>>>> /* there is a type defined */
>>>> if(t == TYPENAME) {
>>>> ty = numbval;
>>>> t = gettok();
>>>> }
>>>> for(;;) {
>>>> switch(t) {
>>>> case ',':
>>>> t = gettok();
>>>> continue;
>>>> 
>>>> case ';':
>>>> break;
>>>> 
>>>> case IDENTIFIER:
>>>> j = chfind(0, tokname);
>>>> if(j >= NTBASE)
>>>> error("%s defined earlier as nonterminal", tokname);
>>>> if(lev) {
>>>> if(ASSOC(toklev[j]))
>>>> error("redeclaration of precedence of %s", tokname);
>>>> SETASC(toklev[j], lev);
>>>> SETPLEV(toklev[j], i);
>>>> }
>>>> if(ty) {
>>>> if(TYPE(toklev[j]))
>>>> error("redeclaration of type of %s", tokname);
>>>> SETTYPE(toklev[j],ty);
>>>> }
>>>> t = gettok();
>>>> if(t == NUMBER) {
>>>> tokset[j].value = numbval;
>>>> if(j < ndefout && j > 3)
>>>> error("please define type number of %s earlier",
>>>> tokset[j].name);
>>>> t = gettok();
>>>> }
>>>> continue;
>>>> }
>>>> break;
>>>> }
>>>> continue;
>>>> 
>>>> case LCURLY:
>>>> defout(0);
>>>> cpycode();
>>>> t = gettok();
>>>> continue;
>>>> 
>>>> default:
>>>> error("syntax error");
>>>> }
>>>> if(t == ENDFILE)
>>>> error("unexpected EOF before %%");
>>>> 
>>>> /* t is MARK */
>>>> if(!yyarg)
>>>> Bprint(ftable, "extern	int	yyerrflag;\n");
>>>> Bprint(ftable, "#ifndef	YYMAXDEPTH\n");
>>>> Bprint(ftable, "#define	YYMAXDEPTH	150\n");
>>>> Bprint(ftable, "#endif\n" );
>>>> if(!ntypes) {
>>>> Bprint(ftable, "#ifndef	YYSTYPE\n");
>>>> Bprint(ftable, "#define	YYSTYPE	int\n");
>>>> Bprint(ftable, "#endif\n");
>>>> }
>>>> if(!yyarg){
>>>> Bprint(ftable, "YYSTYPE	yylval;\n");
>>>> Bprint(ftable, "YYSTYPE	yyval;\n");
>>>> }else{
>>>> if(dflag)
>>>> Bprint(ftable, "#include \"%s.%s\"\n\n", stemc, FILED);
>>>> Bprint(fout, "struct Yyarg {\n");
>>>> Bprint(fout, "\tint\tyynerrs;\n");
>>>> Bprint(fout, "\tint\tyyerrflag;\n");
>>>> Bprint(fout, "\tvoid*\targ;\n");
>>>> Bprint(fout, "\tYYSTYPE\tyyval;\n");
>>>> Bprint(fout, "\tYYSTYPE\tyylval;\n");
>>>> Bprint(fout, "};\n\n");
>>>> }
>>>> prdptr[0] = mem;
>>>> 
>>>> /* added production */
>>>> *mem++ = NTBASE;
>>>> 
>>>> /* if start is 0, we will overwrite with the lhs of the first rule */
>>>> *mem++ = start;
>>>> *mem++ = 1;
>>>> *mem++ = 0;
>>>> prdptr[1] = mem;
>>>> while((t=gettok()) == LCURLY)
>>>> cpycode();
>>>> if(t != IDENTCOLON)
>>>> error("bad syntax on first rule");
>>>> 
>>>> if(!start)
>>>> prdptr[0][1] = chfind(1, tokname);
>>>> 
>>>> /* read rules */
>>>> while(t != MARK && t != ENDFILE) {
>>>> /* process a rule */
>>>> rlines[nprod] = lineno;
>>>> if(t == '|')
>>>> *mem++ = *prdptr[nprod-1];
>>>> else
>>>> if(t == IDENTCOLON) {
>>>> *mem = chfind(1, tokname);
>>>> if(*mem < NTBASE)
>>>> error("token illegal on LHS of grammar rule");
>>>> mem++;
>>>> } else
>>>> error("illegal rule: missing semicolon or | ?");
>>>> /* read rule body */
>>>> t = gettok();
>>>> 
>>>> more_rule:
>>>> while(t == IDENTIFIER) {
>>>> *mem = chfind(1, tokname);
>>>> if(*mem < NTBASE)
>>>> levprd[nprod] = toklev[*mem];
>>>> mem++;
>>>> t = gettok();
>>>> }
>>>> if(t == PREC) {
>>>> if(gettok() != IDENTIFIER)
>>>> error("illegal %%prec syntax");
>>>> j = chfind(2, tokname);
>>>> if(j >= NTBASE)
>>>> error("nonterminal %s illegal after %%prec",
>>>> nontrst[j-NTBASE].name);
>>>> levprd[nprod] = toklev[j];
>>>> t = gettok();
>>>> }
>>>> if(t == '=') {
>>>> levprd[nprod] |= ACTFLAG;
>>>> Bprint(faction, "\ncase %d:", nprod);
>>>> cpyact(mem-prdptr[nprod]-1);
>>>> Bprint(faction, " break;");
>>>> if((t=gettok()) == IDENTIFIER) {
>>>> 
>>>> /* action within rule... */
>>>> sprint(actnm, "$$%d", nprod);
>>>> 
>>>> /* make it a nonterminal */
>>>> j = chfind(1, actnm);
>>>> 
>>>> /*
>>>> * the current rule will become rule number nprod+1
>>>> * move the contents down, and make room for the null
>>>> */
>>>> for(p = mem; p >= prdptr[nprod]; --p)
>>>> p[2] = *p;
>>>> mem += 2;
>>>> 
>>>> /* enter null production for action */
>>>> p = prdptr[nprod];
>>>> *p++ = j;
>>>> *p++ = -nprod;
>>>> 
>>>> /* update the production information */
>>>> levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
>>>> levprd[nprod] = ACTFLAG;
>>>> if(++nprod >= NPROD)
>>>> error("more than %d rules", NPROD);
>>>> prdptr[nprod] = p;
>>>> 
>>>> /* make the action appear in the original rule */
>>>> *mem++ = j;
>>>> 
>>>> /* get some more of the rule */
>>>> goto more_rule;
>>>> }
>>>> }
>>>> 
>>>> while(t == ';')
>>>> t = gettok();
>>>> *mem++ = -nprod;
>>>> 
>>>> /* check that default action is reasonable */
>>>> if(ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].value) {
>>>> 
>>>> /* no explicit action, LHS has value */
>>>> int tempty;
>>>> 
>>>> tempty = prdptr[nprod][1];
>>>> if(tempty < 0)
>>>> error("must return a value, since LHS has a type");
>>>> else
>>>> if(tempty >= NTBASE)
>>>> tempty = nontrst[tempty-NTBASE].value;
>>>> else
>>>> tempty = TYPE(toklev[tempty]);
>>>> if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
>>>> error("default action causes potential type clash");
>>>> }
>>>> nprod++;
>>>> if(nprod >= NPROD)
>>>> error("more than %d rules", NPROD);
>>>> prdptr[nprod] = mem;
>>>> levprd[nprod] = 0;
>>>> }
>>>> 
>>>> /* end of all rules */
>>>> defout(1);
>>>> 
>>>> finact();
>>>> if(t == MARK) {
>>>> Bprint(ftable, "\n");
>>>> if(yyline)
>>>> Bprint(ftable, "#line\t%d\t\"%s\"\n", lineno, infile);
>>>> while((c=Bgetrune(finput)) != Beof)
>>>> Bputrune(ftable, c);
>>>> }
>>>> Bterm(finput);
>>>> }
>>>> 
>>>> 
>>>>> On Wed, Nov 25, 2015 at 10:03 AM, <plannine@sigint.cs.purdue.edu> wrote:
>>>>> On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
>>>>> > unindented consequences
>>>>> 
>>>>> Is that a class of Python bugs or an awesome name for a Nerdcore band?
>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> Ryan
>>>> [ERROR]: Your autotools build scripts are 200 lines longer than your program. Something’s wrong.
>>>> http://kirbyfan64.github.io/

[-- Attachment #2: Type: text/html, Size: 14600 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 11:22                       ` Brantley Coile
@ 2015-11-26 11:37                         ` tlaronde
  2015-11-26 11:55                           ` Charles Forsyth
  2015-11-26 11:38                         ` Bruce Ellis
                                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 40+ messages in thread
From: tlaronde @ 2015-11-26 11:37 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

On Thu, Nov 26, 2015 at 06:22:45AM -0500, Brantley Coile wrote:
>
> I thought the same thing, using ~0 for nil, but realized two things. First, that's a valid address on the PDP11 where the convention developed. It's the unibus space. Second, ~0 + member offest is still in page zero.
>

Plus, in C, 0 is used as a truth value for false...

As long as no logical type was added but values used as logical values,
the choice of 0 for "false" address is "logical" enough...
--
        Thierry Laronde <tlaronde +AT+ polynum +dot+ com>
                     http://www.kergis.com/
                     http://www.arts-po.fr/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 11:22                       ` Brantley Coile
  2015-11-26 11:37                         ` tlaronde
@ 2015-11-26 11:38                         ` Bruce Ellis
  2015-11-26 16:31                         ` erik quanstrom
  2015-11-26 17:48                         ` Bakul Shah
  3 siblings, 0 replies; 40+ messages in thread
From: Bruce Ellis @ 2015-11-26 11:38 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 10307 bytes --]

Simple data share in Inferno. Define a struct with a single byte in it.

Now with b == nil throw in a b.data = 42. Visible channel to every process.

This requires 0xF zillion to be writeable.

On 26 November 2015 at 22:22, Brantley Coile <brantleycoile@me.com> wrote:

> Hi Bakul.  Long time since our Bay Area plan 9 hacking sessions. I've
> avoided the valley all together for a year and a half now. Not quite long
> enough yet.
>
> I thought the same thing, using ~0 for nil, but realized two things.
> First, that's a valid address on the PDP11 where the convention developed.
> It's the unibus space. Second, ~0 + member offest is still in page zero.
>
> By the way, are there any structs more than 4K in Linux? Are there any in
> plan 9?
>
> Sent from my iPad
>
> On Nov 26, 2015, at 2:27 AM, Bakul Shah <bakul@bitblocks.com> wrote:
>
> Using 0xfff...f instead of 0 for a null ptr might've been less
> "disgusting"!
>
> On Nov 25, 2015, at 6:04 PM, Prof Brucee <prof.brucee@gmail.com> wrote:
>
> gcc is indeed a very sad tome. The mmap of 0 is disgusting. I like kenc.
> It just works. My behaviour this afternoon will be undefined but not as
> stupid as that of some programmers.
> On 26/11/2015 5:43 AM, "Brantley Coile" <brantleycoile@me.com> wrote:
>
>> Align it to column 7 and it looks like all the code I saw when I started.
>>
>> iPhone email
>>
>> On Nov 25, 2015, at 12:13 PM, Ryan Gonzalez <rymg19@gmail.com> wrote:
>>
>> Neither! It's what happens when you run sed 's/^\s*//' on your whole code
>> base, yielding results like (from cmd/yacc.c):
>>
>>
>> void
>> setup(int argc, char *argv[])
>> {
>> long c, t;
>> int i, j, fd, lev, ty, ytab, *p;
>> int vflag, dflag, stem;
>> char actnm[8], *stemc, *s, dirbuf[128];
>> Biobuf *fout;
>>
>> ytab = 0;
>> vflag = 0;
>> dflag = 0;
>> stem = 0;
>> stemc = "y";
>> foutput = 0;
>> fdefine = 0;
>> fdebug = 0;
>> ARGBEGIN{
>> case 'v':
>> case 'V':
>> vflag++;
>> break;
>> case 'D':
>> yydebug = ARGF();
>> break;
>> case 'a':
>> yyarg = 1;
>> break;
>> case 'd':
>> dflag++;
>> break;
>> case 'l':
>> yyline = 0;
>> break;
>> case 'o':
>> ytab++;
>> ytabc = ARGF();
>> break;
>> case 's':
>> stem++;
>> stemc = ARGF();
>> break;
>> case 'S':
>> parser = PARSERS;
>> break;
>> default:
>> error("illegal option: %c", ARGC());
>> }ARGEND
>> openup(stemc, dflag, vflag, ytab, ytabc);
>> fout = dflag?fdefine:ftable;
>> if(yyarg){
>> Bprint(ftable, "#define\tYYARG\t1\n\n");
>> }
>> if((fd = mkstemp(ttempname)) >= 0){
>> tempname = ttempname;
>> ftemp = Bfdopen(fd, OWRITE);
>> }
>> if((fd = mkstemp(tactname)) >= 0){
>> actname = tactname;
>> faction = Bfdopen(fd, OWRITE);
>> }
>> if(ftemp == 0 || faction == 0)
>> error("cannot open temp file");
>> if(argc < 1)
>> error("no input file");
>> infile = argv[0];
>> if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
>> i = strlen(infile)+1+strlen(dirbuf)+1+10;
>> s = malloc(i);
>> if(s != nil){
>> snprint(s, i, "%s/%s", dirbuf, infile);
>> cleanname(s);
>> infile = s;
>> }
>> }
>> finput = Bopen(infile, OREAD);
>> if(finput == 0)
>> error("cannot open '%s'", argv[0]);
>> cnamp = cnames;
>>
>> defin(0, "$end");
>> extval = PRIVATE; /* tokens start in unicode 'private use' */
>> defin(0, "error");
>> defin(1, "$accept");
>> defin(0, "$unk");
>> mem = mem0;
>> i = 0;
>>
>> for(t = gettok(); t != MARK && t != ENDFILE;)
>> switch(t) {
>> case ';':
>> t = gettok();
>> break;
>>
>> case START:
>> if(gettok() != IDENTIFIER)
>> error("bad %%start construction");
>> start = chfind(1, tokname);
>> t = gettok();
>> continue;
>>
>> case TYPEDEF:
>> if(gettok() != TYPENAME)
>> error("bad syntax in %%type");
>> ty = numbval;
>> for(;;) {
>> t = gettok();
>> switch(t) {
>> case IDENTIFIER:
>> if((t=chfind(1, tokname)) < NTBASE) {
>> j = TYPE(toklev[t]);
>> if(j != 0 && j != ty)
>> error("type redeclaration of token %s",
>> tokset[t].name);
>> else
>> SETTYPE(toklev[t], ty);
>> } else {
>> j = nontrst[t-NTBASE].value;
>> if(j != 0 && j != ty)
>> error("type redeclaration of nonterminal %s",
>> nontrst[t-NTBASE].name );
>> else
>> nontrst[t-NTBASE].value = ty;
>> }
>> case ',':
>> continue;
>> case ';':
>> t = gettok();
>> default:
>> break;
>> }
>> break;
>> }
>> continue;
>>
>> case UNION:
>> /* copy the union declaration to the output */
>> cpyunion();
>> t = gettok();
>> continue;
>>
>> case LEFT:
>> case BINARY:
>> case RIGHT:
>> i++;
>>
>> case TERM:
>> /* nonzero means new prec. and assoc. */
>> lev = t-TERM;
>> ty = 0;
>>
>> /* get identifiers so defined */
>> t = gettok();
>>
>> /* there is a type defined */
>> if(t == TYPENAME) {
>> ty = numbval;
>> t = gettok();
>> }
>> for(;;) {
>> switch(t) {
>> case ',':
>> t = gettok();
>> continue;
>>
>> case ';':
>> break;
>>
>> case IDENTIFIER:
>> j = chfind(0, tokname);
>> if(j >= NTBASE)
>> error("%s defined earlier as nonterminal", tokname);
>> if(lev) {
>> if(ASSOC(toklev[j]))
>> error("redeclaration of precedence of %s", tokname);
>> SETASC(toklev[j], lev);
>> SETPLEV(toklev[j], i);
>> }
>> if(ty) {
>> if(TYPE(toklev[j]))
>> error("redeclaration of type of %s", tokname);
>> SETTYPE(toklev[j],ty);
>> }
>> t = gettok();
>> if(t == NUMBER) {
>> tokset[j].value = numbval;
>> if(j < ndefout && j > 3)
>> error("please define type number of %s earlier",
>> tokset[j].name);
>> t = gettok();
>> }
>> continue;
>> }
>> break;
>> }
>> continue;
>>
>> case LCURLY:
>> defout(0);
>> cpycode();
>> t = gettok();
>> continue;
>>
>> default:
>> error("syntax error");
>> }
>> if(t == ENDFILE)
>> error("unexpected EOF before %%");
>>
>> /* t is MARK */
>> if(!yyarg)
>> Bprint(ftable, "extern int yyerrflag;\n");
>> Bprint(ftable, "#ifndef YYMAXDEPTH\n");
>> Bprint(ftable, "#define YYMAXDEPTH 150\n");
>> Bprint(ftable, "#endif\n" );
>> if(!ntypes) {
>> Bprint(ftable, "#ifndef YYSTYPE\n");
>> Bprint(ftable, "#define YYSTYPE int\n");
>> Bprint(ftable, "#endif\n");
>> }
>> if(!yyarg){
>> Bprint(ftable, "YYSTYPE yylval;\n");
>> Bprint(ftable, "YYSTYPE yyval;\n");
>> }else{
>> if(dflag)
>> Bprint(ftable, "#include \"%s.%s\"\n\n", stemc, FILED);
>> Bprint(fout, "struct Yyarg {\n");
>> Bprint(fout, "\tint\tyynerrs;\n");
>> Bprint(fout, "\tint\tyyerrflag;\n");
>> Bprint(fout, "\tvoid*\targ;\n");
>> Bprint(fout, "\tYYSTYPE\tyyval;\n");
>> Bprint(fout, "\tYYSTYPE\tyylval;\n");
>> Bprint(fout, "};\n\n");
>> }
>> prdptr[0] = mem;
>>
>> /* added production */
>> *mem++ = NTBASE;
>>
>> /* if start is 0, we will overwrite with the lhs of the first rule */
>> *mem++ = start;
>> *mem++ = 1;
>> *mem++ = 0;
>> prdptr[1] = mem;
>> while((t=gettok()) == LCURLY)
>> cpycode();
>> if(t != IDENTCOLON)
>> error("bad syntax on first rule");
>>
>> if(!start)
>> prdptr[0][1] = chfind(1, tokname);
>>
>> /* read rules */
>> while(t != MARK && t != ENDFILE) {
>> /* process a rule */
>> rlines[nprod] = lineno;
>> if(t == '|')
>> *mem++ = *prdptr[nprod-1];
>> else
>> if(t == IDENTCOLON) {
>> *mem = chfind(1, tokname);
>> if(*mem < NTBASE)
>> error("token illegal on LHS of grammar rule");
>> mem++;
>> } else
>> error("illegal rule: missing semicolon or | ?");
>> /* read rule body */
>> t = gettok();
>>
>> more_rule:
>> while(t == IDENTIFIER) {
>> *mem = chfind(1, tokname);
>> if(*mem < NTBASE)
>> levprd[nprod] = toklev[*mem];
>> mem++;
>> t = gettok();
>> }
>> if(t == PREC) {
>> if(gettok() != IDENTIFIER)
>> error("illegal %%prec syntax");
>> j = chfind(2, tokname);
>> if(j >= NTBASE)
>> error("nonterminal %s illegal after %%prec",
>> nontrst[j-NTBASE].name);
>> levprd[nprod] = toklev[j];
>> t = gettok();
>> }
>> if(t == '=') {
>> levprd[nprod] |= ACTFLAG;
>> Bprint(faction, "\ncase %d:", nprod);
>> cpyact(mem-prdptr[nprod]-1);
>> Bprint(faction, " break;");
>> if((t=gettok()) == IDENTIFIER) {
>>
>> /* action within rule... */
>> sprint(actnm, "$$%d", nprod);
>>
>> /* make it a nonterminal */
>> j = chfind(1, actnm);
>>
>> /*
>> * the current rule will become rule number nprod+1
>> * move the contents down, and make room for the null
>> */
>> for(p = mem; p >= prdptr[nprod]; --p)
>> p[2] = *p;
>> mem += 2;
>>
>> /* enter null production for action */
>> p = prdptr[nprod];
>> *p++ = j;
>> *p++ = -nprod;
>>
>> /* update the production information */
>> levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
>> levprd[nprod] = ACTFLAG;
>> if(++nprod >= NPROD)
>> error("more than %d rules", NPROD);
>> prdptr[nprod] = p;
>>
>> /* make the action appear in the original rule */
>> *mem++ = j;
>>
>> /* get some more of the rule */
>> goto more_rule;
>> }
>> }
>>
>> while(t == ';')
>> t = gettok();
>> *mem++ = -nprod;
>>
>> /* check that default action is reasonable */
>> if(ntypes && !(levprd[nprod]&ACTFLAG) &&
>> nontrst[*prdptr[nprod]-NTBASE].value) {
>>
>> /* no explicit action, LHS has value */
>> int tempty;
>>
>> tempty = prdptr[nprod][1];
>> if(tempty < 0)
>> error("must return a value, since LHS has a type");
>> else
>> if(tempty >= NTBASE)
>> tempty = nontrst[tempty-NTBASE].value;
>> else
>> tempty = TYPE(toklev[tempty]);
>> if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
>> error("default action causes potential type clash");
>> }
>> nprod++;
>> if(nprod >= NPROD)
>> error("more than %d rules", NPROD);
>> prdptr[nprod] = mem;
>> levprd[nprod] = 0;
>> }
>>
>> /* end of all rules */
>> defout(1);
>>
>> finact();
>> if(t == MARK) {
>> Bprint(ftable, "\n");
>> if(yyline)
>> Bprint(ftable, "#line\t%d\t\"%s\"\n", lineno, infile);
>> while((c=Bgetrune(finput)) != Beof)
>> Bputrune(ftable, c);
>> }
>> Bterm(finput);
>> }
>>
>>
>> On Wed, Nov 25, 2015 at 10:03 AM, <plannine@sigint.cs.purdue.edu> wrote:
>>
>>> On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
>>> > unindented consequences
>>>
>>> Is that a class of Python bugs or an awesome name for a Nerdcore band?
>>>
>>>
>>
>>
>> --
>> Ryan
>> [ERROR]: Your autotools build scripts are 200 lines longer than your
>> program. Something’s wrong.
>> http://kirbyfan64.github.io/
>>
>>
>>

[-- Attachment #2: Type: text/html, Size: 15760 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 11:37                         ` tlaronde
@ 2015-11-26 11:55                           ` Charles Forsyth
  0 siblings, 0 replies; 40+ messages in thread
From: Charles Forsyth @ 2015-11-26 11:55 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 477 bytes --]

On 26 November 2015 at 11:37, <tlaronde@polynum.com> wrote:

> Plus, in C, 0 is used as a truth value for false...
>

That doesn't say how a 0 value for a pointer is represented; it's just how
it's written in the program text.
The compiler knows the types and can convert (same as double = 0).

In practice, you can't change it because too much code assumes that mallocz
and memset(..., 0, ...) of structures
containing pointer values will initialise them to null.

[-- Attachment #2: Type: text/html, Size: 956 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 11:22                       ` Brantley Coile
  2015-11-26 11:37                         ` tlaronde
  2015-11-26 11:38                         ` Bruce Ellis
@ 2015-11-26 16:31                         ` erik quanstrom
  2015-11-26 16:42                           ` Brantley Coile
  2015-11-26 16:46                           ` Alexandru Gheorghe
  2015-11-26 17:48                         ` Bakul Shah
  3 siblings, 2 replies; 40+ messages in thread
From: erik quanstrom @ 2015-11-26 16:31 UTC (permalink / raw)
  To: 9fans

On Thu Nov 26 03:25:34 PST 2015, brantleycoile@me.com wrote:

> Hi Bakul.  Long time since our Bay Area plan 9 hacking sessions. I've avoided the valley all together for a year and a half now. Not quite long enough yet.
>
> I thought the same thing, using ~0 for nil, but realized two things. First, that's a valid address on the PDP11 where the convention developed. It's the unibus space. Second, ~0 + member offest is still in page zero.
>
> By the way, are there any structs more than 4K in Linux? Are there any in plan 9?

since that 4k is really pagesz, on amd64 that would be 2mb.  there's no compelling reason on
64-bit machines to start at the bottom instead of the middle.

the answer to the question is yes, yes there are.  by Biobufs are larger than the original, but
they are normally 8k.

; cd /sys/src/cmd
; grep sizeof `{find .|grep acid}|sed 's/;$//g'|awk '$NF ~ /^[0-9][0-9]*$/ && $NF>4096'
./8l/acid6:sizeofBiobuf = 8272
./8l/acid6:sizeof_4_ = 16384
./8l/acid6:sizeof_5_ = 16384
./acid/acid6:sizeofBiobuf = 8248
./aux/vga/acid6:sizeofBiobuf = 49232
./mk/acid:sizeofBiobuf = 8248
./stats.acid:sizeofAuthRpc = 8216
./stats.acid:sizeofEvent = 8368
./6l/acid6:sizeofBiobuf = 8272
./6l/acid6:sizeof_4_ = 16384
./6l/acid6:sizeof_5_ = 16384

this is not an exhaustive list.

- erik



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 16:31                         ` erik quanstrom
@ 2015-11-26 16:42                           ` Brantley Coile
  2015-11-26 16:50                             ` Charles Forsyth
  2015-11-26 16:46                           ` Alexandru Gheorghe
  1 sibling, 1 reply; 40+ messages in thread
From: Brantley Coile @ 2015-11-26 16:42 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

Thanks, Erik. And of those, how many don’t end with arrays or would not use earlier members to access those arrays? I’m still kind of dubious that there are any structures where one would not catch a null pointer.

Of course, this is not the original issue, which was someone fooling the kernel into doing something it might now have wanted to do.

> On Nov 26, 2015, at 11:31 AM, erik quanstrom <quanstro@quanstro.net> wrote:
> 
> On Thu Nov 26 03:25:34 PST 2015, brantleycoile@me.com wrote:
> 
>> Hi Bakul.  Long time since our Bay Area plan 9 hacking sessions. I've avoided the valley all together for a year and a half now. Not quite long enough yet. 
>> 
>> I thought the same thing, using ~0 for nil, but realized two things. First, that's a valid address on the PDP11 where the convention developed. It's the unibus space. Second, ~0 + member offest is still in page zero. 
>> 
>> By the way, are there any structs more than 4K in Linux? Are there any in plan 9?
> 
> since that 4k is really pagesz, on amd64 that would be 2mb.  there's no compelling reason on
> 64-bit machines to start at the bottom instead of the middle.
> 
> the answer to the question is yes, yes there are.  by Biobufs are larger than the original, but
> they are normally 8k.
> 
> ; cd /sys/src/cmd
> ; grep sizeof `{find .|grep acid}|sed 's/;$//g'|awk '$NF ~ /^[0-9][0-9]*$/ && $NF>4096'
> ./8l/acid6:sizeofBiobuf = 8272
> ./8l/acid6:sizeof_4_ = 16384
> ./8l/acid6:sizeof_5_ = 16384
> ./acid/acid6:sizeofBiobuf = 8248
> ./aux/vga/acid6:sizeofBiobuf = 49232
> ./mk/acid:sizeofBiobuf = 8248
> ./stats.acid:sizeofAuthRpc = 8216
> ./stats.acid:sizeofEvent = 8368
> ./6l/acid6:sizeofBiobuf = 8272
> ./6l/acid6:sizeof_4_ = 16384
> ./6l/acid6:sizeof_5_ = 16384
> 
> this is not an exhaustive list.
> 
> - erik
> 




^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 16:31                         ` erik quanstrom
  2015-11-26 16:42                           ` Brantley Coile
@ 2015-11-26 16:46                           ` Alexandru Gheorghe
  1 sibling, 0 replies; 40+ messages in thread
From: Alexandru Gheorghe @ 2015-11-26 16:46 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 593 bytes --]

On Nov 26, 2015 6:35 PM, "erik quanstrom" <quanstro@quanstro.net> wrote:

> > By the way, are there any structs more than 4K in Linux? Are there any
in plan 9?
>
> since that 4k is really pagesz, on amd64 that would be 2mb.  there's no
compelling reason on
> 64-bit machines to start at the bottom instead of the middle.

IIRC i think there was a special case with PAE as well so to speak for
Linux where 36-bit is used from CPU. I remember that in that case pud, pmd
and pgd are used but 0 page map is treated as a more kernel specific
implementation

Though i might be wrong.

[-- Attachment #2: Type: text/html, Size: 755 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 16:42                           ` Brantley Coile
@ 2015-11-26 16:50                             ` Charles Forsyth
  2015-11-26 17:12                               ` erik quanstrom
  0 siblings, 1 reply; 40+ messages in thread
From: Charles Forsyth @ 2015-11-26 16:50 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 355 bytes --]

On 26 November 2015 at 16:42, Brantley Coile <brantleycoile@me.com> wrote:

> I’m still kind of dubious that there are any structures where one would
> not catch a null pointer.
>

I don't think there are any. In practice, ome other value lower down will
be accessed first.
Unless the compiler introduces its own invisible erroneous behaviour.

[-- Attachment #2: Type: text/html, Size: 764 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 16:50                             ` Charles Forsyth
@ 2015-11-26 17:12                               ` erik quanstrom
  0 siblings, 0 replies; 40+ messages in thread
From: erik quanstrom @ 2015-11-26 17:12 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/html, Size: 1036 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 11:22                       ` Brantley Coile
                                           ` (2 preceding siblings ...)
  2015-11-26 16:31                         ` erik quanstrom
@ 2015-11-26 17:48                         ` Bakul Shah
  2015-11-26 18:04                           ` Brantley Coile
  2015-11-26 23:14                           ` Steve Simon
  3 siblings, 2 replies; 40+ messages in thread
From: Bakul Shah @ 2015-11-26 17:48 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 11833 bytes --]

Good points! Though 0 was a valid address on pdp11, right? May be if they had used ~0 as nil and not put any peripheral device at that address,  *nil would've had more immediate failures! Many ~0+offset errors would be caught on machines that trap 2 or 4 byte fetch/store to odd addresses.

I guess the real problem is that compilers don't generate tests to catch *nil (unless they can prove a ptr can't be nil). That + not generating bounds checks.

No comment on the Bay Area :-) Especially since we are trying to hire people!

> On Nov 26, 2015, at 3:22 AM, Brantley Coile <brantleycoile@me.com> wrote:
> 
> Hi Bakul.  Long time since our Bay Area plan 9 hacking sessions. I've avoided the valley all together for a year and a half now. Not quite long enough yet. 
> 
> I thought the same thing, using ~0 for nil, but realized two things. First, that's a valid address on the PDP11 where the convention developed. It's the unibus space. Second, ~0 + member offest is still in page zero. 
> 
> By the way, are there any structs more than 4K in Linux? Are there any in plan 9?
> 
> Sent from my iPad
> 
>> On Nov 26, 2015, at 2:27 AM, Bakul Shah <bakul@bitblocks.com> wrote:
>> 
>> Using 0xfff...f instead of 0 for a null ptr might've been less "disgusting"! 
>> 
>>> On Nov 25, 2015, at 6:04 PM, Prof Brucee <prof.brucee@gmail.com> wrote:
>>> 
>>> gcc is indeed a very sad tome. The mmap of 0 is disgusting. I like kenc. It just works. My behaviour this afternoon will be undefined but not as stupid as that of some programmers.
>>> 
>>>> On 26/11/2015 5:43 AM, "Brantley Coile" <brantleycoile@me.com> wrote:
>>>> Align it to column 7 and it looks like all the code I saw when I started. 
>>>> 
>>>> iPhone email
>>>> 
>>>>> On Nov 25, 2015, at 12:13 PM, Ryan Gonzalez <rymg19@gmail.com> wrote:
>>>>> 
>>>>> Neither! It's what happens when you run sed 's/^\s*//' on your whole code base, yielding results like (from cmd/yacc.c):
>>>>> 
>>>>> 
>>>>> void
>>>>> setup(int argc, char *argv[])
>>>>> {
>>>>> long c, t;
>>>>> int i, j, fd, lev, ty, ytab, *p;
>>>>> int vflag, dflag, stem;
>>>>> char actnm[8], *stemc, *s, dirbuf[128];
>>>>> Biobuf *fout;
>>>>> 
>>>>> ytab = 0;
>>>>> vflag = 0;
>>>>> dflag = 0;
>>>>> stem = 0;
>>>>> stemc = "y";
>>>>> foutput = 0;
>>>>> fdefine = 0;
>>>>> fdebug = 0;
>>>>> ARGBEGIN{
>>>>> case 'v':
>>>>> case 'V':
>>>>> vflag++;
>>>>> break;
>>>>> case 'D':
>>>>> yydebug = ARGF();
>>>>> break;
>>>>> case 'a':
>>>>> yyarg = 1;
>>>>> break;
>>>>> case 'd':
>>>>> dflag++;
>>>>> break;
>>>>> case 'l':
>>>>> yyline = 0;
>>>>> break;
>>>>> case 'o':
>>>>> ytab++;
>>>>> ytabc = ARGF();
>>>>> break;
>>>>> case 's':
>>>>> stem++;
>>>>> stemc = ARGF();
>>>>> break;
>>>>> case 'S':
>>>>> parser = PARSERS;
>>>>> break;
>>>>> default:
>>>>> error("illegal option: %c", ARGC());
>>>>> }ARGEND
>>>>> openup(stemc, dflag, vflag, ytab, ytabc);
>>>>> fout = dflag?fdefine:ftable;
>>>>> if(yyarg){
>>>>> Bprint(ftable, "#define\tYYARG\t1\n\n");
>>>>> }
>>>>> if((fd = mkstemp(ttempname)) >= 0){
>>>>> tempname = ttempname;
>>>>> ftemp = Bfdopen(fd, OWRITE);
>>>>> }
>>>>> if((fd = mkstemp(tactname)) >= 0){
>>>>> actname = tactname;
>>>>> faction = Bfdopen(fd, OWRITE);
>>>>> }
>>>>> if(ftemp == 0 || faction == 0)
>>>>> error("cannot open temp file");
>>>>> if(argc < 1)
>>>>> error("no input file");
>>>>> infile = argv[0];
>>>>> if(infile[0] != '/' && getwd(dirbuf, sizeof dirbuf)!=nil){
>>>>> i = strlen(infile)+1+strlen(dirbuf)+1+10;
>>>>> s = malloc(i);
>>>>> if(s != nil){
>>>>> snprint(s, i, "%s/%s", dirbuf, infile);
>>>>> cleanname(s);
>>>>> infile = s;
>>>>> }
>>>>> }
>>>>> finput = Bopen(infile, OREAD);
>>>>> if(finput == 0)
>>>>> error("cannot open '%s'", argv[0]);
>>>>> cnamp = cnames;
>>>>> 
>>>>> defin(0, "$end");
>>>>> extval = PRIVATE;	/* tokens start in unicode 'private use' */
>>>>> defin(0, "error");
>>>>> defin(1, "$accept");
>>>>> defin(0, "$unk");
>>>>> mem = mem0;
>>>>> i = 0;
>>>>> 
>>>>> for(t = gettok(); t != MARK && t != ENDFILE;)
>>>>> switch(t) {
>>>>> case ';':
>>>>> t = gettok();
>>>>> break;
>>>>> 
>>>>> case START:
>>>>> if(gettok() != IDENTIFIER)
>>>>> error("bad %%start construction");
>>>>> start = chfind(1, tokname);
>>>>> t = gettok();
>>>>> continue;
>>>>> 
>>>>> case TYPEDEF:
>>>>> if(gettok() != TYPENAME)
>>>>> error("bad syntax in %%type");
>>>>> ty = numbval;
>>>>> for(;;) {
>>>>> t = gettok();
>>>>> switch(t) {
>>>>> case IDENTIFIER:
>>>>> if((t=chfind(1, tokname)) < NTBASE) {
>>>>> j = TYPE(toklev[t]);
>>>>> if(j != 0 && j != ty)
>>>>> error("type redeclaration of token %s",
>>>>> tokset[t].name);
>>>>> else
>>>>> SETTYPE(toklev[t], ty);
>>>>> } else {
>>>>> j = nontrst[t-NTBASE].value;
>>>>> if(j != 0 && j != ty)
>>>>> error("type redeclaration of nonterminal %s",
>>>>> nontrst[t-NTBASE].name );
>>>>> else
>>>>> nontrst[t-NTBASE].value = ty;
>>>>> }
>>>>> case ',':
>>>>> continue;
>>>>> case ';':
>>>>> t = gettok();
>>>>> default:
>>>>> break;
>>>>> }
>>>>> break;
>>>>> }
>>>>> continue;
>>>>> 
>>>>> case UNION:
>>>>> /* copy the union declaration to the output */
>>>>> cpyunion();
>>>>> t = gettok();
>>>>> continue;
>>>>> 
>>>>> case LEFT:
>>>>> case BINARY:
>>>>> case RIGHT:
>>>>> i++;
>>>>> 
>>>>> case TERM:
>>>>> /* nonzero means new prec. and assoc. */
>>>>> lev = t-TERM;
>>>>> ty = 0;
>>>>> 
>>>>> /* get identifiers so defined */
>>>>> t = gettok();
>>>>> 
>>>>> /* there is a type defined */
>>>>> if(t == TYPENAME) {
>>>>> ty = numbval;
>>>>> t = gettok();
>>>>> }
>>>>> for(;;) {
>>>>> switch(t) {
>>>>> case ',':
>>>>> t = gettok();
>>>>> continue;
>>>>> 
>>>>> case ';':
>>>>> break;
>>>>> 
>>>>> case IDENTIFIER:
>>>>> j = chfind(0, tokname);
>>>>> if(j >= NTBASE)
>>>>> error("%s defined earlier as nonterminal", tokname);
>>>>> if(lev) {
>>>>> if(ASSOC(toklev[j]))
>>>>> error("redeclaration of precedence of %s", tokname);
>>>>> SETASC(toklev[j], lev);
>>>>> SETPLEV(toklev[j], i);
>>>>> }
>>>>> if(ty) {
>>>>> if(TYPE(toklev[j]))
>>>>> error("redeclaration of type of %s", tokname);
>>>>> SETTYPE(toklev[j],ty);
>>>>> }
>>>>> t = gettok();
>>>>> if(t == NUMBER) {
>>>>> tokset[j].value = numbval;
>>>>> if(j < ndefout && j > 3)
>>>>> error("please define type number of %s earlier",
>>>>> tokset[j].name);
>>>>> t = gettok();
>>>>> }
>>>>> continue;
>>>>> }
>>>>> break;
>>>>> }
>>>>> continue;
>>>>> 
>>>>> case LCURLY:
>>>>> defout(0);
>>>>> cpycode();
>>>>> t = gettok();
>>>>> continue;
>>>>> 
>>>>> default:
>>>>> error("syntax error");
>>>>> }
>>>>> if(t == ENDFILE)
>>>>> error("unexpected EOF before %%");
>>>>> 
>>>>> /* t is MARK */
>>>>> if(!yyarg)
>>>>> Bprint(ftable, "extern	int	yyerrflag;\n");
>>>>> Bprint(ftable, "#ifndef	YYMAXDEPTH\n");
>>>>> Bprint(ftable, "#define	YYMAXDEPTH	150\n");
>>>>> Bprint(ftable, "#endif\n" );
>>>>> if(!ntypes) {
>>>>> Bprint(ftable, "#ifndef	YYSTYPE\n");
>>>>> Bprint(ftable, "#define	YYSTYPE	int\n");
>>>>> Bprint(ftable, "#endif\n");
>>>>> }
>>>>> if(!yyarg){
>>>>> Bprint(ftable, "YYSTYPE	yylval;\n");
>>>>> Bprint(ftable, "YYSTYPE	yyval;\n");
>>>>> }else{
>>>>> if(dflag)
>>>>> Bprint(ftable, "#include \"%s.%s\"\n\n", stemc, FILED);
>>>>> Bprint(fout, "struct Yyarg {\n");
>>>>> Bprint(fout, "\tint\tyynerrs;\n");
>>>>> Bprint(fout, "\tint\tyyerrflag;\n");
>>>>> Bprint(fout, "\tvoid*\targ;\n");
>>>>> Bprint(fout, "\tYYSTYPE\tyyval;\n");
>>>>> Bprint(fout, "\tYYSTYPE\tyylval;\n");
>>>>> Bprint(fout, "};\n\n");
>>>>> }
>>>>> prdptr[0] = mem;
>>>>> 
>>>>> /* added production */
>>>>> *mem++ = NTBASE;
>>>>> 
>>>>> /* if start is 0, we will overwrite with the lhs of the first rule */
>>>>> *mem++ = start;
>>>>> *mem++ = 1;
>>>>> *mem++ = 0;
>>>>> prdptr[1] = mem;
>>>>> while((t=gettok()) == LCURLY)
>>>>> cpycode();
>>>>> if(t != IDENTCOLON)
>>>>> error("bad syntax on first rule");
>>>>> 
>>>>> if(!start)
>>>>> prdptr[0][1] = chfind(1, tokname);
>>>>> 
>>>>> /* read rules */
>>>>> while(t != MARK && t != ENDFILE) {
>>>>> /* process a rule */
>>>>> rlines[nprod] = lineno;
>>>>> if(t == '|')
>>>>> *mem++ = *prdptr[nprod-1];
>>>>> else
>>>>> if(t == IDENTCOLON) {
>>>>> *mem = chfind(1, tokname);
>>>>> if(*mem < NTBASE)
>>>>> error("token illegal on LHS of grammar rule");
>>>>> mem++;
>>>>> } else
>>>>> error("illegal rule: missing semicolon or | ?");
>>>>> /* read rule body */
>>>>> t = gettok();
>>>>> 
>>>>> more_rule:
>>>>> while(t == IDENTIFIER) {
>>>>> *mem = chfind(1, tokname);
>>>>> if(*mem < NTBASE)
>>>>> levprd[nprod] = toklev[*mem];
>>>>> mem++;
>>>>> t = gettok();
>>>>> }
>>>>> if(t == PREC) {
>>>>> if(gettok() != IDENTIFIER)
>>>>> error("illegal %%prec syntax");
>>>>> j = chfind(2, tokname);
>>>>> if(j >= NTBASE)
>>>>> error("nonterminal %s illegal after %%prec",
>>>>> nontrst[j-NTBASE].name);
>>>>> levprd[nprod] = toklev[j];
>>>>> t = gettok();
>>>>> }
>>>>> if(t == '=') {
>>>>> levprd[nprod] |= ACTFLAG;
>>>>> Bprint(faction, "\ncase %d:", nprod);
>>>>> cpyact(mem-prdptr[nprod]-1);
>>>>> Bprint(faction, " break;");
>>>>> if((t=gettok()) == IDENTIFIER) {
>>>>> 
>>>>> /* action within rule... */
>>>>> sprint(actnm, "$$%d", nprod);
>>>>> 
>>>>> /* make it a nonterminal */
>>>>> j = chfind(1, actnm);
>>>>> 
>>>>> /*
>>>>> * the current rule will become rule number nprod+1
>>>>> * move the contents down, and make room for the null
>>>>> */
>>>>> for(p = mem; p >= prdptr[nprod]; --p)
>>>>> p[2] = *p;
>>>>> mem += 2;
>>>>> 
>>>>> /* enter null production for action */
>>>>> p = prdptr[nprod];
>>>>> *p++ = j;
>>>>> *p++ = -nprod;
>>>>> 
>>>>> /* update the production information */
>>>>> levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
>>>>> levprd[nprod] = ACTFLAG;
>>>>> if(++nprod >= NPROD)
>>>>> error("more than %d rules", NPROD);
>>>>> prdptr[nprod] = p;
>>>>> 
>>>>> /* make the action appear in the original rule */
>>>>> *mem++ = j;
>>>>> 
>>>>> /* get some more of the rule */
>>>>> goto more_rule;
>>>>> }
>>>>> }
>>>>> 
>>>>> while(t == ';')
>>>>> t = gettok();
>>>>> *mem++ = -nprod;
>>>>> 
>>>>> /* check that default action is reasonable */
>>>>> if(ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].value) {
>>>>> 
>>>>> /* no explicit action, LHS has value */
>>>>> int tempty;
>>>>> 
>>>>> tempty = prdptr[nprod][1];
>>>>> if(tempty < 0)
>>>>> error("must return a value, since LHS has a type");
>>>>> else
>>>>> if(tempty >= NTBASE)
>>>>> tempty = nontrst[tempty-NTBASE].value;
>>>>> else
>>>>> tempty = TYPE(toklev[tempty]);
>>>>> if(tempty != nontrst[*prdptr[nprod]-NTBASE].value)
>>>>> error("default action causes potential type clash");
>>>>> }
>>>>> nprod++;
>>>>> if(nprod >= NPROD)
>>>>> error("more than %d rules", NPROD);
>>>>> prdptr[nprod] = mem;
>>>>> levprd[nprod] = 0;
>>>>> }
>>>>> 
>>>>> /* end of all rules */
>>>>> defout(1);
>>>>> 
>>>>> finact();
>>>>> if(t == MARK) {
>>>>> Bprint(ftable, "\n");
>>>>> if(yyline)
>>>>> Bprint(ftable, "#line\t%d\t\"%s\"\n", lineno, infile);
>>>>> while((c=Bgetrune(finput)) != Beof)
>>>>> Bputrune(ftable, c);
>>>>> }
>>>>> Bterm(finput);
>>>>> }
>>>>> 
>>>>> 
>>>>>> On Wed, Nov 25, 2015 at 10:03 AM, <plannine@sigint.cs.purdue.edu> wrote:
>>>>>> On Wed, Nov 25, 2015 at 09:25:55AM -0500, Brantley Coile wrote:
>>>>>> > unindented consequences
>>>>>> 
>>>>>> Is that a class of Python bugs or an awesome name for a Nerdcore band?
>>>>> 
>>>>> 
>>>>> 
>>>>> -- 
>>>>> Ryan
>>>>> [ERROR]: Your autotools build scripts are 200 lines longer than your program. Something’s wrong.
>>>>> http://kirbyfan64.github.io/

[-- Attachment #2: Type: text/html, Size: 15497 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 17:48                         ` Bakul Shah
@ 2015-11-26 18:04                           ` Brantley Coile
  2015-11-26 23:14                           ` Steve Simon
  1 sibling, 0 replies; 40+ messages in thread
From: Brantley Coile @ 2015-11-26 18:04 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 264 bytes --]

Hee hee.  My comment has more to do with personal experience than a judgment on the area in general.

> On Nov 26, 2015, at 12:48 PM, Bakul Shah <bakul@bitblocks.com> wrote:
> 
> No comment on the Bay Area :-) Especially since we are trying to hire people!


[-- Attachment #2: Type: text/html, Size: 1060 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 17:48                         ` Bakul Shah
  2015-11-26 18:04                           ` Brantley Coile
@ 2015-11-26 23:14                           ` Steve Simon
  2015-11-26 23:24                             ` Charles Forsyth
  2015-11-26 23:55                             ` Brantley Coile
  1 sibling, 2 replies; 40+ messages in thread
From: Steve Simon @ 2015-11-26 23:14 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 458 bytes --]


I don't know about the PDP but the VAX allowed access to address zero.

Even more insidious, it allowed you to dereference a null pointer and guaranteed it would contain a zero, which resulted in many tiresome portability issues - I used Interdatas at the time, which faulted on a read at address zero.

-Steve


> On 26 Nov 2015, at 17:48, Bakul Shah <bakul@bitblocks.com> wrote:
> 
> Good points! Though 0 was a valid address on pdp11, right? 

[-- Attachment #2: Type: text/html, Size: 1500 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 23:14                           ` Steve Simon
@ 2015-11-26 23:24                             ` Charles Forsyth
  2015-11-26 23:55                             ` Brantley Coile
  1 sibling, 0 replies; 40+ messages in thread
From: Charles Forsyth @ 2015-11-26 23:24 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 168 bytes --]

On 26 November 2015 at 23:14, Steve Simon <steve@quintile.net> wrote:

> I don't know about the PDP but the VAX allowed access to address zero.


Not in my port.

[-- Attachment #2: Type: text/html, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [9fans] Undefined Behaviour in C
  2015-11-26 23:14                           ` Steve Simon
  2015-11-26 23:24                             ` Charles Forsyth
@ 2015-11-26 23:55                             ` Brantley Coile
  1 sibling, 0 replies; 40+ messages in thread
From: Brantley Coile @ 2015-11-26 23:55 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 719 bytes --]

I did a port just like that (DTS Generic Unix) just to see what it would be like. It was awful. I’ll never do that again.

> On Nov 26, 2015, at 6:14 PM, Steve Simon <steve@quintile.net> wrote:
> 
> 
> I don't know about the PDP but the VAX allowed access to address zero.
> 
> Even more insidious, it allowed you to dereference a null pointer and guaranteed it would contain a zero, which resulted in many tiresome portability issues - I used Interdatas at the time, which faulted on a read at address zero.
> 
> -Steve
> 
> 
> On 26 Nov 2015, at 17:48, Bakul Shah <bakul@bitblocks.com <mailto:bakul@bitblocks.com>> wrote:
> 
>> Good points! Though 0 was a valid address on pdp11, right? 
>>>>>>  


[-- Attachment #2: Type: text/html, Size: 2514 bytes --]

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2015-11-26 23:55 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-23 10:20 [9fans] Undefined Behaviour in C Ramakrishnan Muthukrishnan
2015-11-23 11:20 ` Vasudev Kamath
2015-11-25 10:27   ` Alexandru Gheorghe
2015-11-25 10:43     ` Brantley Coile
2015-11-25 10:53       ` Brantley Coile
2015-11-25 12:59       ` Charles Forsyth
2015-11-25 13:48         ` erik quanstrom
2015-11-25 14:25           ` Brantley Coile
2015-11-25 14:31             ` Brantley Coile
2015-11-25 16:03             ` plannine
2015-11-25 17:13               ` Ryan Gonzalez
2015-11-25 18:41                 ` Brantley Coile
2015-11-26  2:04                   ` Prof Brucee
2015-11-26  2:43                     ` Brantley Coile
2015-11-26  2:57                       ` Prof Brucee
2015-11-26  3:48                         ` Ryan Gonzalez
2015-11-26  7:27                     ` Bakul Shah
2015-11-26 11:22                       ` Brantley Coile
2015-11-26 11:37                         ` tlaronde
2015-11-26 11:55                           ` Charles Forsyth
2015-11-26 11:38                         ` Bruce Ellis
2015-11-26 16:31                         ` erik quanstrom
2015-11-26 16:42                           ` Brantley Coile
2015-11-26 16:50                             ` Charles Forsyth
2015-11-26 17:12                               ` erik quanstrom
2015-11-26 16:46                           ` Alexandru Gheorghe
2015-11-26 17:48                         ` Bakul Shah
2015-11-26 18:04                           ` Brantley Coile
2015-11-26 23:14                           ` Steve Simon
2015-11-26 23:24                             ` Charles Forsyth
2015-11-26 23:55                             ` Brantley Coile
2015-11-25 19:19               ` Steffen Nurpmeso
2015-11-23 11:32 ` Charles Forsyth
2015-11-23 11:37   ` Charles Forsyth
2015-11-23 11:50 ` Brantley Coile
2015-11-23 12:05   ` Charles Forsyth
2015-11-23 12:17     ` Brantley Coile
2015-11-23 12:40       ` Charles Forsyth
2015-11-23 12:09   ` Charles Forsyth
2015-11-23 14:30 ` Charles Forsyth

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).