Update 1986/marshall/README.md
Reworded the explanation of the funny opposite/conflicting problems with gcc and clang depending on if the optimiser is disabled or enabled, that I fixed and added alt code to demonstrate it.
This commit is contained in:
1 parent
846339262f
commit
9cb85e0f18
2 files changed
+37
-35
No files matched your search
+27
-23
@@ -8,12 +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 in modern systems where depending on
|
||||
the compiler and flags 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.
|
||||
There is an alternate version. See the [Alternate code](#alternate-code) section
|
||||
for the commentary on why this is: there was a funny problem in modern systems
|
||||
where depending on the compiler and the optimiser 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 for entertainment if nothing else.
|
||||
|
||||
|
||||
## Try:
|
||||
@@ -29,36 +30,37 @@ 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 generate code that segfaults but not another - but when changing the state
|
||||
of the optimiser the opposite would happen: the compiler that did not cause a
|
||||
segfault suddenly did and the one that did now worked! Another problem was an
|
||||
infinite loop also depending on the optimiser.
|
||||
if the compiler was enabled one compiler would generate code that segfaulted but
|
||||
the other one would not. However, when then disabling the optimiser the compiler
|
||||
that had no problem suddenly did and the one that did suddenly did not.
|
||||
|
||||
Another problem was that depending on the optimiser an infinite loop would be
|
||||
entered.
|
||||
|
||||
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:
|
||||
#### The conflicting compiler problems:
|
||||
|
||||
Below we describe the conflicting options that resulted in the need to modify
|
||||
the original code.
|
||||
|
||||
#### Linux
|
||||
##### 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?
|
||||
But then there's that infinite loop. What happens if we remove it?
|
||||
|
||||
Once the loop is fixed if we compile with clang and the optimiser is disabled
|
||||
Once the loop is removed 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
|
||||
string is printed once and then the program 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!
|
||||
will generate code that prints the string twice and dumps core just like before!
|
||||
What about the call to `_exit()`?
|
||||
|
||||
The call was:
|
||||
@@ -71,10 +73,10 @@ _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
|
||||
##### macOS
|
||||
|
||||
But as noted just because it works one way in linux does not mean it works the
|
||||
same way in macOS!
|
||||
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
|
||||
@@ -89,7 +91,8 @@ $ ./marshall
|
||||
Segmentation fault: 11
|
||||
```
|
||||
|
||||
Observe how it doesn't print it twice.
|
||||
Observe how it doesn't print it twice. But of course it segfaults so it's not
|
||||
right either.
|
||||
|
||||
If the optimiser is enabled, however, we will see that it works fine before the
|
||||
change to `_exit()`.
|
||||
@@ -97,9 +100,10 @@ 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`.
|
||||
Due to the different conflicting problems with gcc and clang, 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,
|
||||
changing the value passed into `_exit()` to `1`.
|
||||
|
||||
To try out the alternate version:
|
||||
|
||||
|
||||
+10
-12
@@ -229,24 +229,22 @@ and gcc.
|
||||
|
||||
## [1986/marshall](1986/marshall/marshall.c) ([README.md](1986/marshall/README.md]))
|
||||
|
||||
Cody got this to compile and work with clang and gcc. The optimiser being
|
||||
Cody got this to compile and work with clang and gcc. He noted 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.
|
||||
|
||||
This fix was very interesting and quite amusing, showing up problems with
|
||||
compilers. This is a brief summary but much more is explained in the README.md,
|
||||
giving which compilers had which problems in which systems: the optimiser being
|
||||
enabled in one compiler let it work but broke it in the other; and disabling it
|
||||
would let it work in the one that didn't work but suddenly the one that worked
|
||||
would be broken. See below and the README.md file for more details.
|
||||
would be broken.
|
||||
|
||||
This problem was only after getting clang to compile, of course. It did not
|
||||
compile it because it is more strict about the second and third args to `main()`
|
||||
and the third arg was an `int`. Cody 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.
|
||||
and the third arg was an `int`.
|
||||
|
||||
As noted above, a very funny problem occurred depending on the compiler and
|
||||
whether or not the optimiser was 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
|
||||
We encourage you to read the README.md file to see how odd this problem was and
|
||||
what Cody did to fix it!
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user