Schreiben Sie eine Zeile in ein Programm, das unbrauchbar aussieht [closed]

26

Schreiben Sie ein Programm (die Größe spielt keine Rolle) und fügen Sie eine Zeile ein, die nutzlos aussieht, aber eigentlich nicht - wenn sie entfernt würde, würde das Programm abstürzen oder etwas falsch machen. Fühlen Sie sich frei, die Zeile zu markieren, die von einem Kommentar nicht verwendet wird, oder geben Sie Ihre Codebeschreibung an, wie im folgenden Beispiel (in diesem Beispiel ist die Zeile natürlich nicht erforderlich, sondern nur ein Beispiel).

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

    return 0;
}

Da dies ein Beliebtheitswettbewerb ist, gewinnt die Lösung mit der höchsten Stimmenzahl.

Konrad Borowski
quelle
2
Warum ist die Zeile im Beispiel notwendig?
Gari BN
3
@GariBN Es ist nicht: "In diesem Beispiel wird die Zeile eigentlich nicht benötigt, es ist nur ein Beispiel."
Elixenide
9
@EdCottrell Gut zu wissen ... Ich dachte, ich hätte etwas Grundlegendes verpasst ...
Gari BN
2
Also es ist notwendig. Für das Beispiel. :-)
Florian F
1
Ich stimme dafür, diese Frage als "Off-Topic" zu schließen, da hinterhältige Herausforderungen auf dieser Site nicht mehr zum Thema gehören. meta.codegolf.stackexchange.com/a/8326/20469
cat

Antworten:

33

C

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

Kompiliert nicht, wenn wir die Single entfernen ;.

EDIT :

Lösung unten:

Dies liegt daran, dass eine caseAnweisung nur eine Bezeichnung ist und als solche von einer Anweisung gefolgt werden muss (die in der Norm als "Spezifizierer für auszuführende Aktionen" bezeichnet wird und Deklarationen ausschließt). Um dies zu verhindern, wird der Deklaration ;eine Null-Anweisung vorangestellt . Die Spezifikationen für das caseEtikett finden Sie hier auf Seite 142 (131 im Dokument).

Oberon
quelle
4
GCC sagt, "ein Etikett kann nur Teil einer Aussage sein und eine Erklärung ist keine Aussage".
Vortico
1
Das hat mich gerade in einem Programm gebissen, das ich für die Schule schreibe.
Kevin - Reinstate Monica
Dadurch sehen echte Programme tatsächlich so hässlich aus: \.
Val sagt Reinstate Monica
23

C / C ++

Nur ein Code im Stil von Einführung / Tutorial geschrieben ...

Tutorial Nr. 2 : Zahlen einlesen, mathematische Operationen ausführen und Ergebnisse ausdrucken.

//////////////////////////////////////////////////
///////////////////////////////////////////////////
/////                                            //
/////           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);

}

Das Entfernen der Zeile, result = 42;die auf den ersten Blick überflüssig und angesichts des angegebenen Ziels tatsächlich falsch aussieht, führt dazu, dass das Programm nicht das tut, was in der Beschreibung angegeben ist.

Warum?

Trigraphen schlagen wieder zu! ?? / wird vom Präprozessor durch \ ersetzt , wodurch die nächste Zeile im Kommentar verkettet wird. Das Ergebnis = 42; wird Teil des Kommentars, so dass die Druckzeile "gespeichert" wird. Mit dem Ergebnis = 42; Zeile entfernt, die printf- Zeile wird vom Kommentar verschluckt. Einige Compiler geben möglicherweise eine Warnung aus, oder Trigraphs sind standardmäßig deaktiviert und müssen aktiviert sein, damit dieses Beispiel funktioniert. Das Hervorheben von Syntaxen könnte es auch verraten, aber es gibt Compiler und IDEs, um die Sie sich keine Gedanken machen müssen.

vsz
quelle
Zumindest in gcc müssen Sie angeben, dass Sie Trigraphen verwenden möchten, indem Sie dieses Flag (-trigraphs) hinzufügen. Ohne dies steigt GCC Warnung und ignoriert Trigraphen.
Gari BN
4
Schön! Ich bin froh, dass ich nicht zu weit gescrollt habe, bevor ich es herausgefunden habe. Sie können Ihr Blockquote in Spoiler-Text ändern, indem Sie es mit >!statt mit nur starten >.
zimperlich ossifrage
@squeamishossifrage: danke, das war meine ursprüngliche absicht, die ich >!einfach nicht in jeder zeile verwendet habe . Ich denke, sie werden mir nicht angezeigt, als ich sie schrieb. Interessanterweise verdirbt der SE-Parser es nicht :)
vsz
1
Ich wusste, dass in der Sekunde, in der ich ein lokales Include "stdio.h"anstelle des eigentlichen Library- Includes sah, etwas Hinterhältiges im Gange war<stdio.h>
Braden Best
1
In dem Moment, als ich die überflüssigen Kommentare sah, sagte ich laut: "Wo ist der Trigraph? Es muss einen Trigrap geben - Ah, da ist er."
Katze
19

