2016-10-25 3 views
-8

Ich habe dieses Stück Code, der nur gut auf einigen Compilern läuft, aber auf meiner Uni-Linux-Maschine hat es einen interessanten Fehler. Es ist ein einfacher Code, und ich habe kompliziertere gemacht, aber die Tatsache ist, dass wenn ich -10 und -8 eingibt, es eingibt, wenn es nicht sollte, wo es prüft, ob das Produkt niedriger oder gleich 0 ist (in die Produktfunktion)C Glitch, könnte Compiler sein?

Wie gesagt, wenn ich es auf meinem persönlichen Laptop mit einem neueren gcc (der Maschine ist gcc Version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC), könnte das laufen ein Problem sein, kann nicht an etwas anderes denken), gibt es gut aus. Fragte einer meiner cs Dozenten und er kann aus einem Grund nicht denken, entweder

#include <stdio.h> 

long int p(long int b, long int e) 
{ 
    long int i; 
    long int prod; 
    prod = b * e; 

    if(prod <= 0) 
    return 0; 
    prod = 1; 
    for(i=b ; i<=e ; ++i) 
    prod*=i; 
    return prod; 
} 

int main(void) 
{ 
    long int b, e; 

    scanf("%li %li", &b, &e); 

    printf("The product from range %li to %li is %i \n", b, e, p(b,e)); 

    return 0; 
} 
+4

Also, was sagt der Debugger? 99.xxx% wenn "es ist der Compiler" Anweisungen sind falsch. Bitte sehen Sie [fragen], geben Sie die erforderlichen Informationen ein. Hinweis: C ist nach Wert! Deine 'Änderung' funktioniert nicht wie du denkst! Dies wurde schon tausend Mal zuvor gefragt, also sollte man etwas recherchieren (die Funktion wird häufig 'swap' genannt, welches das korrekte Verb ist). – Olaf

+3

'printf ("% i% i \ n ", b, e);' ein Long in einen Int-Deskriptor zu drucken, ist ein undefiniertes Verhalten. Dies ist möglicherweise nicht das einzige Problem. Ich schlage vor, alle Warnungen auf "Full" zu stellen und dann "-fehler" zu aktivieren. –

+3

Ihre Change-Funktion ist ein großer Noop. Es arbeitet mit allen lokalen Variablen und tut daher nicht das, was Sie offensichtlich denken. – kaylum

Antwort

0

Das Problem ist, dass auf einem 64-Bit-Build, %i mit einem long int zu lesen, oder ein zu drucken, führt zu undefinierten Verhalten . Das korrekte Format ist %li. (Auf einem 32-Bit-Build kann man oft mit der Formatkonflikte "wegkommen", und IIRC, ältere Versionen von GCC haben Sie nicht einmal davor gewarnt - aber GCC 6.2.0 warnt vor der Diskrepanz. Ob der Compiler warnt oder nicht, ist es immer noch ein Problem)

zum Beispiel dieser Code:.

#include <stdio.h> 

static 
long int p(long int b, long int e) 
{ 
    long int i; 
    long int prod; 
    prod = b * e; 

    printf("b = %ld; e = %ld; prod = %ld\n", b, e, prod); 

    if (prod <= 0) 
     return 0; 
    prod = 1; 
    for (i = b; i <= e; ++i) 
     prod *= i; 

    printf("prod = %ld\n", prod); 
    return prod; 
} 

int main(void) 
{ 
    long int b, e; 

    if (scanf("%li %li", &b, &e) == 2) 
    { 
     printf("b = %ld; e = %ld\n", b, e); 
     printf("The product from range %li to %li is %li \n", b, e, p(b, e)); 
    } 

    return 0; 
} 

Kann ausgeführt werden und produziert:

$ ./pd83 <<< '-10 -8' 
b = -10; e = -8 
b = -10; e = -8; prod = 80 
prod = -720 
The product from range -10 to -8 is -720 
$ 

Die <<< '-10 -8' ist Bash sprechen die beiden Zahlen eingeben auf der Standardeingabe des Programms. Beachten Sie das Drucken an vielen Stellen mit dem richtigen Formatbezeichner. Der Code würde nicht mit meinen Standard-Compiler-Optionen kompiliert - zum Teil, weil das Format Mismatches (Ausgabe für eine Kopie des Codes in pd73.c dargestellt):

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -c pd73.c 
pd73.c:3:10: error: no previous prototype for ‘p’ [-Werror=missing-prototypes] 
long int p(long int b, long int e) 
     ^
pd73.c: In function ‘main’: 
pd73.c:21:11: error: format ‘%i’ expects argument of type ‘int *’, but argument 2 has type ‘long int *’ [-Werror=format=] 
    scanf("%i %i", &b, &e); 
     ^
pd73.c:21:14: error: format ‘%i’ expects argument of type ‘int *’, but argument 3 has type ‘long int *’ [-Werror=format=] 
    scanf("%i %i", &b, &e); 
      ^
pd73.c:23:35: error: format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Werror=format=] 
    printf("The product from range %i to %i is %i \n", b, e, p(b,e)); 
           ^
pd73.c:23:41: error: format ‘%i’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Werror=format=] 
    printf("The product from range %i to %i is %i \n", b, e, p(b,e)); 
             ^
pd73.c:23:47: error: format ‘%i’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Werror=format=] 
    printf("The product from range %i to %i is %i \n", b, e, p(b,e)); 
              ^
cc1: all warnings being treated as errors 
$ 

Die erste Warnung ist halb akzeptabel; Ich würde mich nicht beschweren, obwohl Code, den ich schreibe, es nicht erzeugen würde. Die static ist eine Möglichkeit, es zu entfernen. Da keine andere Quelldatei die Funktion benötigt, kann sie statisch gemacht werden. Dies bedeutet, dass der Optimierer auch mehr optimieren kann. Die Alternative besteht darin, eine Prototypdeklaration für die Funktion einzubeziehen, bevor sie definiert wird. Wie die Fehlermeldung sagt, liegt das an dem Warnflag -Wmissing-prototypes.

Die anderen Warnungen sind alle ernsthafte Probleme.

+0

Wie Sie und andere vorgeschlagen, änderte die% i in% li und es funktioniert wie es sollte .. Vielen Dank für Ihre Geduld, Sie haben nur 1 Person mehr vorsichtig mit ihrem Code :) – Cosmin

Verwandte Themen