2012-03-28 3 views
2

Zum Beispiel würde Ich mag so etwas tun:Wie konvertiert man GMP C Parameterkonventionen in etwas natürlicheres?

#include <gmp.h> 
typedef mpz_t Integer; 

// 
Integer F(Integer a,Integer b,Integer c,Integer d) { 
    Integer ret = times(plus(a,b),plus(c,d)); 
} 

Aber GMP mir das nicht tun lassen, offenbar mpz_t ein Array ist, so dass ich den Fehler:

error: ‘F’ declared as function returning an array 

anstatt also hätte ich so etwas wie dies zu tun:

void F(Integer ret,Integer a,Integer b,Integer c,Integer d) { 
    Integer tmp1,tmp2; 

    plus(tmp1,a,b);  
    plus(tmp2,c,d);  
    times(ret,tmp1,tmp2); 
} 

das ist unnatürlich, und nicht nach der logischen Art und Weise, dass C (oder im allgemeinen mathematischen) Ausdrücken zusammengesetzt werden kann. In der Tat können Sie nichts auf eine mathematische Art und Weise zusammensetzen, da Sie GMP-Nummern anscheinend nicht zurückgeben können! Wenn ich zum Beispiel einen einfachen Yacc/Bison-Stil-Parser schreiben möchte, der eine einfache Syntax mit +, -, /, * usw. in C-Code umwandelt, der die gegebenen Ausdrücke mit GMP implementiert, scheint es viel schwieriger als ich müsste alle Zwischenwerte verfolgen.

Also, wie kann ich GMP zwingen, hier meinen Willen zu beugen und eine vernünftigere Syntax zu akzeptieren? Kann ich mpz_t sicher "schummeln" und in ein void * werfen und dann am anderen Ende wieder in mpz_t wiederherstellen? Ich gehe davon aus, die Dokumentation zu lesen, dass es nicht wirklich ist um ein Array herum, sondern nur eine Referenz, also warum kann es nicht auch eine Referenz zurückgeben? Gibt es eine gute Grundlage für die Soundprogrammierung, so dass ich mein eigenes Programm schreiben sollte?

+0

'typedef Integer mpz_t;' Haben Sie das kompiliert? –

+0

Whoops, nein, ich habe nicht kopiert/eingefügt von meiner Quelle Ich habe nur manuell neu getippt und anscheinend diese beiden herum getauscht. Ich habe diesen Fehler korrigiert, danke! – Michael

Antwort

3

Von gmp.h:

typedef __mpz_struct mpz_t[1]; 

Das macht sehr viel Sinn, und ist ziemlich natürlich. Denken Sie daran:

es
mpz_t number; 
DoubleIt(number); /* DoubleIt() operates on `number' (modifies it) as 
        it will be passed as a pointer to the real data */ 

Wäre ein Array nicht, dann würden Sie zu tun haben: mit einer Array der Größe 1 Sie mit einem verdunkelten Zeiger (bekannt als undurchsichtige Referenz) und alle seine Vorteile zu behandeln erlaubt etwas wie:

mpz_t number; 
DoubleIt(&number); 

Und dann kommt die ganze Verwirrung. Die Absicht hinter dem undurchsichtigen Typ ist , um diese zu verstecken, also müssen Sie sich nicht darum sorgen. Und einer der wichtigsten Bedenken sollte klar sein: Größe (was zur Leistung führt). Natürlich können Sie solche Struktur nicht zurückgeben, die Daten beschränkt, die auf den verfügbaren Speicher beschränkt sind. Was über diese ein (man denke mpz_t hier als „First-Class“ Typ):

mpz_t number = ...; 
number = DoubleIt(number); 

Sie (das Programm) haben würde, alle Daten in number kopieren und drücken Sie sie als Parameter an die Funktion . Dann muss es einen geeigneten Platz für zurückgeben, eine weitere Nummer noch größer.

Fazit: Da Sie indirekt mit Daten umgehen müssen (mit Zeigern) ist es besser, einen undurchsichtigen Typ zu verwenden. Sie werden eine Referenz nur an Ihre Funktionen übergeben, aber Sie können an ihnen arbeiten, als wäre das ganze Konzept Pass-by-Referenz (C standardmäßig Pass-by-Referenz).

+0

Ok, ich verstehe, warum sie ein Array der Größe 1 verwenden, und es ist ziemlich clever. Außerdem können Sie den lokalen Speicher leichter definieren, als wenn sie zum Beispiel typedef __mpz_struct * mpz_t eingegeben hätten. In diesem Fall wäre es schwieriger, den automatischen Speicher für die zugrunde liegende Struktur zuzuweisen. Es ist also natürlich vom Standpunkt der Zuordnung und Weitergabe, aber nicht natürlich vom Standpunkt der Rückgabewerte. – Michael

+0

Und, ich denke, ich sollte hinzufügen, diese Aufrufkonvention ermöglicht ihnen auch, den Trick zu machen, zu erkennen, wenn ein neuer Speicher nicht benötigt wird, z.B. mpz_add (x, x, x) – Michael

Verwandte Themen