Napisz wiersz w programie, który wygląda na bezużyteczny [zamknięty]


26

Napisz jakiś program (rozmiar nie ma znaczenia) i wstaw linię, która wygląda na bezużyteczną, ale tak naprawdę nie jest - jeśli zostanie usunięta, program się zawiesi lub zrobi coś złego. Możesz zaznaczyć linię, która wygląda nieużywana przez komentarz, lub wspomnieć o swoim opisie kodu, tak jak w przykładzie poniżej (oczywiście w tym przykładzie linia nie jest tak naprawdę potrzebna, to tylko przykład).

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

    return 0;
}

Ponieważ jest to konkurs popularności, rozwiązanie z największą liczbą głosów wygrywa.


2
Dlaczego linia w tym przykładzie jest konieczna?
Gari BN

3
@GariBN To nie jest: „w tym przykładzie linia nie jest tak naprawdę potrzebna, to tylko przykład”.
elixenide

9
@EdCottrell Dobrze wiedzieć ... Myślałem, że przegapiłem podstawową rzecz ...
Gari BN

2
Więc to jest potrzebne. Na przykład. :-)
Florian F

1
Głosuję za zamknięciem tego pytania jako nie na temat, ponieważ słabe wyzwania nie są już na tej stronie tematem. meta.codegolf.stackexchange.com/a/8326/20469
kot

Odpowiedzi:


33

do

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

Nie skompilujemy się, jeśli usuniemy singiel ;.

EDYCJA :

Rozwiązanie poniżej:

Dzieje się tak, ponieważ caseinstrukcja jest po prostu etykietą i jako taka musi następować instrukcja (którą standard określa jako „specyfikator działań do wykonania”, co wyklucza deklaracje). Aby temu zapobiec, należy poprzedzić deklarację z ;, a oświadczenie zerowej . Specyfikacje caseetykiety można znaleźć tutaj na stronie 142 (131 w dokumencie)


4
GCC mówi „etykieta może być tylko częścią oświadczenia, a oświadczenie nie jest oświadczeniem”.
Vortico

1
Właśnie mnie to ugryzło w programie, który piszę dla szkoły.
Kevin - Przywróć Monikę

To sprawia, że ​​prawdziwe programy wyglądają tak brzydko: \.
val mówi Przywróć Monikę

23

C / C ++

Tylko trochę kodu napisanego w stylu wprowadzenia / samouczka ...

Samouczek nr. 2 : czytanie liczb, wykonywanie na nich operacji matematycznych i drukowanie wyników.

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

}

Usunięcie linii, result = 42;która na pierwszy rzut oka wydaje się zarówno zbędna, a biorąc pod uwagę podany cel, faktycznie niewłaściwy, spowoduje, że program nie zrobi tego, co stwierdza opis.

Czemu?

Trójkąty znów uderzają! ?? / zostanie zastąpione przez preprocesor przez \ , co z kolei połączy kolejną linię z komentarzem. Wynik = 42; staje się częścią komentarza, więc „zapisuje” linię drukowania. Z wynikiem = 42; linia usunięta, linia printf zostanie połknięta przez komentarz. Niektóre kompilatory mogą dawać ostrzeżenie lub trygrafy mogą być domyślnie wyłączone i muszą być włączone, aby ten przykład działał. Podświetlanie składni również może go zdradzić, ale istnieją kompilatory i środowiska IDE, które nie pozostawiają mądrzejszego.


Przynajmniej w gcc musisz określić, że chcesz używać trigrafów, dodając tę ​​flagę (-trigraphs). Bez tego gcc podnosi ostrzeżenie i ignoruje trygrafy.
Gari BN

4
Niezłe! Cieszę się, że nie przewinąłem zbyt daleko, zanim się zorientowałem. Możesz zmienić cytat w tekst spoilera, zaczynając od >!zamiast zamiast >.
wrażliwy ossifrage

@squeamishossifrage: dzięki, to był mój pierwotny zamiar, użyłem >!nie tylko w każdej linii. Myślałem, że nie wyświetlają się dla mnie, gdy je napisałem. Co ciekawe, parser SE nie psuje go :)
vsz

