Builtins in Clang nicht so eingebaut?

8

Wenn ich folgendes in strlen.c habe:

%Vor%

Und dann kompiliere es mit gcc und clang wie folgt:

%Vor%

Ich bin überrascht zu sehen, dass strlen-clang.o einen Verweis auf "strlen" enthält, während gcc die Funktion erwartungsgemäß inline eingezeichnet hat und keinen solchen Verweis hat. (Siehe Objdumps unten). Ist das ein Bug im Klang? Ich habe es in mehreren Versionen des clang Compilers getestet, einschließlich 3.8.

Bearbeiten: Der Grund, warum das für mich wichtig ist, ist, dass ich mit -nostdlib verlinke, und die clang-kompilierte Version gibt mir einen Linkfehler, der strlen nicht gefunden wird.

Clang

%Vor%

GCC

%Vor%     
brooks94 27.07.2016, 13:58
quelle

2 Antworten

4

Nur um die Optimierung aus dem Weg zu räumen:

Mit clang -O0 :

%Vor%

Mit clang -O3

%Vor%

Nun zu dem Problem:

Die Clang-Dokumentation behauptet, dass Clam alle von GCC unterstützten Builtins unterstützt.
Die GCC-Dokumentation scheint jedoch integrierte Funktionen und die Namen ihrer Bibliotheksäquivalente als Synonyme zu behandeln:

  

Beide Formulare haben denselben Typ (einschließlich Prototyp), dieselbe Adresse (wenn ihre Adresse vergeben wird) und dieselbe Bedeutung wie die C-Bibliotheksfunktionen [...].

Es garantiert auch nicht eine eingebaute Funktion mit einem Bibliotheksäquivalent (wie es bei strlen der Fall ist), um tatsächlich optimiert zu werden:

  

Viele dieser Funktionen sind nur in bestimmten Fällen optimiert. Wenn sie in einem bestimmten Fall nicht optimiert sind, wird ein Aufruf an die Bibliotheksfunktion ausgegeben.

Außerdem erwähnt das Handbuch zu den internen Schlüsseln nur __builtin_strlen einmal:

  
  • __builtin_strlen und strlen : Dies sind Konstanten, die als Integer-Konstantenausdrücke gefaltet sind, wenn das Argument ein String-Literal ist.
  •   

Abgesehen davon scheinen sie keine Versprechungen zu machen.

Da in Ihrem Fall das Argument für __builtin_strlen kein String-Literal ist und die GCC-Dokumentation Aufrufe von eingebauten Funktionen in Bibliotheksfunktionsaufrufe ermöglicht, scheint das Verhalten von clang vollkommen zu sein.

A "Patch zur Überprüfung" auf Die Mailingliste clang developers sagt auch:

  

[...] Es wird immer noch auf Laufzeitnutzung der Bibliothek strlen zurückgreifen, falls   Kompilierzeitauswertung ist nicht möglich / erforderlich [...].

Das war 2012, aber der Text zeigt an, dass zumindest damals nur die Kompilierzeit-Auswertung unterstützt wurde.

Jetzt sehe ich zwei Optionen:

  • Wenn Sie das Programm nur selbst kompilieren und dann verwenden und / oder verteilen möchten, schlage ich vor, dass Sie einfach gcc verwenden.
  • Wenn Sie andere benötigen, um Ihren Code sowohl unter gcc als auch clang zu kompilieren, empfehle ich, eine C-Bibliothek als Abhängigkeit für die statische Verknüpfung hinzuzufügen.

Ich rate dringend gegen das Rollen Ihrer eigenen Implementierungen von Standardbibliotheksfunktionen, sogar für scheinbar einfache Fälle (wenn Sie nicht zustimmen, versuchen Sie, Ihre eigene strlen Implementierung zu schreiben und vergleichen Sie sie mit die glibc one ).

    
Siguza 27.07.2016 16:38
quelle
4

Weder GCC noch Clang versprechen, diesen Built-In zu inline zu bringen. Sie haben einige GCC-Dokumente zitiert, die ein solches Versprechen zu geben scheinen:

  

... GCC-integrierte Funktionen werden immer inline erweitert ...

aber das ist ein Satzfragment, das aus dem Zusammenhang gerissen wurde. Der komplette Satz ist

  

Mit Ausnahme von Einbauten mit Bibliotheksäquivalenten wie den unten besprochenen standardmäßigen C-Bibliotheksfunktionen, oder Erweiterungen für Bibliotheksaufrufe integrierte GCC-Funktionen werden immer inline erweitert und haben daher keine entsprechenden Einstiegspunkte und ihre Adresse kann nicht erhalten werden.

__builtin_strlen hat die Bibliotheksäquivalent strlen , also macht dieser Satz keine Versprechen darüber, ob er inline wird.

    
user2357112 27.07.2016 18:42
quelle

Tags und Links