Einige Fragen zu einem Array mit einer einzigen Instanz in typedef

8

Ich habe irgendeinen Code gelesen, bei dem Ganzzahlen mit beliebiger Länge verwendet wurden, wobei der GNU Multi-Precision (GMP) Bibliothekscode verwendet wurde. Der Typ für eine MP-Ganzzahl ist mpz_t , wie in der Header-Datei gmp.h definiert.

Aber ich habe einige Fragen über die Definition der unteren Ebene dieses bibliotheksdefinierten Typs mpz_t . Im Header-Code:

%Vor%

Erste Frage: Verbindet sich die [1] mit der __mpz_struct ? Mit anderen Worten, definiert das typedef einen mpz_t Typ als __mpz_struct Array mit einem Vorkommen?

Zweite Frage: Warum das Array? (Und warum nur ein Vorfall?) Ist das einer dieser Struktur-Hacks von denen ich gehört habe?

Dritte Frage (vielleicht indirekt bezogen auf die zweite Frage): Die GMP-Dokumentation für die mpz_init_set(mpz_t, unsigned long int) -Funktion sagt, sie nur als Vorübergehender Wert zu verwenden, obwohl man annehmen würde, dass diese Funktion dies würde Ändere seinen Inhalt innerhalb der aufgerufenen Funktion (und würde daher eine Pass-by-Reference-Syntax benötigen). Siehe meinen Code:

%Vor%

Aktiviert das Array mit nur einem Vorkommen automatisch den Pass-by-Reference (aufgrund des Zusammenbruchs der Array- / Pointer-Semantik in C)? Ich gebe frei zu, dass ich das etwas überbewerte, aber ich würde jede Diskussion darüber lieben. Danke!

    
pr1268 29.01.2011, 04:14
quelle

3 Antworten

3

* Erste Frage: Verbindet die [1] mit dem __mpz_struct? Mit anderen Worten, definiert der Typedef einen mpz_t-Typ als __mpz_struct-Array mit einem Vorkommen? *

Ja.

Zweite Frage: Warum das Array? (Und warum nur ein Vorfall?) Ist das einer dieser Struct-Hacks, von denen ich gehört habe?

Schlägt mich. Ich weiß es nicht, aber eine Möglichkeit ist, dass der Autor ein Objekt erstellen wollte, das automatisch als Referenz übergeben wurde, oder "Ja", möglicherweise der Struktur-Hack. Wenn Sie jemals ein mpz_t -Objekt als letztes Mitglied einer Struktur sehen, dann ist es "fast sicher" der Struktur-Hack. Eine Zuordnung sieht aus wie

%Vor%

wäre ein totes Werbegeschenk.

Aktiviert das Array mit nur einem Vorkommnis automatisch Pass-by-Reference ...?

Aha, du hast es auch herausgefunden. "Ja", ein möglicher Grund besteht darin, Pass-by-Reference auf Kosten komplexerer Referenzen zu vereinfachen.

Ich nehme an, eine andere Möglichkeit besteht darin, dass sich im Datenmodell oder im Algorithmus etwas geändert hat, und der Autor wollte jede Referenz finden und irgendwie ändern. Eine solche Änderung würde das Programm mit dem gleichen Basistyp belassen, aber jede nicht konvertierte Referenz ausschließen.

    
DigitalRoss 29.01.2011, 04:21
quelle
4

Dies scheint kein Struktur-Hack in dem auf C2 beschriebenen Sinn zu sein. Es scheint, dass sie möchten, dass mpz_t eine Pointer-Semantik hat (vermutlich wollen sie, dass die Leute sie wie einen undurchsichtigen Zeiger verwenden). Betrachten Sie den syntaktischen Unterschied zwischen den folgenden Schnipsel:

%Vor%

Und

%Vor%

Da C-Arrays in Zeigern zerfallen, ist auch eine automatische Übergabe durch Referenz für den mpz_t -Typ möglich.

Sie können auch einen zeigerähnlichen Typ verwenden, ohne dass malloc oder free it erforderlich ist.

    
Daniel Gallagher 29.01.2011 04:29
quelle
2

Der Grund dafür liegt in der Implementierung von mpn . Insbesondere, wenn Sie mathematisch geneigt sind, werden Sie erkennen, dass N die Menge der natürlichen Zahlen ist (1,2,3,4 ...), während Z die Menge der ganzen Zahlen ist (..., - 2, -1,0 , 1,2, ...).

Das Implementieren einer bignum-Bibliothek für Z ist gleichbedeutend damit, dies für N zu tun und einige spezielle Regeln für Zeichenoperationen zu berücksichtigen, dh zu verfolgen, ob eine Addition oder eine Subtraktion durchgeführt werden muss und was das Ergebnis ist.

>

Was die Implementierung einer Bibliothek von bignum angeht ... Hier ist eine Zeile, die Ihnen einen Hinweis gibt:

%Vor%

Und jetzt schauen wir uns eine Funktionssignatur an, die damit arbeitet:

%Vor%

Grundsätzlich kommt es darauf an, dass ein "Glied" ein ganzzahliges Feld ist, das die Bits einer Zahl darstellt, und die ganze Zahl wird als ein riesiges Array dargestellt. Der clevere Teil ist, dass gmp all dies in einer sehr effizienten, gut optimierten Weise tut.

Wie auch immer, zurück zur Diskussion. Im Prinzip ist die einzige Möglichkeit, Arrays in C zu übergeben, wie Sie wissen, die Übergabe von Zeigern an diese Arrays. Nun, um den Überblick zu behalten, sind zwei Typen definiert: ein mp_ptr , ein Array von mp_limb_t , das groß genug ist, um deine Nummer zu speichern, und mp_srcptr , was eine konstante Version davon ist Sie können nicht versehentlich die Bits der Quell-Bignums ändern, auf dem Sie arbeiten. Die Grundidee ist, dass die meisten Funktionen diesem Muster folgen:

%Vor%

usw. Also, ich vermute, mpz_* Funktionen folgen dieser Konvention einfach konsistent zu sein, und es ist, weil das ist, wie die Autoren denken.

Kurze Version: Wegen der Notwendigkeit, eine bignum lib zu implementieren, ist dies notwendig.

    
user257111 29.01.2011 08:06
quelle

Tags und Links