1
Wiedziałem, że coś dziwnego się zaczęło, gdy tylko zobaczyłem lokalną "stdio.h"<stdio.h>
dołączonej

1
W chwili, gdy zobaczyłem zbędne komentarze, powiedziałem na głos: „Gdzie jest trygraf? Musi być trygrap… Ach, tam jest”.
kot

19

Biała przestrzeń

Niestety nie mogę wyświetlić tutaj mojego programu, ponieważ StackExchange usuwa wszystkie końcowe białe znaki. To samo dotyczy pastebin.com i pastie.org, więc nie mogę również link do tego.

Oczywiście cały program „wygląda na bezużyteczny”, ale jeśli usuniesz dowolną linię, zrobi to coś innego.


41
Ale na szczęście nic wartościowego nie zostanie utracone, ponieważ cały język jest bezużyteczny :-)
piskliwy ossifrage

1
@Timwi co z polem „surowe dane wklejania”?
Braden Best

1
@ Timwi Właśnie przetestowałem to tutaj i rozumiem, co masz na myśli. Ale jeśli umieścisz tekst inny niż biały, zostanie on przesłany, a dane surowego wklejania pozostaną nietknięte. Np. Możesz wstawić dodatkowy wiersz z napisem „Skopiuj surowe dane wklej i usuń ten wiersz”
Braden Best

8
zamień \ t na t. Zamień „” na s, zamień \ n na n
Cruncher

7
Najlepszy dowcip w historii: opublikuj coś bez pisania kodu.
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);

Powodem tego jest to, że ciało forjest b+-, nie b++lub b--; dlatego jeśli usuniesz wymagany wiersz, zwiększy bon wartość -alert(a).


„doda to bwartości alert(a)”: A więc nie powinno b+-być b+=?
Gaurang Tandon

@GaurangTandon No; Chodzi o to, że wygląda jak b++lub b--.
Szczoteczka do zębów

co właściwie oznacza b + -?
Mhmd

5
@ user689 b + -2 + 2. Dlatego jeśli usuniesz wiersz za pomocą 2 + 2;, zostanie wyświetlone b + -alert(a);.
Szczoteczka do zębów

8

DO:

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

Jeśli usuniesz wiersz, i = i;kod nie będzie działał. To dlatego, że...

... w rzeczywistości nawet się nie skompiluje. Zgodnie ze standardem C etykiety takie jak pominąć w powyższym przykładzie muszą być powiązane z instrukcją. Wystarczyłby nawet pojedynczy średnik, ale jeśli usuniesz cały wiersz, etykieta nie będzie miała powiązanej instrukcji i kompilacja się nie powiedzie. Ta odpowiedź wyjaśnia nieco bardziej szczegółowo.


7

APL

Oto funkcja APL:

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

To nie to samo, co monadycznego J za 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

Może przyjąć opcjonalny lewy argument, który daje przesunięcie:

      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

Linia ⍺←⎕IO ⋄ ⎕IO←⍺wygląda na bezużyteczną („przypisuj ⎕IOdo , a następnie przypisuj do ⎕IO”), ale pierwsza część działa tylko wtedy, gdy nie podano lewego argumentu, więc w rzeczywistości coś robi:

  • jeśli nie podano, ustaw na (globalny) ⎕IO.
  • ustaw (lokalnie) ⎕IOna

7

DO#

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

Zmienna fibomusi zostać przypisana, zanim będzie można jej użyć wewnątrz lambda, nawet jeśli przypisujesz ją do fibosiebie. Jeśli usuniesz (pozornie bezużyteczne) przypisanie, wystąpi błąd kompilatora („Korzystanie z nieprzypisanej zmiennej lokalnej„ fibo ””).


To nie jest wyjątek zerowy, to błąd niezainicjowanego kompilatora zmiennych. Lepiej też przenieś deklarację do własnej linii, ponieważ deklaracja nie jest bezużyteczna.
Kendall Frey

@KendallFrey Dobra uwaga! Naprawiony.
Ben Reich