Leerzeichen

Leider kann ich mein Programm hier nicht anzeigen, da StackExchange alle nachgestellten Leerzeichen entfernt. Das gleiche gilt für pastebin.com und pastie.org, daher kann ich auch keine Links dazu erstellen.

Natürlich sieht das gesamte Programm "nutzlos" aus, aber wenn Sie eine Zeile entfernen, ändert sich etwas.

Timwi
quelle
41
Aber zum Glück geht nichts von Wert verloren, denn die gesamte Sprache ist nutzlos :-)
zimperliches Ossifrage
1
@ Timwi was ist mit dem Feld "Rohdaten einfügen"?
Braden Best
1
@Timwi Getestet habe ich es gerade hier , und ich sehe , was Sie meinen. Wenn Sie jedoch Text ohne Leerzeichen einfügen, wird dieser gesendet, und die Rohdaten für das Einfügen bleiben unberührt. ZB könnten Sie eine zusätzliche Zeile einfügen, in der steht: "Kopieren Sie die Rohdaten und löschen Sie diese Zeile"
Braden Best
8
Ersetze \ t durch t. Ersetze "" mit s, ersetze \ n mit n
Cruncher
7
Bester Streich aller Zeiten: Posten Sie etwas, ohne tatsächlich Code zu schreiben.
Kaz Wolfe
9

JavaScript:

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

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

Der Grund , es funktioniert , ist , weil der Körper von dem forist b+-, nicht b++oder b--; Wenn Sie die erforderliche Zeile entfernen, wird daher bder Wert von hinzugefügt -alert(a).

Zahnbürste
quelle
"es erhöht bden Wert von alert(a)": Soll das nicht b+-sein b+=?
Gaurang Tandon
@ GaurangTandon Nein; Die Idee ist, dass es aussieht wie b++oder b--.
Zahnbürste
was bedeutet eigentlich b + -?
Mhmd
5
@ user689 b + -2 + 2. Wenn Sie die Zeile mit löschen 2 + 2;, wird dies zu ausgewertet b + -alert(a);.
Zahnbürste
8

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;
}

Wenn Sie die Zeile löschen, i = i;funktioniert der Code nicht. Das ist weil...

... in der Tat wird es nicht einmal kompilieren. Gemäß dem C - Standard - Labels wie skip im obigen Beispiel muss mit einer Anweisung zugeordnet werden. Sogar ein einzelnes Semikolon hätte ausgereicht, aber wenn Sie die gesamte Zeile löschen, ist der Bezeichnung keine Anweisung zugeordnet, und die Kompilierung schlägt fehl. Diese Antwort wird etwas ausführlicher erklärt.

zimperliches Ossifrage
quelle
7

APL

Hier ist eine APL-Funktion:

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

Es macht dasselbe wie Js Monade 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

Es kann ein optionales linkes Argument verwendet werden, das den Offset angibt:

      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

Die Linie ⍺←⎕IO ⋄ ⎕IO←⍺sieht nutzlos ( „assign ⎕IOzu , weisen Sie dann auf ⎕IO“), aber der erste Teil läuft nur , wenn keine linke Argument gegeben ist, so in der Tat ist es etwas tut:

  • Wenn nein, wird auf (global) gesetzt ⎕IO.
  • setze (lokal) ⎕IOauf
Marinus
quelle
7

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);

Die Variable fibomuss zugewiesen werden, bevor Sie sie in einem Lambda verwenden können, auch wenn Sie dieses Lambda sich fiboselbst zuweisen . Wenn Sie die (scheinbar nutzlose) Zuweisung entfernen, tritt ein Compilerfehler auf („Verwendung der nicht zugewiesenen lokalen Variablen 'fibo'“).

Ben Reich
quelle
Es handelt sich nicht um eine Nullreferenzausnahme, sondern um einen nicht initialisierten Variablen-Compilerfehler. Verschieben Sie die Deklaration auch besser in eine eigene Zeile, da die Deklaration nicht unbrauchbar ist.
Kendall Frey
@KendallFrey Guter Punkt! Fest.
Ben Reich
5

Windows Batch:

echo hello
pause
echo world

