
WACC is this book and I am blogging my way through it. This is the last chapter in part 1. A quick skim shows its not too hard. Adding
externandstatickeywords- non stack data
The last point means I need to identify the syntax for this in NASM, the book uses gas syntax, and my normal cheat of looking what MSVC does is no longer available since I gave up on MASM
………. oh dear
Oh My Goodness (2)
That was the hardest chapter by far, took me more than a week. Part of the slowness is due to the fact that I am on the road with a small laptop and limited hacking time, but even so…
The complicated illogical behavior of the combinations of static and extern was a game of whack-a-mole..

fix one failing test and beak another one, fix that one and another one breaks….
Making it up as you go along
The chapter demonstrates the early life of the C language. The original authors were more focused on getting Unix running on a PDP 11 than on clean design of a new language. The language they had gradually evolved until they had something that did the job.
Accidental side effects of the way things got coded in the compiler became the standard, for example this one cited in the c standard
switch (expr){
int i = 4;
f(i);
case 0:
i = 17;
/* falls through into default code */
default:
printf("%d\n", i);
}
which is actually compiled as
switch (expr){
int i;
case 0:
i = 17;
/* falls through into default code */
default:
printf("%d\n", i);
}
Declarations before the first case work, but the initialization is ignored and any statements are not executed (note the lack of the call to the function f). No way was this designed behavior.
Other odd behaviours to do with this chapter.
...
extern int x = 10;
...
Most developers will tell you this is illegal, the Extern Declarations (GNU C Language Manual) page doesn’t mention it as a valid form of extern. gcc warns you if you do this but compiles it anyway, treating it as int x = 10, MSVC silently compiles it.
This is valid code
...
{
int x;
{
extern int x;
....
}
....
}
int x;
the inner x refers to the file level x. This is not allowed though:
...
{
extern int x = 20;
}
..
Why not? It could be compiled as static int x = 20;
The c standard had to invent a whole new variable state called ‘tentative’ to try to bring order to some other parts, see External and tentative definitions – cppreference.com
Tentative definitions were invented to standardize various pre-C89 approaches to forward declaring identifiers with internal linkage.
Some of the tests in the excellent test suite demonstrate the odd corners of the language, gcc compiles with warnings, msvc compiles with no complaint, wacc (the books compiler) is required to fatal them!
I have the source code of the original K&R compiler from Unix v7, I am going to have a look to see how many of these oddities are intentional and how many are accidental.
Getting it working
The assembler I am using (nasm) needs to be explicitly told that a symbol is external, This
movl foo(%rip), ax
works in gcc/gas but nasm needs
extern foo
...
mov dword [foo], ax
(Interesting to note tthat it does not need functions to be declared as external though, this is inferred)
This in turn means that this information needs to be in the TACKY data so I added it to the StaticVariable. So this code
extern int foo;
int bang = 99;
int func(){
static int bar = 42;
return foo + 32;
}
generates
Static Variable: bar$0 = Some(Int(42)) Global: false External: false
Static Variable: bang = Some(Int(99)) Global: true External: false
Static Variable: foo = None Global: true External: true
I also need to add another assembler program: tests\chapter_10\valid\data_on_page_boundary_windows.s
segment .bss
align 4096
resb 4090
global zed
zed:
resb 4
I am still sticking to my aim to have TACKY be self contained, there are places in this chapter where it indicates that the code reading the tacky needs to read the symbol table. I fixed that by assigning to Data vs Pseudo in the TACKY code to moira phase. I can do this because all the information I need is in the TACKY StaticVariables
I also still have the single pass c source to TACKY front end.
Ran 517 tests in 100.458s
OK
Leave a comment