5

Pakiet Windows:

echo hello
pause
echo world

Ustaw działający program i zmodyfikuj plik, aby:

rem test01
pause
echo hello world

Jeśli usuniesz lub zmienisz rozmiar komentarza, spowoduje to spustoszenie, ponieważ pierwsza instancja programu wstrzymuje się, a następnie kontynuuje tłumaczenie od 19. bajtu.


Nie widzę żadnych komentarzy.
orion

4
REM (uwaga) jest operatorem komentarzy - stackoverflow.com/questions/11269338
OJW

4

Jawa

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

Jest to działający program, który pobiera stronę internetową z adresu URL. Możesz być zaskoczony, że linia

            http://codegolf.stackexchange.com

kompiluje się bez ostrzeżenia. W rzeczywistości program nie skompiluje się bez niego.

To właściwie etykieta http:, po której następuje komentarz //codegolf.... Etykieta dotyczy chwili i jest używana w break http;instrukcji.


1
Proszę o jakieś wyjaśnienie, inaczej usunę ten wiersz, cokolwiek powiesz.
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

Podobna sytuacja pojawiła się ostatnio w pracy - współpracownik faktycznie oznaczył moją, jak się wydaje, niepotrzebną inicjalizację podczas przeglądania kodu, a ja bardzo chciałem umieścić wyjaśnienie w bloku spoilera. Więc zrobię to tutaj.

Linia jest konieczna, ponieważ zmienna zainicjowana wewnątrz bloku jest lokalna dla tego bloku. Jeśli zainicjujemy go poza blokiem, wówczas wartość będzie mogła uciec do zakresu metody.

Dane wyjściowe takie jak:

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

Dane wyjściowe z usuniętym pierwszym wierszem metody:

