Écrivez une ligne dans le programme qui semble inutile [fermé]


26

Écrivez un programme (la taille n'a pas d'importance) et mettez une ligne qui semble inutile, mais ce n'est pas le cas - s'il était supprimé, le programme planterait ou ferait quelque chose de mal. N'hésitez pas à marquer la ligne qui semble inutilisée par un commentaire, ou à mentionner la description de votre code, comme dans l'exemple ci-dessous (bien sûr, dans cet exemple, la ligne n'est en fait pas nécessaire, c'est juste un exemple).

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

    return 0;
}

Comme c'est un concours de popularité, la solution avec le plus grand nombre de votes l'emporte.


2
Pourquoi la ligne de l'exemple est-elle nécessaire?
Gari BN

3
@GariBN Ce n'est pas: "dans cet exemple, la ligne n'est en fait pas nécessaire, c'est juste un exemple."
elixenide

9
@EdCottrell Bon à savoir ... Je pensais avoir raté quelque chose de base ...
Gari BN

2
Donc , il est nécessaire. Pour l'exemple. :-)
Florian F

1
Je vote pour fermer cette question comme hors sujet car les défis sournois ne sont plus sur le sujet sur ce site. meta.codegolf.stackexchange.com/a/8326/20469
cat

Réponses:


33

C

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

Ne sera pas compilé si nous supprimons le single ;.

MODIFIER :

Solution ci-dessous:

Cela se produit car une caseinstruction n'est qu'une étiquette et, en tant que telle, doit être suivie d'une instruction (que la norme appelle un "spécificateur pour les actions à effectuer", ce qui exclut les déclarations). Pour éviter cela, nous préfixons la déclaration avec ;, une déclaration nulle . Les spécifications de l' caseétiquette se trouvent ici à la page 142 (131 dans le document)


4
GCC dit "une étiquette ne peut faire partie que d'une déclaration et une déclaration n'est pas une déclaration".
Vortico

1
Je viens d'être mordu par cela dans un programme que j'écris pour l'école.
Kevin - Réintègre Monica

Cela rend les vrais programmes si moche en fait: \.
val dit Réintégrer Monica le

23

C / C ++

Juste du code écrit dans le style d'introduction / tutoriel ...

Tutorial nr. 2 : lire des nombres, effectuer des opérations mathématiques sur eux et imprimer les résultats.

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

}

La suppression de la ligne result = 42;qui, à première vue, semble à la fois superflue et, compte tenu de l'objectif déclaré, en fait faux, entraînera en fait le programme à ne pas faire ce que la description indique.

Pourquoi?

Les trigraphes frappent à nouveau! ?? / sera remplacé par le préprocesseur avec \ , qui, à son tour, concaténera la ligne suivante dans le commentaire. Le résultat = 42; devient une partie du commentaire, donc il "enregistre" la ligne d'impression. Avec le résultat = 42; ligne supprimée, la ligne printf sera avalée par le commentaire. Certains compilateurs peuvent donner un avertissement ou les trigraphes peuvent être désactivés par défaut et doivent être activés pour que cet exemple fonctionne. La mise en évidence de la syntaxe peut également la trahir, mais il existe des compilateurs et des IDE autour desquels vous ne serez pas plus sage.


Au moins dans gcc, vous devez spécifier que vous souhaitez utiliser des trigraphes en ajoutant ce drapeau (-trigraphs). Sans cela, gcc augmente l'avertissement et ignore les trigraphes.
Gari BN

4
Joli! Je suis content de ne pas avoir fait défiler trop loin avant de le comprendre. Vous pouvez changer votre blockquote en texte spoiler en le commençant par >!au lieu de simplement >.
squeamish ossifrage

@squeamishossifrage: merci, c'était mon intention initiale, je ne l'utilisais >!pas sur toutes les lignes. Je pense qu'ils ne s'affichent pas pour moi comme je les ai écrits. Fait intéressant, l'analyseur SE ne le gâche pas :)
vsz

1
Je savais qu'il y avait quelque chose de sournois à la seconde où j'ai vu une inclusion locale "stdio.h"au lieu de l'inclusion réelle de la bibliothèque,<stdio.h>
Braden Best

1
Au moment où j'ai vu les commentaires superflus, j'ai dit à haute voix: "Où est le trigraphe? Il doit y avoir un trigrap-- Ah, il est là."
chat

19

Espace blanc

Malheureusement, je ne peux pas montrer mon programme ici parce que StackExchange supprime tous les espaces en fin. La même chose est vraie pour pastebin.com et pastie.org, donc je ne peux pas y lier non plus.

Bien sûr, l' ensemble du programme «semble inutile», mais si vous supprimez une ligne, cela fera quelque chose de différent.


41
Mais heureusement rien de valeur ne sera perdu, car la langue entière est inutile :-)
squeamish ossifrage

1
@Timwi qu'en est-il de la boîte "données de pâte brutes"?
Braden Best

