2012-05-10 16 views
9

Der folgende Code kompiliert und läuft gut in C (zumindest nach 'gcc -std = gnu99'), aber es kompiliert nicht unter C++, was "Zeile 5: Fehler: kann nicht konvertieren Doppel 'zu' Doppel Komplex 'in Initialisierung ". Weiß jemand warum?C Komplexe Zahlen in C++?

#include "/usr/include/complex.h" 
#include <stdio.h> 

int main(int argc, char * argv[]) { 
    double complex a = 3; // ERROR ON THIS LINE 
    printf("%lf\n", creal(a)); 
    return 0; 
} 

Ich weiß, es ist eine andere Art und Weise komplexe Zahlen in C++ zu tun, aber ich habe C komplexe Zahlen in C++ zu verwenden, weil das ist, wie die Legacy-Code mir gegeben wurde, tut Dinge. Danke, wenn du helfen kannst!

+4

Aber wirklich, _why_ nicht wollen Sie [ 'std :: Komplex <>'] (http: // verwenden en.cppreference.com/w/cpp/numeric/complex)? – ildjarn

+2

FTR, '-std = gnu99' ist nicht wirklich die Flagge, die du für ** C ** willst. Das ist "C mit Sachen, die GNU dachte, wäre eine gute Idee, aber ob es ist oder nicht, ist für Interpretation". '-std = c99' ist wünschenswert, wenn Sie ** C ** wollen. –

+0

ildjarn: Leider verwendet die Bibliothek, mit der ich arbeite, C99 komplexe Zahlen in C++. Es scheint nicht ratsam, ein Projekt auf diese Weise zu starten, aber das ist der Code, mit dem ich arbeiten muss. Martinho: Das stimmt. Ich hätte den Test mit -std = c99 – iloveponies

Antwort

10

Verwenden der C Schlüsselwort für komplexe: _Complex. C++ verwendet Komplex als (Vorlage) -Klasse. Ich bin mir nicht sicher wo creal ist oder ich würde das auskommentieren.

#include <complex.h> 
#include <cstdio> 

int main(int argc, char * argv[]) { 
    double _Complex a = 3.0 + 0.0I; // DECLARATION WORKS NOW - NOTE ASSIGNMENT MUST HAVE IMAG PART 
    //printf("%lf\n", creal(a)); 
    return 0; 
} 

Das funktioniert in gcc (Ich kompilierte mit g ++). Ich habe eine Warnung über veraltete .h-Header erhalten.

Here ist ein Link zu einer E-Mail-Spur, die Nicht-Standard-Kompatibilität mit C++ und C mit komplexen Zahlen zeigt. C++ 11 erfordert Layout-Kompatibilität von C++ - Komplexen mit C _Complexes.

Ich untersuche zZ creal, etc. in C++. Ich finde nichts im Standard. Da anscheinend einige Anstrengungen unternommen werden, um eine Quellenkompatibilität zwischen C++ und C zu schaffen, können creal, cpow, etc. die Bibliotheksvorschläge um TR2 ergänzen.

+0

DANKE !!!!! Nach dem, was Sie gesagt haben, war ich in der Lage, die Lösung zu bekommen. Mit Stack Overflow kann ich die Lösung noch nicht posten, aber Sie müssen den Imaginärteil zur Zuweisung hinzufügen. – iloveponies

9

Compatibility of C and C++

Several additions of C99 are not supported in C++ or conflict with C++ features, such as variadic macros, compound literals, designated initializers, variable-length arrays, and native complex-number types. The long long int datatype and restrict qualifier defined in C99 are not included in the current C++ standard, but some compilers such as the GNU Compiler Collection[4] provide them as an extension. The long long datatype along with variadic templates, with which some functionality of variadic macros can be achieved, are present in the new C++ standard, C++11. On the other hand, C99 has reduced some other incompatibilities by incorporating C++ features such as // comments and mixed declarations and code.

15

Ein C++ - Compiler könnte wählen, das Schlüsselwort _Complex als Erweiterung zu unterstützen (und ein paar tun), aber das ist nicht tragbar. Wenn Sie eine portable C++ - Lösung haben möchten, müssen Sie leider die C++ std :: complex-Vorlagen verwenden.

Die gute Nachricht ist, dass C++ std :: komplexe Zahlen garantiert kompatibel mit C komplexen Zahlen sind (in dem Sinne, dass ein Zeiger auf einen immer in einen Zeiger auf den anderen konvertiert werden kann, und das Richtige wird passieren), was bedeutet, dass Sie keine Probleme haben werden, wenn Sie mit einer C-Bibliothek interoperieren müssen, die C-komplexe Werte erwartet.

C11:

Each complex type has the same representation and alignment requirements as an array type containing exactly two elements of the corresponding real type; the first element is equal to the real part, and the second element to the imaginary part, of the complex number.

C++ 11:

If z is an lvalue expression of type cv std::complex<T> then:

— the expression reinterpret_cast<cv T(&)[2]>(z) shall be well-formed,

reinterpret_cast<cv T(&)[2]>(z)[0] shall designate the real part of z , and

reinterpret_cast<cv T(&)[2]>(z)[1] shall designate the imaginary part of z .

+0

Wo ist diese Garantie ("C++ std :: komplexe Zahlen sind garantiert kompatibel mit komplexen C99-Zahlen")? Die Antwort unten (http://stackoverflow.com/a/10540288/2189128) zitiert eine nicht-kanonische Quelle (Wikipedia), die das Gegenteil sagen. – Jeff

+2

@Jeff: Der Wikipedia-Link widerspricht eigentlich nicht meinem Anspruch; Sie sind verschiedene Typen, haben aber garantiert die gleichen Speicherlayout- und Ausrichtungsanforderungen. Ich habe die passenden Referenzen zu meiner Antwort hinzugefügt. –