
How to Get Fired Using Switch Statements and Statement Expressions - mirceasoaica
http://blog.robertelder.org/switch-statements-statement-expressions/
======
vvanders
Anyone who rates themselves a 8-9 in C/C++ either is a compiler developer or
hasn't spent enough time with the language.

It's always a fun experiment in Dunning-Kruger to see someone ranks themselves
with C/C++.

~~~
packetslave
Kind of like interviewing at Google: "oh, you're a 9 in C++? let me introduce
you to your interviewers for the day: Hans Boehm, Chandler Carruth, Richard
Smith, and Jeffrey Yasskin. We were lucky to get them; they're off to the ISO
C++ standards committee meeting tomorrow"

~~~
bertiewhykovich
This would be a moronic interviewing technique, but it would also be
unsurprising for Google.

------
na85
Seems to have gone offline due to the HN hug of death. Anyone got a mirror?

Edit: oh wow, I feel like an atheist who previously thought the conversation
about how horrible Hell is was mostly just overwrought fanatics but has now
caught a glimpse of Cocytus.

~~~
robertelder
Update: Moved about 7 small images and css into S3 and page load time is now <
3 seconds with 380 users on site. I'm about 90% sure that my efforts caused
the improvement.

It's still up, but it's super slow with > 20-60 second page load times. I just
moved some images into s3 which made it a bit faster. There are currently 267
people on the site according to google analytics.

~~~
marktangotango
Multiply google analytics users by k to get a more accurate number, where k is
a percentage of readers using uBlock or some other blocker that blocks google
analytics. Ie k=1.5 for a tech heavy audience :)

Edit; Anecdata, almost all my signups come from users who block google
analytics.

------
hellofunk
I made the terrible mistake this week of using the strategies in this article
as a way to provide to my employer my resignation, and unfortunately it didn't
work as I'd expected.

~~~
danbmil99
That's because the premise of the article is completely wrong. There's a
venerable tradition on Wall Street of generating unmaintainable code and not
sharing your knowledge with anyone else. If you're lucky enough for the code
you're writing to be mission-critical, you can write your own check and never
get fired.

~~~
ygjb
I won't say which, but one of my previous employers had a policy of only using
frameworks and libraries that were invented at the org to reduce the
likelihood of employees developing transferable skills. I learned about the
policy after I wrote a detailed write-up of a specific bug class that was
affecting all of our apps, and recommending switching libraries, and sent it
to the leads of all of the development teams across the org. Learning this was
a contributing factor in my leaving the place :/

------
tuix
The Duff's device example is incorrect. In n%4, the value of n before
n=(n+3)/4 should be used, not after that.

~~~
robertelder
Thanks, I modified it from an example one but introduced some mistakes. I've
corrected it and tested it this time.

------
tombone12
I am reminded of the following story, reproduced here in its entirety

\----

Thompson, Ritchie and Kernighan admit that Unix was a prank

=====================================

