Add alt code to 1986/marshall
Add the code before the fixes to the entry that prevented it from working right depending on the compiler and optimiser (where having the optimiser with one compiler would let it work with one and not work with the other but having it disabled would reverse this in the same way) and documented the ways the compilers conflicted for instructional value and entertainment. Updated .gitignore.
This commit is contained in:
1 parent
c7c030c917
commit
d792fbf437
5 files changed
+121
-9
No files matched your search
@@ -1,3 +1,4 @@
|
||||
marshall
|
||||
marshall.orig
|
||||
prog.orig
|
||||
marshall.alt
|
||||
@@ -116,8 +116,8 @@ OBJ= ${PROG}.o
|
||||
DATA=
|
||||
TARGET= ${PROG}
|
||||
#
|
||||
ALT_OBJ=
|
||||
ALT_TARGET=
|
||||
ALT_OBJ= ${PROG}.alt.o
|
||||
ALT_TARGET= ${PROG}.alt
|
||||
|
||||
|
||||
#################
|
||||
|
||||
+96
-1
@@ -8,6 +8,13 @@ Eric Marshall
|
||||
make all
|
||||
```
|
||||
|
||||
There is an alternate version. See the Alternate code section for the commentary
|
||||
on why this is: there was a funny problem depending on the compiler and flags
|
||||
where it would work with one compiler with the optimiser but it would not work
|
||||
with the other; and if the optimiser state is changed the previous problematic
|
||||
compiler might work but the other one would not! We describe this in more detail
|
||||
below and we encourage you to read it.
|
||||
|
||||
|
||||
## Try:
|
||||
|
||||
@@ -15,7 +22,95 @@ make all
|
||||
./marshall
|
||||
```
|
||||
|
||||
# Judges' remarks:
|
||||
### Alternate code:
|
||||
|
||||
As some changes had to be made due to the problem of conflicting compiler
|
||||
options briefly noted above we provide the code that demonstrates the problem so
|
||||
you can see if your compiler has the problem as described below.
|
||||
|
||||
In some versions of gcc and clang (this was first discovered in fedora linux 38)
|
||||
depending on whether or not the optimiser was enabled would cause one compiler
|
||||
to segfault but not another but when changing the state of the optimiser the
|
||||
opposite would happen: the compiler that did not segfault suddenly did and the
|
||||
one that did now worked! Another problem was an infinite loop also depending on
|
||||
the optimiser.
|
||||
|
||||
The alternate code has the original fix for clang which works with some
|
||||
compilers depending on the optimiser. When we refer to the code below we refer
|
||||
to the alternate code.
|
||||
|
||||
### The conflicting compiler problems:
|
||||
|
||||
Below we describe the conflicting options that resulted in the need to modify
|
||||
the original code.
|
||||
|
||||
#### Linux
|
||||
|
||||
With the optimiser disabled GCC compiled the code to enter an infinite loop.
|
||||
Enabling the optimiser and it worked fine. But if the optimiser is enabled clang
|
||||
generates code that first prints the text twice (it should print it once) and
|
||||
then immediately dumps core!
|
||||
|
||||
But then what happens if we remove the infinite loop?
|
||||
|
||||
Once the loop is fixed if we compile with clang and the optimiser is disabled
|
||||
all is okay. If however we compile with gcc and the optimiser is disabled the
|
||||
string is printed once and the program then dumps core! Why is this? It is
|
||||
because of the call to `_exit()` (see below). Clang works fine with the loop
|
||||
removed and the optimiser disabled. If however we enable the optimiser clang
|
||||
generates code that prints the string twice and dumps core just like before!
|
||||
What about the call to `_exit()`?
|
||||
|
||||
The call was:
|
||||
|
||||
|
||||
```c
|
||||
_exit(argv[(int)*argc-2/cc[1*(int)*argc]|-1<<4]);
|
||||
```
|
||||
|
||||
Changing it to not refer to these variables and just exit 1 and the problems
|
||||
disappear!
|
||||
|
||||
#### macOS
|
||||
|
||||
But as noted just because it works one way in linux does not mean it works the
|
||||
same way in macOS!
|
||||
|
||||
If the infinite loop is not removed/commented out and the optimiser is enabled
|
||||
it works fine but if it's disabled it prints out the string and then enters an
|
||||
infinite loop.
|
||||
|
||||
After we fix the infinite loop if we change the `_exit()` call in macOS and
|
||||
disable the optimiser we might get something like:
|
||||
|
||||
```sh
|
||||
$ ./marshall
|
||||
choo choo
|
||||
Segmentation fault: 11
|
||||
```
|
||||
|
||||
Observe how it doesn't print it twice.
|
||||
|
||||
If the optimiser is enabled, however, we will see that it works fine before the
|
||||
change to `_exit()`.
|
||||
|
||||
|
||||
#### To use:
|
||||
|
||||
Due to the different conflicting problems we instead offer the problematic code
|
||||
as an alternate version whereas [marshall.c](marshall.c) has both the infinite
|
||||
loop and the complicated arg to `_exit()` commented out, replaced by just `1`.
|
||||
|
||||
To try out the alternate version:
|
||||
|
||||
```sh
|
||||
make alt
|
||||
```
|
||||
|
||||
Use `marshall.alt` as you would `marshall` above.
|
||||
|
||||
|
||||
## Judges' remarks:
|
||||
|
||||
This program prints the name of the picture. The layout is somewhat
|
||||
pretty though it is not the usual sort of output one would expect
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
extern int
|
||||
errno
|
||||
;char
|
||||
grrr
|
||||
;main( r,
|
||||
argv, argc ) char **argc ,
|
||||
r ; char *argv[];{int P( );
|
||||
#define x int i, j,cc[4];printf(" choo choo\n" ) ;
|
||||
x ;if (P( ! i ) | cc[ ! j ]
|
||||
& P(j )>2 ? j : i ){* argv[i++ +!-i]
|
||||
; for (i= 0;; i++ );
|
||||
_exit(argv[(int)*argc-2/cc[1*(int)*argc]|-1<<4]);printf("%d",P(""));}}
|
||||
P ( a ) char a ; { a ; while( a > " B "
|
||||
/* - by E ricM arsh all- */); }
|
||||
+8
-6
@@ -144,12 +144,14 @@ was an `int`. He notes that he tried to keep the ASCII art as close to the
|
||||
original as possible. The line lengths are the same but some spaces had to be
|
||||
changed to non-spaces.
|
||||
|
||||
As the fix was it worked for macOS but it did not work for modern linux, not
|
||||
before with gcc or after the fix with either gcc or clang, so Cody fixed that
|
||||
too. This took some changes and commenting code out (commented out for the ASCII
|
||||
art as noted). It was a game of cat and mouse where one fix with one compiler
|
||||
caused it to segfault with the other but after commenting out two portions it
|
||||
works fine.
|
||||
A very funny problem occurred depending on the compiler and whether or not the
|
||||
optimiser is enabled that had to be fixed: one compiler would work fine but
|
||||
another might enter an infinite loop or segfault but then once the optimiser
|
||||
state was changed the compiler that worked no longer worked (in the same was as
|
||||
the other one not working) and the one that didn't work did! We encourage you to
|
||||
see the README.md file to see how odd this problem was and what Cody did to fix
|
||||
it!
|
||||
|
||||
|
||||
## [1986/wall](1986/wall/wall.c) ([README.md](1986/wall/README.md]))
|
||||
|
||||
|
||||
Reference in new issue
Block a user