Scrivi una riga nel programma che sembra inutile [chiuso]


26

Scrivi un programma (le dimensioni non contano) e metti una linea che sembra inutile, ma in realtà non lo è - se venisse rimosso, il programma si arresterebbe in modo anomalo o farebbe qualcosa di sbagliato. Sentiti libero di contrassegnare la linea che sembra inutilizzata da un commento o di menzionarla nella descrizione del codice, come nell'esempio seguente (ovviamente, in questo esempio, la linea non è effettivamente necessaria, è solo un esempio).

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

    return 0;
}

Trattandosi di un concorso di popolarità, vince la soluzione con il maggior numero di voti.


2
Perché la riga nell'esempio è necessaria?
Gari BN,

3
@GariBN Non è: "in questo esempio, la linea in realtà non è necessaria, è solo un esempio".
elixenide,

9
@EdCottrell Buono a sapersi ... Pensavo di aver perso alcune cose basilari ...
Gari BN,

2
Quindi è necessario. Per l'esempio :-)
Florian F

1
Sto votando per chiudere questa domanda come fuori tema perché le sfide subdole non sono più in argomento su questo sito. meta.codegolf.stackexchange.com/a/8326/20469
cat

Risposte:


33

C

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

Non compileremo se rimuoviamo il singolo ;.

MODIFICA :

Soluzione di seguito:

Ciò accade perché caseun'istruzione è solo un'etichetta e, come tale, deve essere seguita da un'istruzione (che lo standard fa riferimento come "identificatore per le azioni da eseguire", che esclude le dichiarazioni). Per evitare ciò, anteponiamo la dichiarazione a a ;, un'istruzione null . Le specifiche per l' caseetichetta sono disponibili qui a pagina 142 (131 nel documento)


4
GCC afferma che "un'etichetta può far parte solo di un'istruzione e una dichiarazione non è un'affermazione".
Vortico,

1
Sono stato morso da questo in un programma che sto scrivendo per la scuola.
Kevin - Ripristina Monica il

Questo rende i programmi reali davvero così brutti: \.
dice Val Reinstate Monica il

23

C / C ++

Solo un po 'di codice scritto nello stile di introduzione / tutorial ...

Tutorial n. 2 : lettura di numeri, esecuzione di operazioni matematiche su di essi e stampa dei risultati.

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

}

Rimuovere la linea result = 42;che a prima vista sembra sia superflua e, considerando l'obiettivo dichiarato, in realtà errato, farà sì che il programma non faccia ciò che afferma la descrizione.

Perché?

Le trigrafi colpiscono di nuovo! ?? / sarà sostituito dal preprocessore con \ , che a sua volta concatenerà la riga successiva nel commento. Il risultato = 42; diventa parte del commento, quindi "salva" la linea di stampa. Con il risultato = 42; riga rimossa, la riga printf verrà ingoiata dal commento. Alcuni compilatori potrebbero dare un avviso, oppure le trigrafi potrebbero essere disattivate come predefinite e devono essere attivate affinché questo esempio funzioni. L'evidenziazione della sintassi potrebbe anche tradirlo, ma ci sono compilatori e IDE in giro che non ti lasciano più saggio.


Almeno in gcc, è necessario specificare che si desidera utilizzare le trigrafi aggiungendo questo flag (-trigraphs). Senza questo, gcc emette un avvertimento e ignora le trigrafi.
Gari BN,

4
Ben fatto! Sono contento di non essere scivolato troppo in basso prima di capirlo. Puoi modificare il tuo blockquote in testo spoiler avviandolo con >!invece di solo >.
ossifrage schifoso

@squeamishossifrage: grazie, questa era la mia intenzione originale, non l'ho >!mai usata in tutte le righe. Pensavo che non fossero visualizzati per me mentre li scrivevo. È interessante notare che il parser SE non lo rovina :)
vsz

1
Sapevo che stava succedendo qualcosa di subdolo nel momento in cui ho visto un'inclusione locale "stdio.h"anziché quella effettiva della biblioteca,<stdio.h>
Braden Best,

1
Nel momento in cui ho visto i commenti superflui che ho detto ad alta voce, "Dov'è la trigrafia? Deve esserci un trigrap ... Ah, eccolo."
gatto

19

Lo spazio bianco

Sfortunatamente non posso mostrare qui il mio programma perché StackExchange rimuove tutti gli spazi bianchi finali. Lo stesso vale per pastebin.com e pastie.org, quindi nemmeno io posso collegarmi ad esso.

Ovviamente, l' intero programma "sembra inutile", ma se rimuovi qualsiasi riga, farà qualcosa di diverso.


41
Ma per fortuna nulla di valore andrà perso, perché l' intera lingua è inutile :-)
ossifrage schizzinoso

1
@Timwi che dire della casella "dati di pasta grezza"?
Braden Best