1
@Timwi Je viens de le tester ici , et je vois ce que tu veux dire. Mais si vous mettez du texte non blanc, il sera soumis et les données de collage brutes seront intactes. Par exemple, vous pouvez mettre une ligne supplémentaire disant "Copiez les données de pâte brutes et supprimez cette ligne"
Braden Best

8
remplacer \ t par t. Remplacer "" par s, remplacer \ n par n
Cruncher

7
Meilleure farce de tous les temps: publier quelque chose sans vraiment écrire de code.
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);

La raison pour laquelle cela fonctionne est parce que le corps de l' forest b+-, non b++ou b--; par conséquent, si vous supprimez la ligne requise, elle s'ajoutera à bla valeur de -alert(a).


"cela ajoutera à bla valeur de alert(a)": Alors, n'est-ce b+-pas b+=?
Gaurang Tandon

@GaurangTandon No; l'idée est qu'elle ressemble à b++ou b--.
Brosse à dents

que signifie réellement b + -?
Mhmd

5
@ user689 b + -2 + 2. C'est pourquoi si vous supprimez la ligne avec 2 + 2;, elle est évaluée b + -alert(a);.
Brosse à dents

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

Si vous supprimez la ligne, i = i;le code ne fonctionnera pas. Ceci est dû au fait...

... en fait, il ne compilera même pas. Selon la norme C, les étiquettes comme skip dans l'exemple ci-dessus doivent être associées à une instruction. Même un seul point-virgule aurait suffi, mais si vous supprimez la ligne entière, l'étiquette n'a aucune instruction associée et la compilation échoue. Cette réponse explique un peu plus en détail.


7

APL

Voici une fonction APL:

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

Cela fait la même chose que le monadique de 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

Il peut prendre un argument gauche facultatif qui donne le décalage:

      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 ligne ⍺←⎕IO ⋄ ⎕IO←⍺semble inutile ("assigner ⎕IOà , puis assigner à ⎕IO"), mais la première partie ne s'exécute que si aucun argument gauche n'est donné, donc en fait elle fait quelque chose:

  • si non est défini, définissez sur (global) ⎕IO.
  • définissez (local) ⎕IOsur

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 variable fibo doit être affectée avant de pouvoir l'utiliser dans un lambda, même si vous vous affectez ce lambda fibo. Si vous supprimez l'affectation (apparemment inutile), une erreur de compilation se produira («Utilisation de la variable locale non affectée« fibo »»).


Ce n'est pas une exception de référence nulle, c'est une erreur de compilation de variable non initialisée. Aussi, mieux déplacer la déclaration sur sa propre ligne, car la déclaration n'est pas inutile.
Kendall Frey

@KendallFrey Bon point! Fixé.
Ben Reich

5

Lot Windows:

echo hello
pause
echo world

Définissez le programme en cours d'exécution et modifiez le fichier pour:

rem test01
pause
echo hello world

Si vous supprimez ou redimensionnez le commentaire, cela causera des ravages car la 1ère instance du programme se met en pause puis continue d'interpréter à partir du 19e octet.


Je ne vois aucun commentaire.
orion

4
REM (remarque) est l'opérateur de commentaire - 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");
    }
}

Il s'agit d'un programme de travail qui récupère une page Web à partir d'une URL. Vous pourriez être surpris que la ligne

            http://codegolf.stackexchange.com

compile sans même un avertissement. En fait, le programme ne compile pas sans lui.

Il est en fait une étiquette, http:suivi d'un commentaire, //codegolf.... L'étiquette s'applique à while et est utilisée dans l' break http;instruction.


1
Une explication s'il vous plaît, ou je supprimerai cette ligne quoi que vous disiez.
Bill Woodger

3

Rubis

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

Une chose similaire est arrivée au travail récemment - un collègue a en fait signalé mon initialisation apparemment inutile lors de la révision du code, et j'ai été vraiment tenté de mettre l'explication dans un bloc de spoiler. Je vais donc le faire ici.

La ligne est nécessaire car une variable initialisée à l'intérieur d'un bloc est locale à ce bloc. Si nous l'initialisons en dehors du bloc, la valeur peut s'échapper vers la portée de la méthode.

Sortie telle quelle:

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

Sortie avec la première ligne de la méthode supprimée:

variable locale non définie ou méthode `match 'pour main: Object (NameError)


1
C'est assez évident pourquoi cela est nécessaire ... et de toute façon, une meilleure façon d'écrire ceci serait justematch = Prime.find { |n| n.to_s[regexp] }
Poignée de porte

1
Cela ne ferait pas ce que je veux ... Prime.findrenvoie n(par exemple 223), et matchdoit l'être n.to_s[regexp](par exemple "22"). Évidemment, j'ai inventé le problème pour que cela soit nécessaire.
histocrate

Ah, désolé, ne remarquez - vous appeliez findsur Primeet non un tableau. Quoi qu'il en soit, il est encore assez facile de remarquer pourquoi cette ligne est nécessaire ...
Poignée de porte

C'est suffisant. Peut-être que mon collègue était tout simplement inobservable.
histocrate

Huh. Pas de déclarations de variables, mais l'approche inverse de la mise en défaut locale / non locale de ce que fait Python. Ça va me sembler bizarre si je décide d'apprendre Ruby.
user2357112 prend en charge 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    

Ici, \n//This is a comment c'est nécessaire. Sans cela, le code ne fonctionnera pas.

Au moins un caractère \nest nécessaire après EOT;pour l'exécuter correctement


3

JAVASCRIPT

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

; // This must be here

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

Sans le point-virgule adeviendrait alors la valeur de retour de la 2e fonction - dans ce cas, c'est le cas undefined. Parce que la fonction initialement affectée à asera exécutée immédiatement avec la deuxième fonction comme argument 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 
       . 

Si vous exécutez le programme ci-dessus (n'importe quel IBM Mainframe COBOL depuis COBOL II (premier compilateur IBM au standard de 1985, probablement aussi d'autres COBOL IBM), la sortie est:

22/02/14 13.11.02 BONJOUR MONDE!

Cependant, si vous supprimez la ligne triplement inutile "DÉPLACER L'ESPACE VERS W-UNE FOIS COMPILÉ". (le champ a une valeur initiale d'espace et contient d'autres contenus dans l'instruction suivante, et il est de toute façon ramifié) le programme ne produit aucune sortie et en fait Abends (U4038) (ce qui signifie qu'il se bloque) avec le message suivant :

 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. 

(le code et le texte des messages varient selon les compilateurs, les décalages dépendent du compilateur réel utilisé et des options de compilation, l'adresse dépend de l'endroit où le programme est chargé lors de son exécution).

La raison en est NEXT SENTENCE. Ceci est un Secret GO TO. Le compilateur recherche le prochain point final / période dans la source et génère une branche vers l'instruction suivante. À partir de COBOL II, l'utilisation des arrêts complets / périodes a été assouplie. Un programme doit se terminer par un point / période complète. Dans ce cas, la branche est hors de la fin du programme.

Les deux programmes compilent 100% de nettoyages (pas de messages de diagnostic, code retour nul).

Ce comportement est une "extension IBM" stupide pour COBOL. La norme de 1985 ne permet pas NEXT SENTENCEdans IF/ END-IF( CONTINUEest utilisé à la place, ce qui est un no-op). IBM l'a autorisé - provoquant de temps en temps d'horribles 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");
}

Problème de débordement de chaîne simple.


1
Tout compilateur décent va vous donner un diagnostic "trop ​​d'initialiseurs".
Ben Voigt

Quelle plate-forme segfaults sans blah? Ici avec OpenBSD 5.5 / amd64 et le système gcc, il ne se sépare jamais, qu'il y soit ou non blah. Le programme compilé alloue 16 octets d'espace de pile et copie la valeur 16 bits de "ok" dans les 2 premiers octets. Le 3ème octet non initialisé a «\ 0» par chance. Si blahest là, il est dans le 16e octet et ne termine toujours pas la chaîne.
kernigh

2

~ - ~!

C'est probablement le plus stupide et le plus évident ici.

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

Il lance une erreur sans cette deuxième ligne, avec elle il imprime y.

la barre oblique inverse n'est pas un personnage d'échappement, hehe.


Comment prononcez-vous le nom de la langue?

8
@professorfish~-~!
Timtech

1
@professorfish Ce serait "aucun commentaire".
cjfaure

1

Lot Windows

Il s'agit d'un fichier batch qui imprime les numéros 1 à 10 avec une ligne vide après chacun:

@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

Cela utilise effectivement un hack sale pour stocker une nouvelle ligne dans une variable (l'utilisation d'extensions retardées supprime la ligne NL plus effrayante dans la réponse liée). Si vous supprimez ou modifiez les deux lignes vides complètement inutiles au-dessus du commentaire, cela ne fonctionnera pas.


0

troff

Troff est le système de traitement de texte le plus merveilleux. Je l'utilise pour mes documents. Il nécessite un système de macros pour être prêt à être utilisé, et le plus célèbre est le mspackage de macros. Compilons le morceau de code suivant avec l' -msoption classique .

.\" -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 troisième ligne semble être inutile, et serait en fait inutile sans le package de macro. Puisqu'il est suivi deux lignes ci-dessous par un positionnement vertical absolu, il pourrait sembler inutile de ne rien imprimer avant. Mais sans ce caractère invisible, le positionnement vertical n'aura aucun effet, même si je ne suis pas absolument sûr de pouvoir expliquer pourquoi (voir ce fil si vous voulez jeter un coup d'œil à la discussion). Cela rend le nouvel utilisateur fou, mais l'astuce devrait devenir familière à l'utilisateur le plus expérimenté.

Je viens de vérifier avec ma version préférée de troff qui n'est pas très connue (heirloom troff), mais je suis presque sûr que cela fonctionne toujours de la même manière avec GNU troff.


Bien, cela se produit également dans LaTeX. Sans boîte vide ou quelque chose de similaire, l'espacement vertical ne fonctionne pas correctement.
orion
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.