niezdefiniowana zmienna lokalna lub metoda `match 'dla main: Object (NameError)


1
To dość oczywiste, dlaczego jest to potrzebne ... a zresztą lepszym sposobem na napisanie tego byłoby po prostumatch = Prime.find { |n| n.to_s[regexp] }
Klamka

1
To nie zrobiłoby tego, co chcę ... Prime.findzwraca n(np. 223) i matchmusi być n.to_s[regexp](np. „22”). Oczywiście wymyśliłem ten problem, aby było to konieczne.
histokrata

Ach, przepraszam, nie zauważył pan dzwoni findna Primea nie tablicy. W każdym razie wciąż dość łatwo jest zauważyć, dlaczego ta linia jest potrzebna ...
Klamka

Słusznie. Może mój współpracownik był po prostu nieuważny.
histokrata

Huh Brak deklaracji zmiennych, ale przeciwne podejście do domyślnego ustawienia lokalnego / nielokalnego w stosunku do tego, co robi Python. To będzie dziwne, jeśli kiedykolwiek zdecyduję się nauczyć Ruby.
user2357112 obsługuje Monikę

3

PHP

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

Tutaj \n//This is a commentjest konieczne. Bez tego kod nie uruchomi się.

Po prawidłowym uruchomieniu \nkonieczne jest co najmniej charEOT;


3

JAVASCRIPT

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

; // This must be here

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

Bez średnika astałoby się wtedy jakąkolwiek wartością zwracaną z 2. funkcji - w tym przypadku jest undefined. Ponieważ funkcja pierwotnie przypisana azostanie wykonana natychmiast z drugą funkcją jako argumentem b.


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 
       . 

Jeśli uruchomisz powyższy program (dowolny COBOL IBM Mainframe od COBOL II (pierwszy kompilator IBM do standardu 1985, prawdopodobnie również inne COBOL IBM), wynikiem będzie:

02/22/14 13.11.02 CZEŚĆ ŚWIATA!

Jeśli jednak usuniesz potrójnie bezużyteczną linię „PRZENIEŚ MIEJSCE NA W-KIEDY”. (pole ma początkową wartość spacji i ma inną treść umieszczoną w nim w następnej instrukcji, i tak i tak jest rozgałęzione) program nie generuje danych wyjściowych i faktycznie przerywa (U4038) (co oznacza, że ​​się zawiesza) z następującym komunikatem :

 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. 

(kod i tekst wiadomości różnią się w zależności od kompilatora, przesunięcia zależą od faktycznego użytego kompilatora i opcji kompilacji, adres zależy od tego, gdzie program jest ładowany po wykonaniu EXECuted).

Powodem jest NEXT SENTENCE. Jest to Secret GO TO. Kompilator wyszukuje następny kropkę / kropkę w źródle i generuje gałąź do następującej instrukcji. Od COBOL II korzystanie z kropek / kropek zostało złagodzone. Program musi kończyć się kropką / kropką. W takim przypadku gałąź nie działa na końcu programu.

Oba programy kompilują się w 100% czysto (brak komunikatów diagnostycznych, kod powrotu zero).

To zachowanie jest głupim „rozszerzeniem IBM” do języka COBOL. Standard z 1985 r. Nie zezwala na NEXT SENTENCEwewnątrz IF/ END-IF( CONTINUEzamiast tego stosuje się, co nie jest możliwe). IBM na to pozwolił - od czasu do czasu powodując okropne Gotchas.


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

Prosty problem przepełnienia łańcucha.


1
Każdy przyzwoity kompilator da ci diagnozę „zbyt wielu inicjatorów”.
Ben Voigt

Która platforma nie działa poprawnie blah? Tutaj z OpenBSD 5.5 / amd64 i systemowym gcc, nigdy nie segreguje błędów, niezależnie od tego, czy blahtam jest. Skompilowany program przydziela 16 bajtów miejsca na stosie i kopiuje 16-bitową wartość „ok” do pierwszych 2 bajtów. Niezainicjowany trzeci bajt ma na szczęście „\ 0”. Jeśli blahtam jest, jest w szesnastym bajcie i wciąż nie kończy łańcucha.
kernigh

2

~ - ~!

To chyba najgłupszy i najbardziej oczywisty tutaj.

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

Zgłasza błąd bez tej drugiej linii i drukuje y.

ukośnik odwrotny nie jest ucieczką, hehe.


Jak wymawiasz nazwę języka?

8
@professorfish~-~!
Timtech

1
@professorfish To byłoby „bez komentarza”.
cjfaure

1

Pakiet Windows

To jest plik wsadowy, w którym po każdym drukowane są liczby od 1 do 10 z pustą linią:

@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

To skutecznie wykorzystuje brudny hack do przechowywania nowej linii w zmiennej (użycie opóźnionych rozszerzeń pozbywa się bardziej przerażającej linii NL w powiązanej odpowiedzi). Jeśli usuniesz lub w inny sposób zmienisz dwie całkowicie bezużyteczne puste linie nad komentarzem, cóż, to nie zadziała.


0

troff

Troff to najwspanialszy system przetwarzania tekstu. Używam go do swoich dokumentów. Wymaga systemu makr, aby być gotowym do użycia, a najbardziej znanym jest mspakiet makr. Skompilujmy następujący fragment kodu z -msopcją klasyczną .

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

Trzecia linia wydaje się bezużyteczna i faktycznie byłaby bezużyteczna bez pakietu makr. Ponieważ po dwóch liniach poniżej znajduje się absolutna pionowa pozycja, może wydawać się bez sensu nic przedrukować. Ale bez tego niewidzialnego charakteru pionowe pozycjonowanie nie przyniesie żadnego efektu, chociaż nie jestem absolutnie pewien, czy mógłbym wyjaśnić, dlaczego (zobacz ten wątek, jeśli chcesz rzucić okiem na dyskusję). To powoduje, że nowy użytkownik jest szalony, ale sztuczka powinna się zaznajomić z bardziej eksperymentowanym użytkownikiem.

Właśnie sprawdziłem z moją ulubioną wersją troffa, która nie jest bardzo znana (heirloom troff), ale jestem pewien, że nadal działa tak samo z GNU troff.


Fajnie, dzieje się tak również w LaTeX. Bez pustego pudełka lub czegoś podobnego pionowe odstępy nie działają poprawnie.
orion
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.