Stellen Sie das Programm ein und ändern Sie die Datei auf:

rem test01
pause
echo hello world

Wenn Sie den Kommentar entfernen oder seine Größe ändern, führt dies zu Problemen, da die erste Instanz des Programms angehalten wird und die Interpretation ab dem 19. Byte fortgesetzt wird.

OJW
quelle
Ich sehe keine Kommentare.
Orion
4
REM (Bemerkung) ist der Kommentaroperator - stackoverflow.com/questions/11269338
OJW
4

Java

package stackexchange;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class Curl
{
    public void getUrl(String address)
    {
        try {
            URL url = new URL(address);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            BufferedReader input = new BufferedReader(new InputStreamReader(conn.getInputStream()));

            /* don't remove this line! */
            http://codegolf.stackexchange.com

            while( true ){
                String line = input.readLine();
                if( line==null ) break http;
                System.out.println(line);
            }

            input.close();

        } catch(IOException ex){
            // ignore.
        }
    }

    public static void main(String[] args) {
        Curl curl = new Curl();
        curl.getUrl("http://codegolf.stackexchange.com");
    }
}

Es ist ein Arbeitsprogramm, das eine Webseite von einer URL abruft. Sie könnten überrascht sein, dass die Leitung

            http://codegolf.stackexchange.com

kompiliert ohne Warnung. Tatsächlich kompiliert das Programm ohne es nicht.

Es ist eigentlich ein Etikett http:, gefolgt von einem Kommentar //codegolf.... Das Etikett gilt für die Zeit und wird in der break http;Anweisung verwendet.

Florian F
quelle
1
Bitte eine Erklärung, oder ich werde diese Zeile entfernen, was auch immer Sie sagen.
Bill Woodger
3

Rubin

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

Ein ähnliches Problem trat kürzlich bei der Arbeit auf - ein Mitarbeiter hat meine scheinbar unnötige Initialisierung während der Codeüberprüfung markiert, und ich war wirklich versucht, die Erklärung in einen Spoilerblock zu stecken. Also mache ich das hier.

Die Zeile ist erforderlich, da eine in einem Block initialisierte Variable für diesen Block lokal ist. Wenn wir es außerhalb des Blocks initialisieren, kann der Wert in den Gültigkeitsbereich der Methode übergehen.

Ausgabe wie sie ist:

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

Ausgabe mit entfernter erster Zeile der Methode:

