Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Write some program (the size doesn't matter), and put a line that looks useless, but it's actually not - if it would be removed, the program would crash, or do something wrong. Feel free to mark the line that looks unused by a comment, or mention it your code description, like in example below (of course, in this example, the line is actually not needed, it's just an example).

int main(void) {
    /* The line below is actually needed. */
    2 + 2;

    return 0;
}

As this is popularity contest, the solution with highest number of votes wins.

share|improve this question
2  
Why is the line in the example necessary? –  Gari BN Jan 27 at 14:23
3  
@GariBN It's not: "in this example, the line is actually not needed, it's just an example." –  Ed Cottrell Jan 27 at 15:53
7  
@EdCottrell Good to know... I thought I missed some basic thing... –  Gari BN Jan 27 at 18:26
add comment

16 Answers 16

up vote 30 down vote accepted

C

int main(int argc, char **argv) {
    switch(argc) {
        case 2:
            ;
            int allowed = 0;
        case 3:
            argc--;
            break;
        default:
            argc = 3;
    }
    return 0;
}

Won't compile if we remove the single ;.

EDIT:

Solution below:

This happens because a case statement is just a label, and, as such, must be followed by a statement (which the standard refers to as a "specifier for actions to be performed", which rules out declarations). To prevent this, we prefix the declaration with a ;, a null statement. Specifications for the case label can be found here at page 142 (131 in-document)

share|improve this answer
    
It will be great if you provide a description why it won't compile without ;. –  VisioN Jan 26 at 1:16
2  
GCC says "a label can only be part of a statement and a declaration is not a statement". –  Vortico Jan 26 at 7:42
    
I was just bitten by this in a program I'm writing for school. –  Kevin Mar 23 at 21:44
add comment

C / C++

Just some code written in the style of introduction / tutorial...

Tutorial nr. 2: reading in numbers, performing mathematical operations on them, and printing the results.

//////////////////////////////////////////////////
///////////////////////////////////////////////////
/////                                            //
/////           T  U  T  O  R  I  A  L           //
/////                                            //
///////////////////////////////////////////////////

#include "stdio.h"

int main()
{
    ///////////////////////////////////////////////
    // Local variables (int means integer!!)      /
    int a, b, result;

    ///////////////////////////////////////////////
    // Reading them in                            /
    scanf("%d", &a);
    scanf("%d", &b);

    ///////////////////////////////////////////////
    // Performing an operation, e.g. addition!!!  /
    result = a+b;

    ///////////////////////////////////////////////
    // Why is the next line absolutely mandatory??/
    result = 42;
    printf("The result is: %d", result);

}

Removing the line result = 42; which at first glance looks both superfluous, and, considering the stated objective, actually wrong, will actually cause the program to not do what the description states.

Why?

Trigraphs strike again! ??/ will be replaced by the preprocessor with \, which will, in turn, concatenate the next line into the comment. The result = 42; becomes part of the comment, so it "saves" the printing line. With the result = 42; line removed, the printf line will be swallowed by the comment. Some compilers might give a warning, or trigraphs might be turned off as default and must be turned on for this example to work. Syntax highlighting might also betray it, but there are compilers and IDEs around which leave you none the wiser.

share|improve this answer
    
At least in gcc, you must specify that you want to use trigraphs by adding this flag (-trigraphs). Without this, gcc rises warning and ignores trigraphs. –  Gari BN Jan 27 at 18:42
4  
Nice one! I'm glad I didn't scroll down too far before figuring it out. You can change your blockquote into spoiler text by starting it with >! instead of just >. –  squeamish ossifrage Jan 27 at 19:52
    
@squeamishossifrage : thanks, this was my original intention, I used >! just not in every line. I though they don't display for me as I wrote them. Interestingly, the SE parser does not spoil it :) –  vsz Jan 27 at 21:29
1  
I knew something sneaky was afoot the second I saw a local include "stdio.h" instead of the actual library include, <stdio.h> –  B1KMusic Feb 28 at 17:37
    
@B1KMusic +1 just for teaching me the difference.. –  Ollie Ford Jun 3 at 1:19
show 1 more comment

Whitespace

Unfortunately I cannot show my program here because StackExchange strips all trailing whitespace. The same is true of pastebin.com and pastie.org, so I can’t link to it either.

Of course, the entire program “looks useless”, but if you remove any line, it will do something different.

share|improve this answer
26  
But fortunately nothing of value will be lost, because the entire language is useless :-) –  squeamish ossifrage Jan 27 at 21:27
    
pastebin doesn't strip whitespace. –  B1KMusic Feb 28 at 17:40
    
@B1KMusic: It does strip from the end of the entire input. :) –  Timwi Mar 10 at 18:32
    
