Merge pull request #928 from xexyl/1986-marshall-compilers
This commit is contained in:
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