Frank Schönmann: Benötigt er ein IQ-Upgrade?

Beitrag lesen

hi!

Das glaube ich spontan erstmal nicht... :) Was sollte den
Optimierer in dem Fall davon abhalten, a=a+1; zu a++; zu
optimieren, und dann ein INC daraus zu machen?
die Analyse von "'a=a+1' == 'a++'" dauert länger als die von
"'a++' == 'a++'". Abgesehen davon wird in allen mir bekannten
Systemen bei 'a=a+1' tatsächlich der Wert 'a' mit dem Wert '1'
zusammengezählt und anschließend nach 'a' gespeichert, während bei
'a++' der Speicher direkt an der richtigen Stelle modifiziert
wird.

Dann mach ich mal eben einen Test mit dem Intel-Compiler. Folgendes
Programm:

=== cut ===
void main() {
  int a = 0;

a++;
  a+=1;
  a=a+1;

a+=2;
  a=a+2;
}
=== cut ===

(Angeblich komplett) ohne irgendwelche Optimierungen kommt dabei das
hier heraus (zum Nachvollziehen: die Parameter waren /S /GX- /GR-
/FAcs /Od):

=== cut ===
;;; void main() {

push      ebp                             ;test.c:1.13
        mov       ebp, esp                        ;test.c:1.13
        sub       esp, 3                          ;test.c:1.13
        and       esp, -8                         ;test.c:1.13
        add       esp, 4                          ;test.c:1.13
        sub       esp, 4                          ;test.c:1.13

;;;   int a = 0;

mov       DWORD PTR [ebp-4], 0            ;test.c:2.7

;;;   a++;

inc       DWORD PTR [ebp-4]               ;test.c:4.3

;;;   a+=1;

inc       DWORD PTR [ebp-4]               ;test.c:5.3

;;;   a=a+1;

inc       DWORD PTR [ebp-4]               ;test.c:6.5

;;;   a+=2;

add       DWORD PTR [ebp-4], 2            ;test.c:8.3

;;;   a=a+2;

add       DWORD PTR [ebp-4], 2            ;test.c:9.5

;;; }

xor       eax, eax                        ;test.c:10.1
        leave                                     ;test.c:10.1
        ret                                       ;test.c:10.1
=== cut ===

Der GNU-Compiler macht daraus (nur mit der Option -S) folgenden Code:

=== cut ===
_main:
 pushl %ebp
 movl %esp,%ebp
 subl $24,%esp
 call ___main
 movl $0,-4(%ebp)
 incl -4(%ebp)
 incl -4(%ebp)
 incl -4(%ebp)
 addl $2,-4(%ebp)
 addl $2,-4(%ebp)
L2:
 movl %ebp,%esp
 popl %ebp
 ret
=== cut ===

Und jetzt erzähl mir nochmal, bei diesen Anweisungen würden jeweils
unterschiedliche Instruktionen herauskommen. Der Intel-Compiler war
übrigens v5.0, der GNU-Compiler v2.95.3-5, beide unter Win2000.

bye, Frank!