@Timwi what about the "raw paste data" box? –  B1KMusic Mar 10 at 18:54
5  
replace \t with t. Replace " " with s, replace \n with n –  Cruncher Mar 19 at 18:37
show 1 more comment

C:

#include <stdio.h>
#include <string.h>

int main() {
    int i,sum;
    char s[4];

    /* Add all the integers < 1000 that contain no '0' or '9' */
    sum=0;
    for (i=0; i<1000; i++) {
        sprintf(s,"%d",i);
        if (strchr(s,'0')) goto skip;
        if (strchr(s,'9')) goto skip;
        sum += i;
      skip:
        i = i; /* Don't delete this line! */
    }
    printf("The answer is %d\n",sum);  /* <<< Should be 258948 */
    return 0;
}

If you delete the line i = i; then the code won't work. This is because...

... in fact it won't even compile. According to the C standard, labels like skip in the above example must be associated with a statement. Even a single semicolon would have sufficed, but if you delete the whole line then the label has no associated statement and compilation fails. This answer explains in a bit more detail.

share|improve this answer
add comment

JavaScript:

for (var a = 0, b = 4; ++a < b; a++)b+-

2 + 2; // This line is needed, or it will alert twice!
alert(a);

The reason it works is because the body of the for is b+-, not b++ or b--; therefore, if you remove the required line, it will add to b the value of -alert(a).

share|improve this answer
    
"it will add to b the value of alert(a)" : So, shouldn't the b+- be b+= ? –  Gaurang Tandon Feb 22 at 17:20
    
@GaurangTandon No; the idea is that it looks like b++ or b--. –  toothbrush Feb 22 at 17:27
    
what does b+- actualy mean? –  Mhmd Feb 22 at 18:19
4  
@user689 b + -2 + 2. That's why if you delete the line with 2 + 2;, it evaluates to b + -alert(a);. –  toothbrush Feb 22 at 18:23
add comment

APL

Here's an APL function:

i_←{
  ⍺←⎕IO ⋄ ⎕IO←⍺
  ⍵⍴⍳×/⍵
}

It does the same thing as J's monadic i.:

      i_ 5 5
 1  2  3  4  5
 6  7  8  9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

It can take an optional left argument that gives the offset:

      0 i_ 5 5
 0  1  2  3  4
 5  6  7  8  9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24

The line ⍺←⎕IO ⋄ ⎕IO←⍺ looks useless ("assign ⎕IO to , then assign to ⎕IO"), but the first part only runs if no left argument is given, so in fact it does do something:

  • if no is given, set to (global) ⎕IO.
  • set (local) ⎕IO to
share|improve this answer
add comment

C#

Func<int, int> fibo;
fibo = null; //Note that this can be set to *any* Func<int, int> reference.  It doesn't matter.
fibo = x => x < 1 ? 1 : fibo(x-1) + fibo(x-2);

The variable fibo must be assigned before you can use it inside a lambda, even if you’re assigning that lambda to fibo itself. If you remove the (seemingly useless) assignment, a compiler error will occur (“Use of unassigned local variable 'fibo'”).

share|improve this answer
    
It's not a null reference exception, it's an uninitialized variable compiler error. Also, better move the declaration to its own line, because the declaration is not useless. –  Kendall Frey Jan 27 at 13:47
    
@KendallFrey Good point! Fixed. –  Ben Reich Jan 27 at 15:34
add comment

Ruby

require 'prime'

