Warum bedeutet die Aussage “2i;” KEINEN Compilerfehler verursachen?

Lesezeit: 4 Minuten

Benutzeravatar von daltonfury42
daltonfury42

Anstatt von 2*ischrieb ich nachlässig 2i:

int foo(int i)
{
    2i;
    return 2i;
}

Ich habe erwartet, dass der Compiler den Fehler abfängt. Aber das tat es nicht. So ist 2i eine gültige Aussage in C? Wenn ja, was macht es? Verwirrt!

Ich habe mit gcc Version 5.3.0 kompiliert und hier ist die Assembly-Ausgabe:

    .file   "strange.c"
    .text
    .globl  foo
    .type   foo, @function
foo:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    %edi, -4(%rbp)
    nop
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   foo, .-foo
    .ident  "GCC: (GNU) 5.3.0"
    .section    .note.GNU-stack,"",@progbits

  • Welcher Compiler ist das?

    – Iharob Al Asimi

    3. Februar 2016 um 17:28 Uhr

  • Ich arbeite nicht mit _Complex Zahlen. Nach einigem Lesen im Standard und dem bereitgestellten Link denke ich, dass die Antwort von @iharob richtig ist.

    – zu ehrlich für diese Seite

    3. Februar 2016 um 17:37 Uhr

  • @Olaf Die schnellste Fourier-Transformation im Westen fftw nutzt die _Complex Typ. Das habe ich beim Schreiben einer Datenverarbeitungssoftware für meine Diplomarbeit herausgefunden (Eigentlich Physik, nicht Informatik oder ähnliches) – (Ich musste einen Tiefpassfilter anwenden, also Faltung, also schnelle Fourier-Transformation, also fftw).

    – Iharob Al Asimi

    3. Februar 2016 um 17:41 Uhr


  • @iharob: Hmm, ist das schneller als die ffte und wenn nicht, darf ich die schnellere benutzen, wenn ich im Westen wohne, aber östlich von dir? 😉 Im Ernst: Danke für die Info. Wie es aussieht, unterstützt der C-Standard nicht einmal eine ähnlich einfache Notation mit C11.

    – zu ehrlich für diese Seite

    3. Februar 2016 um 17:48 Uhr

  • Ein sehr gutes Beispiel für “.. nicht ‘Heureka’ sondern ‘Das ist lustig…'”!

    – Jongware

    3. Februar 2016 um 18:47 Uhr

Benutzeravatar von Iharob Al Asimi
Iharob Al-Asimi

Das ist ein gcc Verlängerungund 2i ist die imaginäre Konstante Geben Sie hier die Bildbeschreibung ein. Sie können also eine komplexe Zahl wie folgt schreiben:

#include <complex.h>

_Complex x = 4 + 5i;

  • Wow, das kam überraschend! Können Sie mir sagen, warum es funktioniert hat, auch wenn ich die Header-Datei complex.h nicht eingefügt habe?

    – daltonfury42

    3. Februar 2016 um 17:39 Uhr

  • @daltonfury42 Der Header ist für die _Complex Typ, 2i ist eine Konstante (wie gcc es versteht). Ergänzen Sie die std=c99 oder std=c11 Flagge kombiniert mit -Wall und du wirst eine Warnung sehen. Auch tatsächlich kehrt es nicht zurück 0 aber da sollte der Rückgabetyp sein _Complex und der Wert 0 + 2ikönnen Sie es nicht mit untersuchen printf(). Also vielleicht ist das genau das real Teil 0!

    – Iharob Al Asimi

    3. Februar 2016 um 17:40 Uhr


  • @daltonfury42: Das musst du nicht #include <float.h> (oder math.h), um Unterstützung zu erhalten Gleitkommakonstanten entweder.

    – zu ehrlich für diese Seite

    3. Februar 2016 um 17:45 Uhr

  • @daltonfury42 Das stimmt. Header-Dateien ändern die Sprachsyntax nicht, sie deklarieren nur Dinge wie Variablen, Funktionen, Typen usw.

    – Barmar

    3. Februar 2016 um 17:54 Uhr

  • @ daltonfury42 Obwohl es möglich gewesen wäre, die Erkennung dieser Syntax durch a #pragmadie complex.h ausstellen könnte. Aber sie haben es nicht so gemacht.

    – Barmar

    3. Februar 2016 um 17:55 Uhr

Benutzeravatar von chqrlie
chqrlie

2i ist ein gcc Erweiterung für ein komplexes Integer-Literal, eine reine imaginäre Zahl, die das Doppelte der Quadratwurzel von ist -1. Diese Erweiterung wird unterstützt von clang auch.

Es ist etwas überraschend, dass Ihre Kompilierung mit gcc 5.4.0 erzeugt die gepostete Assembly-Ausgabe:

  • Kompilieren weiter http://gcc.godbolt.org/# Ich erhalte einen Kompilierungsfehler von gcc 5.3.0: http://gcc.godbolt.org/#: error: cannot convert '__complex__ int' to 'int' in return.
  • Der gepostete Assemblycode für die Funktion foo ist falsch: es kehrt nicht zurück 0. Konvertieren der komplexen ganzzahligen Konstante 2i zu int sollte seinen Realteil zurückgeben 0.

Umgekehrt mit clang 3.7 kompiliert es ohne Warnung und generiert optimalen Code, aber natürlich nicht das, was Sie erwarten:

foo(int):                       # @foo(int)
    xorl    %eax, %eax
    retq

Diese Syntax kann in beliebiger Reihenfolge mit anderen Suffixen kombiniert werden. Kompilieren Sie den folgenden Code mit clang -Weverything gibt mir entsprechende Warnungen warning: imaginary constants are a GNU extension [-Wgnu-imaginary-constant]:

#include <stdio.h>

int main() {
    /* complex integer literals */
    printf("sizeof(2i) = %zd\n", sizeof(2i));
    printf("sizeof(2ui) = %zd\n", sizeof(2ui));
    printf("sizeof(2li) = %zd\n", sizeof(2li));
    printf("sizeof(2lli) = %zd\n", sizeof(2lli));
    /* complex floating point literals */
    printf("sizeof(2.i) = %zd\n", sizeof(2.i));
    printf("sizeof(2.fi) = %zd\n", sizeof(2.fi));
    printf("sizeof(2e0fi) = %zd\n", sizeof(2e0fi));
    printf("sizeof(2e0i) = %zd\n", sizeof(2e0i));
    /* alternate order */
    printf("sizeof(2il) = %zd\n", sizeof(2il));
    printf("sizeof(2ill) = %zd\n", sizeof(2ill));
    printf("sizeof(2.if) = %zd\n", sizeof(2.if));

    return 0;
}

Es erzeugt diese Ausgabe in meiner Umgebung:

sizeof(2i) = 8
sizeof(2ui) = 8
sizeof(2li) = 16
sizeof(2lli) = 16
sizeof(2.i) = 16
sizeof(2.fi) = 8
sizeof(2e0fi) = 8
sizeof(2e0i) = 16
sizeof(2il) = 16
sizeof(2ill) = 16
sizeof(2.if) = 8

Probieren Sie den letzten mit Ihrem Syntaxhervorhebungseditor aus ;-)

  • Nun, das habe ich bekommen, als ich GCC 5.3.0 auf meinem PC mit Arch Linux verwendet habe. Hier ist meine gcc-konfiguration, falls es dich interessiert.

    – daltonfury42

    4. Februar 2016 um 12:11 Uhr

1418650cookie-checkWarum bedeutet die Aussage “2i;” KEINEN Compilerfehler verursachen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy