C / C ++ - Verknüpfungskonvention

8

Beim Aufruf von C ++ - Algorithmen wie copy_if, transform usw., die als letztes Argument eine unäre oder binäre Funktion annehmen, kann ich eine C-Bibliotheksfunktion wie atoi oder tolower übergeben.

Für z.B. Unter Anrufe funktionieren gut und geben Sie die richtige Ausgabe (versucht in ideone)

%Vor%

Funktioniert diese Verwendung garantiert mit allen C ++ - Compilern?

Das Buch Denken in C ++ erwähnt "Dies funktioniert mit einigen Compilern, aber es ist nicht erforderlich." Der genannte Grund ist (wie ich es verstehe) Transformation ist C ++ - Funktion und erwartet, dass das letzte Argument dieselbe Aufrufkonvention hat.

Das Buch schlägt auch eine Lösung für dieses Problem vor, das darin besteht, eine Wrapper-Funktion in einer separaten cpp-Datei zu erstellen und die iostreams-Header-Datei nicht einzubeziehen.

%Vor%

Das funktioniert gut, aber ich habe nicht verstanden, wie das Problem mit der Anrufkonvention gelöst wird. transform ist immer noch eine C ++ - Funktion und tolower ist immer noch eine C-Funktion im strTolower, also wie diese unterschiedlichen Aufrufkonventionen hier gehandhabt werden.

    
irappa 18.03.2014, 00:21
quelle

1 Antwort

2

Die erste Sache, die zu beachten ist, die nicht wirklich Teil Ihrer Frage ist, aber die jemandem beim Lesen helfen könnte, ist, dass die Algorithmen entweder einen Funktionszeiger oder ein Funktionsobjekt als Argument verwenden können.

Ein Funktionszeiger ist genau das - ein Zeiger auf eine Funktion, die eine bestimmte Menge von Parametern erwartet und einen bestimmten Typ zurückgibt.

Ein Funktionsobjekt ist eine Instanz einer Klasse, die operator () überschrieben hat.

Beim Expandieren der Algorithmusvorlage kann der Compiler sehen, welcher der beiden Fälle zutrifft und wird entsprechenden Aufrufcode generieren.

Wenn eine C-Funktion als Binärfunktion in einem Algorithmus verwendet wird, handelt es sich um einen Funktionszeiger, den Sie bereitstellen. Sie können eine C-Funktion aus C ++ aufrufen, solange sie als extern C { ... } deklariert ist.

Viele Compiler enthalten Header-Dateien für die C-Bibliotheksfunktionen, die etwa so aussehen:

%Vor%

Wenn Sie also einen C-Bibliothek-Header aus einem C ++ - Programm einfügen, stehen Ihnen alle enthaltenen Funktionen magisch zur Verfügung. Dieser Teil wird jedoch vom Standard nicht garantiert, weshalb in Ihrem Buch steht, dass er möglicherweise nicht mit allen Compilern funktioniert.

Eine weitere Falte ist, dass es nicht erlaubt ist, Funktionszeiger auf einen Typ mit einer anderen Sprachverknüpfung zu setzen, was zumindest in einigen Ihrer Beispiele der Fall ist, obwohl einige Compiler das sowieso zu erlauben scheinen - siehe zum Beispiel GCC-Fehler .

Der andere Catch, der speziell für tolower gilt, besteht beispielsweise darin, dass einige der Namen von C-Bibliotheksfunktionen auch Namen von Funktionen oder Vorlagen in der C ++ - Standardbibliothek sind. Zum Beispiel wird der Name tolower auch in <locale> definiert. Dieser spezielle Fall wird in diesem GCC-Fehlerbericht besprochen. Die Verwendung eines Wrappers, der in einer separaten Kompilierungseinheit kompiliert wurde, die die widersprüchlichen Deklarationen nicht enthält, würde dieses Problem beheben.

    
harmic 18.03.2014, 01:13
quelle

Tags und Links