# Given a regular expression, return the smallest prime containing it
# and the substring of the prime that matches it
def smallest_prime_matching_regexp(regexp)
  match = 'this assignment is necessary even though the value is never used'
  prime = Prime.find { |n| match = n.to_s[regexp] }
  return prime, match
end

[ /4/, /1+2/, /[02468]{2,}/ ].each do |regexp|
  prime, match = smallest_prime_matching_regexp(regexp)
  puts "#{regexp.inspect}:\t#{prime} (#{match})"
end

A similar thing came up at work recently--a coworker actually flagged my seemingly unnecessary initialization during code review, and I was really tempted to put the explanation inside a spoiler block. So I'll do that here.

The line is necessary because a variable initialized inside a block is local to that block. If we initialize it outside the block, then the value is able to escape to the method scope.

Output as is:

/4/:    41 (4)
/1+2/:  127 (12)
/[02468]{2,}/:  223 (22)

Output with the first line of the method removed:

undefined local variable or method `match' for main:Object (NameError)

share|improve this answer
1  
It's fairly obvious why that's needed... and anyway, a better way to write this would be just match = Prime.find { |n| n.to_s[regexp] } –  Doorknob Jan 25 at 23:47
1  
That wouldn't do what I want...Prime.find returns n (e.g. 223), and match needs to be n.to_s[regexp] (e.g. "22"). Obviously I contrived the problem to make that necessary. –  histocrat Jan 25 at 23:50
    
Ah, sorry, didn't notice you were calling find on Prime and not an array. Anyway, it's still fairly easy to notice why that line is needed... –  Doorknob Jan 25 at 23:51
    
Fair enough. Maybe my coworker was just being unobservant. –  histocrat Jan 25 at 23:52
    
Huh. No variable declarations, but the opposite approach to defaulting local/nonlocal to what Python does. That's going to feel weird if I ever decide to learn Ruby. –  user2357112 Apr 4 at 14:47
add comment

PHP

<?php
$some_html_text= <<<EOT
<h1>This is a Header </h1>
<body> This is a body </body>
EOT;
//This is a comment    

Here, \n//This is a comment is necessary. Without it the code won't run.

At least a \n char is necessary after EOT; to run it properly

share|improve this answer
add comment
#include <stdio.h>
#include <stdlib.h>

void strcmp_or_die(char *s, char *t) {
    if(!strcmp(s, t)) {
        printf("Success!\n");
    } else {
        int *ptr = NULL;
        *ptr = 0;
    }
}

int main(void) {
    char blah = '\0'; //segfaults without this line

    char v[2] = "ok";
    strcmp_or_die(v, "ok");
}

Simple string overflow problem.

share|improve this answer
1  
Any decent compiler is going to give you a "too many initializers" diagnostic. –  Ben Voigt Apr 4 at 18:49
    
Which platform segfaults without blah? Here with OpenBSD 5.5/amd64 and the system gcc, it never segfaults, whether or not blah is there. The compiled program allocates 16 bytes of stack space and copies the 16-bit value of "ok" to the first 2 bytes. The uninitialized 3rd byte has '\0' by luck. If blah is there, it is in the 16th byte, and still not terminating the string. –  kernigh Jun 6 at 1:46
add comment

Windows Batch

This is a batch file that prints the numbers 1 to 10 with an empty line after each:

@echo off

setlocal EnableDelayedExpansion

set NL=^


rem Previous two lines deliberately left blank for NL to work.

for /l %%a in (1,1,10) do (
    echo %%a!NL!
)

endlocal

pause

This effectively makes use of a dirty hack to store a newline inside a variable (the use of delayed expansions gets rid of the more scary looking NL line in the linked answer). If you remove or otherwise change the two completely useless-looking blank lines above the comment, well, it won't work.

share|improve this answer
add comment

Windows Batch:

echo hello
pause
echo world

Set the program running and modify the file to:

rem test01
pause
echo hello world

If you remove or resize the comment, it will cause havoc as the 1st instance of the program pauses and then continues interpreting from the 19th byte onwards.

share|improve this answer
    
I don't see any comments. –  orion May 30 at 11:40
    
REM (remark) is the comment operator - stackoverflow.com/questions/11269338 –  OJW May 30 at 12:24
add comment

~-~!

This is probably the stupidest, most obvious one here.

'=|hello\|:
'=~!|Useless?\|:
@'[|y|]|n|:

It throws an error without that second line, with it it prints y.

the backslash isn't an escape character, hehe.

share|improve this answer
    
How do you pronounce the language name? –  professorfish Jun 5 at 12:57
    
@professorfish ~-~! –  Timtech Jun 5 at 13:10
    
@professorfish That'd be "no comment". –  Trimsty Jun 5 at 15:31
add comment

JAVASCRIPT

var a = function(b) {
    return b;
}

; // This must be here

(function() {
    // more code
}());

Without the semicolon then a would become what ever the return value from 2nd function is - in this case it's undefined. Because the function originally assigned to a will be executed right away with the second function as the argument b.

share|improve this answer
add comment

COBOL (IBM Mainframe)

   ID DIVISION. 
   PROGRAM-ID. USELESS. 
   DATA DIVISION. 
   WORKING-STORAGE SECTION. 
   01  W-WHEN-COMPILED              PIC X(8)BX(8) VALUE SPACE.
   PROCEDURE DIVISION. 
       IF W-WHEN-COMPILED EQUAL TO SPACE 
           NEXT SENTENCE 
       END-IF 
       MOVE SPACE                   TO W-WHEN-COMPILED. 
       MOVE WHEN-COMPILED           TO W-WHEN-COMPILED 

       DISPLAY W-WHEN-COMPILED " HELLO WORLD!" 
       GOBACK 
       . 

If you run the above program (any IBM Mainframe COBOL since COBOL II (first IBM compiler to 1985 standard, probably other IBM COBOLs as well) the output is:

02/22/14 13.11.02 HELLO WORLD!

However, if you remove the triply-useless line "MOVE SPACE TO W-WHEN-COMPILED." (the field has an initial value of space, and has other content placed in it in the next instruction, and it is branched over anyway) the program produces no output and actually Abends (U4038) (that means it crashes) with the following message:

 IGZ0037S The flow of control in program USELESS proceeded beyond the 
          last line of the program.  From compile unit USELESS at entry 
          point USELESS at compile unit offset +000003AC at entry offset
          +000003AC at address 119003AC. 

(message code and text would vary amongst compilers, offsets depend upon actual compiler used and compile options, address depends on where program is loaded when EXECuted).

The reason is the NEXT SENTENCE. This is a Secret GO TO. The compiler hunts down the next full-stop/period in the source, and generates a branch to the following instruction. From COBOL II, the use of full-stops/periods was relaxed. A program must end with a full-stop/period. In this case, the branch is off the end of the program.

Both programs compile 100% clean (no diagnostic messages, Return Code of zero).

This behaviour is a dumb "IBM Extension" to COBOL. The 1985 Standard does not allow NEXT SENTENCE within IF/END-IF (CONTINUE is used instead, which is a no-op). IBM allowed it - causing horrible Gotchas from time-to-time.

share|improve this answer
add comment

troff

Troff is the most wonderful text processing system. I use it for my documents. It requires a macro system in order to be ready to be used, and the most famous is the ms macro package. Let's compile the following piece of code with the classical -ms option.

.\" -ms macro package
.\" the following line seems to be useless
\& \" print an invisible character
.ad c
.sp |300p \" absolute vertical positionning
.ps 36p
.ft B
My title.
.PP
This is a paragraph.

The third line seems to be useless, and would actually be useless without the macro package. Since it is followed two lines below by an absolute vertical positionning, it could seem meaningless to print nothing before. But without this invisible character, the vertical positionning will have no effect, though I am not absolutely sure I could explain why (see this thread if you want to have a glance at the discussion). This makes the new user crazy, but then the trick should become familiar to the more experimented user.

Just checked with my favorite version of troff which is not very known (heirloom troff), but I am pretty sure it still works the same with GNU troff.

share|improve this answer
    
Nice one, this happens in LaTeX too. Without an empty box or something similar, vertical spacing doesn't work properly. –  orion May 30 at 11:41
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.