1
@Timwi L'ho appena testato qui e capisco cosa intendi. Ma se si inserisce un testo non di spazi bianchi, verrà inviato e i dati di pasta grezza rimarranno intatti. Ad esempio, potresti inserire una riga aggiuntiva che dice "Copia i dati grezzi di incolla ed elimina questa riga"
Braden Best

8
sostituire \ t con t. Sostituisci "" con s, sostituisci \ n con n
Cruncher

7
Il miglior scherzo di sempre: pubblica qualcosa senza scrivere codice.
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);

Il motivo per cui funziona è perché il corpo dell'essere forè o b+-no ; pertanto, se si rimuove la riga richiesta, verrà aggiunta al valore di .b++b--b-alert(a)


"aggiungerà al bvalore di alert(a)": Quindi, non dovrebbe b+-essere b+=?
Gaurang Tandon,

@GaurangTandon No; l'idea è che sembra b++o b--.
Spazzolino da denti

cosa significa b + - attualmente?
Mhmd,

5
@ user689 b + -2 + 2. Ecco perché se elimini la riga con 2 + 2;, viene valutata b + -alert(a);.
Spazzolino da denti

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

Se elimini la riga, i = i;il codice non funzionerà. Questo è perché...

... in effetti non si compila nemmeno. Secondo lo standard C, etichette come skip nell'esempio sopra devono essere associate a un'istruzione. Anche un solo punto e virgola sarebbe stato sufficiente, ma se si elimina l'intera riga, l'etichetta non ha alcuna istruzione associata e la compilazione non riesce. Questa risposta spiega un po 'più in dettaglio.


7

APL

Ecco una funzione APL:

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

Fa la stessa cosa della monadica di J 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

Può prendere un argomento sinistro opzionale che fornisce l'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

La linea ⍺←⎕IO ⋄ ⎕IO←⍺sembra inutile ("assegnare ⎕IOa , quindi assegnare a ⎕IO"), ma la prima parte viene eseguita solo se non viene fornito alcun argomento sinistro, quindi in effetti fa qualcosa:

  • se non viene fornito, impostare su (globale) ⎕IO.
  • impostare (locale) ⎕IOsu

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

La variabile fibodeve essere assegnata prima di poterla utilizzare all'interno di una lambda, anche se si sta assegnando quella lambda a fibose stessa. Se si rimuove l'assegnazione (apparentemente inutile), si verificherà un errore del compilatore (“Uso della variabile locale non assegnata 'fibo'”).


Non è un'eccezione di riferimento null, è un errore del compilatore variabile non inizializzato. Inoltre, spostare meglio la dichiarazione sulla propria riga, poiché la dichiarazione non è inutile.
Kendall Frey,

@KendallFrey Ottimo punto! Fisso.
Ben Reich,

5

Batch di Windows:

echo hello
pause
echo world

Impostare il programma in esecuzione e modificare il file su:

rem test01
pause
echo hello world

Se rimuovi o ridimensiona il commento, causerà il caos mentre la prima istanza del programma si interrompe e continua a interpretare dal 19 ° byte in poi.


Non vedo alcun commento.
Orione,

4
REM (osservazione) è l'operatore di commento - stackoverflow.com/questions/11269338
OJW

4

Giava

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

È un programma di lavoro che recupera una pagina Web da un URL. Potresti essere sorpreso che la linea

            http://codegolf.stackexchange.com

compila senza nemmeno un avvertimento. In effetti, il programma non si compila senza di esso.

In realtà è un'etichetta, http:seguito da un commento, //codegolf.... L'etichetta si applica al momento e viene utilizzata break http;nell'istruzione.


1
Qualche spiegazione per favore, o rimuoverò quella riga qualunque cosa tu dica.
Bill Woodger,

3

Rubino

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

Una cosa simile è venuta al lavoro di recente: un collega in realtà ha segnalato la mia inizializzazione apparentemente non necessaria durante la revisione del codice e sono stato davvero tentato di inserire la spiegazione in un blocco di spoiler. Quindi lo farò qui.

La linea è necessaria perché una variabile inizializzata all'interno di un blocco è locale per quel blocco. Se lo inizializziamo all'esterno del blocco, il valore è in grado di uscire dall'ambito del metodo.

Uscita così com'è:

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

Output con la prima riga del metodo rimosso:

variabile locale non definita o metodo `match 'per main: Object (NameError)


1
È abbastanza ovvio il motivo per cui è necessario ... e comunque, un modo migliore per scrivere questo sarebbe solomatch = Prime.find { |n| n.to_s[regexp] }
Doorknob

1
Quello non farebbe quello che voglio ... Prime.findritorna n(es. 223), e matchdeve essere n.to_s[regexp](es. "22"). Ovviamente ho escogitato il problema per renderlo necessario.
istocrato

Ah, mi dispiace, non si accorse che stavi chiamando findsu Primee non un array. Ad ogni modo, è ancora abbastanza facile notare perché quella linea è necessaria ...
Maniglia della porta

Giusto. Forse il mio collega non stava osservando.
istocratico

Huh. Nessuna dichiarazione variabile, ma l'approccio opposto al default locale / non locale rispetto a quello che fa Python. Sarebbe strano se mai decidessi di imparare Ruby.
user2357112 supporta 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    

Qui \n//This is a commentè necessario. Senza di esso il codice non verrà eseguito.

\nÈ necessario almeno un carattere dopo EOT;averlo eseguito correttamente


3

JAVASCRIPT

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

; // This must be here

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

Senza il punto e virgola adiventerebbe il valore restituito dalla seconda funzione, in questo caso lo è undefined. Perché la funzione inizialmente assegnata averrà eseguita immediatamente con la seconda funzione come argomento b.


2

COBOL (mainframe IBM)

   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 
       . 

Se si esegue il programma sopra (qualsiasi COBOL mainframe IBM dal COBOL II (primo compilatore IBM allo standard 1985, probabilmente anche altri IBM COBOL) l'output è:

22/02/14 13.11.02 CIAO MONDO!

Tuttavia, se si rimuove la linea triplicamente inutile "SPOSTA SPAZIO SU W-QUANDO COMPILATO". (il campo ha un valore iniziale di spazio e contiene altro contenuto inserito nell'istruzione successiva ed è comunque ramificato) il programma non produce alcun output e effettivamente Abends (U4038) (significa che si arresta in modo anomalo) con il seguente messaggio :

 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. 

(il codice e il testo del messaggio variano tra i compilatori, gli offset dipendono dall'effettivo compilatore utilizzato e dalle opzioni di compilazione, l'indirizzo dipende da dove viene caricato il programma quando viene eseguito).

Il motivo è il NEXT SENTENCE. Questo è un Secret GO TO. Il compilatore cerca il punto / punto successivo successivo nella sorgente e genera un ramo alla seguente istruzione. Da COBOL II, l'uso di punti pieni / periodi è stato rilassato. Un programma deve terminare con un punto / punto completo. In questo caso, il ramo è fuori dalla fine del programma.

Entrambi i programmi vengono compilati al 100% (nessun messaggio diagnostico, codice di ritorno pari a zero).

Questo comportamento è una stupida "estensione IBM" di COBOL. Lo standard del 1985 non consente NEXT SENTENCEall'interno IF/ END-IF( CONTINUEviene utilizzato invece, che è un non-op). IBM lo permetteva, causando di tanto in tanto orribili Gotcha.


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

Problema di overflow della stringa semplice.


1
Qualsiasi compilatore decente ti fornirà una diagnostica "troppi inizializzatori".
Ben Voigt,

Quale piattaforma segfault senza blah? Qui con OpenBSD 5.5 / amd64 e il sistema gcc, non segfa mai, indipendentemente dal fatto che blahci sia o meno . Il programma compilato alloca 16 byte di spazio dello stack e copia il valore a 16 bit di "ok" nei primi 2 byte. Il 3 ° byte non inizializzato ha '\ 0' per fortuna. Se blahè presente, si trova nel sedicesimo byte e non termina ancora la stringa.
kernigh,

2

~ - ~!

Questo è probabilmente il più stupido, il più ovvio qui.

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

Genera un errore senza quella seconda riga, con la quale stampa y.

la barra rovesciata non è un personaggio di fuga, hehe.


Come si pronuncia il nome della lingua?

8
@professorfish~-~!
Timtech,

1
@professorfish Sarebbe "nessun commento".
cjfaure,

1

Windows Batch

Questo è un file batch che stampa i numeri da 1 a 10 con una riga vuota dopo ciascuno:

@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

Questo fa effettivamente uso di un hack sporco per memorizzare una nuova riga all'interno di una variabile (l'uso di espansioni ritardate elimina la linea NL dall'aspetto più spaventoso nella risposta collegata). Se rimuovi o modifichi in altro modo le due righe vuote completamente inutili sopra il commento, beh, non funzionerà.


0

troff

Troff è il più meraviglioso sistema di elaborazione del testo. Lo uso per i miei documenti. Richiede un sistema macro per essere pronto per essere utilizzato, e il più famoso è il mspacchetto macro. Compiliamo il seguente pezzo di codice con l' -msopzione classica .

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

La terza riga sembra essere inutile e in realtà sarebbe inutile senza il pacchetto macro. Poiché è seguito da due righe in basso da un posizionamento verticale assoluto, potrebbe sembrare insignificante non stampare nulla prima. Ma senza questo personaggio invisibile, il posizionamento verticale non avrà alcun effetto, anche se non sono assolutamente sicuro di poter spiegare il perché (vedi questa discussione se vuoi dare un'occhiata alla discussione). Questo fa impazzire il nuovo utente, ma il trucco dovrebbe diventare familiare all'utente più sperimentato.

Ho appena controllato con la mia versione preferita di troff che non è molto conosciuta (heirloom troff), ma sono abbastanza sicuro che funzioni ancora allo stesso modo con GNU troff.


Bello, questo succede anche in LaTeX. Senza una scatola vuota o qualcosa di simile, la spaziatura verticale non funziona correttamente.
Orione,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.