2010-11-24 15 views
1

Ich arbeite derzeit an einem Projekt, das die Suche nach & beweglichen Elementen in Graphen beinhaltet. Ich dachte, das igrap Paket war ziemlich gut für meine einfachen Bedürfnisse, jedoch, wie ich es gewohnt bin, mit Java zu arbeiten, sind einige Dinge nicht klar.Vermeiden von zu viel Gießen

Warum definieren zum Beispiel die Leute, die das igraph-Paket erstellt haben, grundlegende Elemente wie ganze Zahlen als 'igraph_integer_t' neu? Gibt es eine Möglichkeit zu vermeiden, dass ich jedes Mal, wenn ich eine Funktion ihrer Bibliothek anrufe, alles wieder in Ganzzahlen umwandeln muss, was den Code ziemlich unordentlich macht?

+0

http://igraph.sourceforge.net/ – poolie

+1

C ist nicht C++; Es ist nie erforderlich, Umwandlungen mit Ganzzahl- oder Gleitkommatypen zu verwenden. –

Antwort

0

Ich weiß nicht, ob es möglich ist (ich kenne dieses Paket nicht), aber Sie sollten in Ihrer eigenen Anwendung igraph_integer_t verwenden oder ein Framework um igraph erstellen, mit dem Sie kommunizieren können.

Die Sache ist, wenn Sie die falsche Größe Integer verwenden (kurz vs. lang, signiert vs unsigned, etc.), dann können Sie einige wirklich skurrile Bugs bekommen, die schwer zu finden sind. Ich würde ein Framework erstellen, um mit igraph zu interagieren, das die passende Größe int für die verwendete Bibliothek und den Compiler auswählt. Ich würde Casting vermeiden, außer in diesem Rahmen, wo Sie wissen, dass es sicher sein sollte.

Kurz zusammengefasst: fügen Sie eine Abstraktionsebene hinzu.

+0

Dies ist einfach eine kaputte Praxis der Bibliotheksautoren; Es gibt keine legitime Entschuldigung. Wenn sie einen Integer-Typ einer bestimmten Größe benötigen, sollte ihre API den Standardtyp für diese Größe verwenden, z. 'int32_t'. Wenn sie eine "normale" Integer-Größe haben wollen, die mit der Plattform variiert, ist das "int" oder "long" und sie sollten einen dieser Typen verwenden. –

+0

@R .. Ich stimme sicherlich zu, aber das löst das Problem nicht, wenn Sie die Bibliothek verwenden müssen _now _... oder? –

+0

Es tut. Schauen Sie einfach in 'igraph.h' oder wie auch immer es heißt, finden Sie die Definition von' igraph_integer_t' (was ich 99% sicher bin einfach 'int'), und gehen Sie dann wie gewohnt mit' int'. –

1

Dies ist eine ziemlich üble Praxis, die viele Bibliotheken ohne guten Grund tun. Suchen Sie nach dem Typ igraph_integer_t. Wenn es int ist, was ich erwarte, einfach int überall verwenden und so tun, als ob igraph_integer_t nicht existiert. Es gibt absolut keine Notwendigkeit für Casts. Alle Integer-Typen (und Gleitkomma-Typen) werden implizit in C konvertiert, und C typedef Typen werden nicht als unabhängig von ihren Definitionen betrachtet.

2

Als einer der Autoren von igraph, ist mir klar, dass dies eine fragwürdige Designentscheidung war/war, die zu Beginn des Projekts getroffen wurde. Die ursprüngliche Absicht war wirklich, "eine Abstraktionsebene hinzuzufügen": Wir haben mit wissenschaftlichem Quellcode gearbeitet, bevor die App int überall verwendete und aufgrund von Überlaufproblemen mussten wir alle int durch long alle über den Quellcode austauschen Das Programm arbeitet mit dem Problem, mit dem wir konfrontiert wurden. Deshalb haben wir igraph_integer_t anstatt einfach int oder long - wenn Sie feststellen, dass der igraph_integer_t Datentyp zu klein für Ihre Probleme ist, müssen Sie nur einen Platz im Quellcode ändern.

Im Rückblick ist das obige Szenario ziemlich selten, also ist es wahrscheinlich ein ziemlich schwaches Argument. Um die Dinge weiter zu komplizieren, wird igraph_integer_t aus Angst vor Fällen, in denen der long-Datentyp nicht auf allen Plattformen ausreicht, auf double typedef. (Ein Szenario, das mir gerade einfällt, ist das Zählen von Motiven in einem großen Diagramm - die Anzahl der Motive, obwohl sie ganzzahlig ist, kann die Grenzen des Datentyps long auf älteren Plattformen leicht überschreiten). Da war nicht um das Projekt zu der Zeit, als die Entscheidung über igraph_integer_t getroffen wurde, könnte es nicht der genaue Grund sein, das ist genau das, was ich denke, hätte sein können. Fühlen Sie sich frei, auf der igraph-help mailing list zu fragen, wenn Sie sich für die blutigen Detals interessieren. Wie auch immer, ich benutze den C-Kern von igraph direkt sehr (da ich für die Python-Wrapper verantwortlich bin), also kann ich sicher sagen, dass zwischen igraph_integer_t und anderen Datentypen nur in zwei Fällen unterschieden werden kann:

  1. Bei Verwendung eines Werts igraph_integer_t in printf.Sie müssen entweder igraph_integer_t in eine long umwandeln und %ld in der Formatzeichenkette verwenden oder kein Casting ausführen und %g in der Formatzeichenfolge verwenden (was implizit davon abhängig ist, dass igraph_integer_t eine double ist).

  2. Beim Indexieren eines Arrays mit einem igraph_integer_t. Sie müssen es natürlich auf long werfen.

+0

Wow. Einfach wow. Einen Typ "Integer" benennen und als Fließkomma Typ definieren. Wie Sie sagen, führt dies zu vielen nicht offensichtlichen Fehlern: nicht nur das Array-Problem, sondern auch das völlige Versagen des '%' -Operators und Fehlverhalten des '/' -Operators. Danke zumindest für die Erkenntnis, dass es wahrscheinlich eine schlechte Idee war. –

+0

Übrigens +1 für eine sehr informative Antwort von der Quelle. –

+0

Für den Fall, dass noch jemand dies liest: 'igraph_integer_t' wird nun in der Quelle typedef 'zu einem' int' und nicht zu 'double'. –