(This piece was found on Usenet. This is fiction, not reality. Always remember
that this is not true. It's really a joke, right? -- Editor)

In an announcement that has stunned the computer industry, Ken Thompson,
Dennis Ritchie and Brian Kernighan admitted that the Unix operating system and
C programming language created by them is an elaborate prank kept alive for
over 20 years. Speaking at the recent UnixWorld Software Development Forum,
Thompson revealed the following:

"In 1969, AT&T had just terminated their work with the GE/Honeywell/AT&T
Multics project. Brian and I had started work with an early release of Pascal
from Professor Niklaus Wirth's ETH Labs in Switzerland and we were impressed
with its elegant simplicity and power. Dennis had just finished reading 'Bored
of the Rings', a National Lampoon parody of the Tolkien's 'Lord of the Rings'
trilogy. As a lark, we decided to do parodies of the Multics environment and
Pascal. Dennis and I were responsible for the operating environment. We looked
at Multics and designed the new OS to be as complex and cryptic as possible to
maximize casual users' frustration levels, calling it Unix as a parody of
Multics, as well as other more risque! allusions. We sold the terse command
language to novitiates by telling them that it saved them typing.

Then Dennis and Brian worked on a warped version of Pascal, called 'A'. 'A'
looked a lot like Pascal, but elevated the notion of the direct memory address
(which Wirth had banished) to the central concept of the "pointer" as an
innocuous sounding name for a truly malevolent construct. Brian must be
credited with the idea of having absolutely no standard I/O specification:
this ensured that at least 50% of the typical commercial program would have to
be re-coded when changing hardware platforms.

Brian was also responsible for pitching this lack of I/O as a feature: it
allowed us to describe the language as "truly portable". When we found others
were actually creating real programs with A, we removed compulsory type-
checking on function arguments. Later, we added a notion we called "casting":
this allowed the programmer to treat an integer as though it were a 50kb user-
defined structure. When we found that some programmers were simply not using
pointers, we eliminated the ability to pass structures to functions, enforcing
their use in even the simplest applications. We sold this, and many other
features, as enhancements to the efficiency of the language. In this way, our
prank evolved into B, BCPL, and finally C.

We stopped when we got a clean compile on the following syntax:
for(;P("\n"),R-;P("|"))for(e=C;e-;P("_"+( _u++ /8)%2))P("| "+(_u/4)%2);

At one time, we joked about selling this to the Soviets to set their computer
science progress back 20 or more years.

Unfortunately, AT&T and other US corporations actually began using Unix and C.
We decided we'd better keep mum, assuming it was just a passing phase. In
fact, it's taken US companies over 20 years to develop enough expertise to
generate useful applications using this 1960's technological parody. We are
impressed with the tenacity of the general Unix and C programmer. In fact,
Brian, Dennis and I have never ourselves attempted to write a commercial
application in this environment.

We feel really guilty about the chaos, confusion and truly awesome programming
projects that have resulted from our silly prank so long ago."

Dennis Ritchie said: "What really tore it (just when ADA was catching on), was
that Bjarne Stroustrup caught onto our joke. He extended it to further parody
Smalltalk. Like us, he was caught by surprise when nobody laughed. So he added
multiple inheritance, virtual base classes, and later ...templates. All to no
avail. So we now have compilers that can compile 100,000 lines per second, but
need to process header files for 25 minutes before they get to the meat of
"Hello, World".

Major Unix and C vendors and customers, including AT&T, Microsoft, Hewlett-
Packard, GTE, NCR, and DEC have refused comment at this time.

Borland International, a leading vendor of object-oriented tools, including
the popular Turbo Pascal and Borland C++, stated they had suspected for
Windows was originally written in C++. Philippe Kahn said: "After two and a
half years programming, and massive programmer burn-outs, we re-coded the
whole thing in Turbo Pascal in three months. I think it's fair to say that
Turbo Pascal saved our bacon". Another Borland spokesman said that they would
continue to enhance their Pascal products and halt further efforts to develop
C/C++.

Professor Wirth of the ETH Institute and father of the Pascal, Modula 2, and
Oberon structured languages, cryptically said "P.T. Barnum was right." He had
no further comments.

~~~
Unklejoe
[When we found that some programmers were simply not using pointers, we
eliminated the ability to pass structures to functions, enforcing their use in
even the simplest applications.]

I'm confused. You can pass a structure to a function by value in C. What does
he mean by this?

~~~
Someone
In ANSI C, not in K&R C.
[https://en.wikipedia.org/wiki/C_(programming_language)#K.26R...](https://en.wikipedia.org/wiki/C_\(programming_language\)#K.26R_C)
doesn't explicitly say it, but gets close:

 _" In the years following the publication of K&R C, several features were
added to the language [...] functions returning struct or union types (rather
than pointers)"_

------
userbinator
Statement expressions are certainly not in the standard nor supported by MSVC,
and based on the compiler behaviour exhibited in the article, it looks like
they may have been added in haste without considering (nor testing...) how the
feature would interact with all the other features of the language.

The Asm fragment there seems like it doesn't even match the C at all; it
begins with these 3 rather useless instructions which appear to be a very dumb
translation of "if((char)1)", a statement that does not even exist in the C
code:

    
    
            movb    $1, %al
            testb   %al, %al
            jne     .LBB0_2
    

_In the first iteration the use of the jump from the switch statement jumps
over these instructions, although they are executed on later loop iterations.
It seems pretty reasonable that the compiler would do this, after all you are
telling it to branch into the middle of a for loop comparison._

IMHO if branching to that location is allowed, this would be a defect because
there is a (slightly) saner interpretation: branch there to execute the case,
then "return" 10 from the statement expression and compare that to i,
continuing onward from there as usual. Whether the compiler chooses to use
temporary variables shouldn't make any difference according to these
semantics. If we "linearise" that example according to such a principle, it
may become something like this:

    
    
            int i = 0;
            // switch(i)
            if(i == 0)
                goto case0;
            else
                goto switch_end;
            // i = 0;           // unreachable
            // goto loop_check; // unreachable
        loop_body:
            i;
            // loop increment
            i++;
        case0:
            // if there was code for case 0 it would go here
        loop_check:
            int r = 10; // result of statement expression
            if(i < r)
                goto loop_body;
        switch_end:
            return 0;
    

...and that does not cause any uninitialised reads or writes. Also, the
extremely contorted control flow in some of these examples reminds me of
continuations.

The jump into the function parameter is puzzling at first (and once again
shows what I'd consider a defect since it crashes), but using the same
semantics of "continue at the remainder of the statement", it can be
transformed into this:

    
    
            int i = 0;
            if(i == 0)
                goto case0;
            else
                goto switch_end;
        case0:
            // if there was code for case 0 it would go here
            int r = 1;
            // continue with evaluating the parameter
            int p = i + r + i;
            // and call the function
            f(p);
        switch_end:
            return 0;

~~~
jjnoakes
> there is a (slightly) saner interpretation: branch there to execute the
> case, then "return" 10 from the statement expression and compare that to i,
> continuing onward from there as usual [...] and that does not cause any
> uninitialised reads or writes

The code you wrote did one additional thing: it moved the "switch" starting
point from before the "i=0" initialization to after the "i=0" initialization,
which is more than just a different interpretation, it's completely different
semantics.

~~~
yorwba
i is initialized twice in the example code

    
    
      int i = 0;
        switch(i){
         for(i = 0; i < ({case 0:; 10;}); i++){
    

The compiler probably tried to be intelligent and optimized it away.

EDIT: Okay I tried reading the assembly and I think I understand whats going
on:

    
    
      movl    $0, -8(%rbp)                     # translation of i = 0
      ...                                      # the following is jumped over
      movl    -8(%rbp), %eax
      movl    %eax, -16(%rbp) # 4-byte Spill   # i is moved to somewhere else in memory
      ...                                      # the switch jumps between these
      movl    -16(%rbp), %eax # 4-byte Reload  # tries to reload i from its "new" position
    

Whoever wrote the code to place variables into memory obviously didn't
consider this kind of insane control flow.

~~~
jjnoakes
Yep, you are right, I missed that "i" was initialized twice; when I see "i=0"
in a for loop I assume it isn't initialized right above (otherwise, why put
the "i=0" in the for loop at all?).

------
ursus_bonum
Maybe compilers shouldn't have stupid extensions that make it possible to
crash/hang the compiler?

------
krylon
I did not know about the switch-based co-routines, but they made me groan and
giggle at the same time.

I try to come up with a real-world metaphor to describe this mixture of horror
and delight to non-programmers, but I am not sure there is one.

------
ryandrake
First code snippet has a bug: no colon after default.

~~~
robertelder
Fixed.