undefinierte lokale Variable oder Methode `match 'für main: Object (NameError)

Histokrat
quelle
1
Es ist ziemlich offensichtlich, warum dies erforderlich ist ... und auf jeden Fall wäre ein besserer Weg, dies zu schreiben, einfachmatch = Prime.find { |n| n.to_s[regexp] }
Türklinke
1
Das würde nicht das tun, was ich will ... gibt Prime.findzurück n(zB 223) und matchmuss sein n.to_s[regexp](zB "22"). Offensichtlich habe ich mir das Problem ausgedacht, dies notwendig zu machen.
Histokrat
Ah, sorry, habe nicht bemerkt , Sie riefen findauf Primeund nicht ein Array. Wie auch immer, es ist immer noch ziemlich leicht zu bemerken, warum diese Leitung benötigt wird ...
Türklinke
Meinetwegen. Vielleicht war mein Kollege nur unaufmerksam.
Histokrat
Huh. Keine Variablendeklarationen, aber der umgekehrte Ansatz zur Standardeinstellung von local / nonlocal für das, was Python tut. Es wird komisch, wenn ich jemals beschließe, Ruby zu lernen.
user2357112 unterstützt Monica
3

PHP

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

Hier, \n//This is a comment ist notwendig. Ohne das läuft der Code nicht.

Zumindest ein \nChar ist erforderlich EOT;, um es ordnungsgemäß auszuführen

War ich
quelle
3

JAVASCRIPT

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

; // This must be here

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

Ohne das Semikolon awürde dann auch immer der Rückgabewert aus der 2. Funktion werden - in diesem Fall ist es undefined. Weil die ursprünglich zugewiesene Funktion asofort mit der zweiten Funktion als Argument ausgeführt wird b.

ankr
quelle
2

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 
       . 

Wenn Sie das obige Programm ausführen (jedes IBM Mainframe COBOL seit COBOL II (erster IBM Compiler bis 1985, wahrscheinlich auch andere IBM COBOLs), lautet die Ausgabe:

22.02.14 13.11.02 HALLO WELT!

Entfernen Sie jedoch die dreifach nutzlose Zeile "MOVE SPACE TO W-WHEN-COMPILED". (Das Feld hat einen Anfangswert für Leerzeichen, und in der nächsten Anweisung ist anderer Inhalt enthalten, und es wird trotzdem verzweigt.) Das Programm gibt keine Ausgabe aus und beendet (U4038) (dh es stürzt ab) mit der folgenden Meldung :

 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. 

(Der Nachrichtencode und der Text variieren zwischen den Compilern. Die Offsets hängen vom tatsächlich verwendeten Compiler und den Kompilierungsoptionen ab. Die Adresse hängt davon ab, wo das Programm beim Ausführen geladen wird.)

Der Grund ist der NEXT SENTENCE. Das ist ein Secret GO TO. Der Compiler sucht den nächsten Punkt in der Quelle und generiert eine Verzweigung zur folgenden Anweisung. Ab COBOL II wurde die Verwendung von Punkt / Periode gelockert. Ein Programm muss mit einem Punkt enden. In diesem Fall befindet sich der Zweig außerhalb des Programmendes.

Beide Programme kompilieren 100% sauber (keine Diagnosemeldungen, Return Code von Null).

Dieses Verhalten ist eine dumme "IBM-Erweiterung" für COBOL. Die 1985 Norm erlaubt es nicht , NEXT SENTENCEinnerhalb IF/ END-IF( CONTINUEanstelle verwendet wird, die ein no-op ist). IBM erlaubte es - und verursachte von Zeit zu Zeit schreckliche Fallstricke.

Bill Woodger
quelle
2
#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");
}

Einfaches String-Überlauf-Problem.

photoionisiert
quelle
1
Jeder vernünftige Compiler wird Ihnen eine "zu viele Initialisierer" -Diagnose geben.
Ben Voigt
Welche Plattform segfaults ohne blah? Hier mit OpenBSD 5.5 / amd64 und dem System gcc gibt es keine Fehler, egal ob es vorhanden ist oder nicht blah. Das kompilierte Programm weist 16 Bytes Stapelspeicherplatz zu und kopiert den 16-Bit-Wert "ok" in die ersten 2 Bytes. Das nicht initialisierte 3. Byte hat zum Glück '\ 0'. Wenn blahvorhanden, befindet es sich im 16. Byte und beendet die Zeichenfolge immer noch nicht.
Kernigh
2

~ - ~!

Dies ist wahrscheinlich die dümmste und offensichtlichste hier.

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

Ohne diese zweite Zeile wird ein Fehler ausgegeben und damit gedruckt y.

der Backslash ist kein Fluchtcharakter, hehe.

cjfaure
quelle
Wie spricht man den Sprachnamen aus?
8
@professorfish~-~!
Timtech
1
@professorfish Das wäre "kein Kommentar".
cjfaure
1

Windows Batch

Dies ist eine Batch-Datei, die die Nummern 1 bis 10 mit jeweils einer leeren Zeile ausgibt:

@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

Dies nutzt effektiv einen schmutzigen Hack , um eine neue Zeile in einer Variablen zu speichern (die Verwendung von verzögerten Erweiterungen beseitigt die gruseligere NL-Zeile in der verknüpften Antwort). Wenn Sie die zwei völlig unnützen leeren Zeilen über dem Kommentar entfernen oder auf andere Weise ändern, funktioniert dies nicht.

Bob
quelle
0

troff

Troff ist das wunderbarste Textverarbeitungssystem. Ich benutze es für meine Dokumente. Es erfordert ein Makrosystem, um einsatzbereit zu sein, und das bekannteste ist das msMakropaket. Kompilieren wir den folgenden Code mit der klassischen -msOption.

.\" -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.

Die dritte Zeile scheint nutzlos zu sein und wäre ohne das Makropaket eigentlich nutzlos. Da zwei Zeilen darunter eine absolute vertikale Positionierung folgt, kann es sinnlos erscheinen, vorher nichts zu drucken. Aber ohne dieses unsichtbare Zeichen hat die vertikale Positionierung keine Auswirkung, obwohl ich nicht sicher bin, ob ich erklären kann, warum (siehe diesen Thread, wenn Sie einen Blick auf die Diskussion werfen möchten). Dies macht den neuen Benutzer verrückt, aber dann sollte der Trick dem erfahreneren Benutzer vertraut werden.

Ich habe gerade mit meiner Lieblingsversion von troff nachgesehen, die nicht sehr bekannt ist (Erbstück troff), aber ich bin mir ziemlich sicher, dass es mit GNU troff immer noch genauso funktioniert.

Thomas Baruchel
quelle
Schön, das passiert auch in LaTeX. Ohne ein leeres Kästchen oder ähnliches funktioniert der vertikale Abstand nicht richtig.
Orion