Betrachten Sie die folgende Inline-Funktion:
// Inline specifier version
#include<iostream>
#include<cstdlib>
inline int f(const int x);
inline int f(const int x)
{
return 2*x;
}
int main(int argc, char* argv[])
{
return f(std::atoi(argv[1]));
}
und die constexpr äquivalente Version:
// Constexpr specifier version
#include<iostream>
#include<cstdlib>
constexpr int f(const int x);
constexpr int f(const int x)
{
return 2*x;
}
int main(int argc, char* argv[])
{
return f(std::atoi(argv[1]));
}
Meine Frage ist: constexpr
Bedeutet der Bezeichner den Bezeichner inline
in dem Sinne, dass constexpr
der Compiler , wenn ein nicht konstantes Argument an eine Funktion übergeben wird, versucht, inline
die Funktion so auszuführen, als ob der Bezeichner inline
in seine Deklaration aufgenommen worden wäre?
Garantiert der C ++ 11-Standard dies?
inline
Spezifizierer tut. (Oder vielleicht habe ich Ihre Formulierung falsch verstanden.)inline
Spezifizierer hat nichts mehr mit Inlininginline
in direktem Zusammenhang mit Inlining steht. Also nein, derconstexpr
Spezifizierer impliziert deninline
Spezifizierer nicht in diesem Sinne, da dieser Sinn nicht existiert.Antworten:
Ja ([dcl.constexpr], §7.1.5 / 2 im C ++ 11-Standard): "constexpr-Funktionen und constexpr-Konstruktoren sind implizit inline (7.1.2)."
Beachten Sie jedoch, dass der
inline
Bezeichner nur sehr geringe (wenn überhaupt) Auswirkungen darauf hat, ob ein Compiler eine Funktion wahrscheinlich inline erweitert oder nicht. Dies wirkt sich jedoch auf die eine Definitionsregel aus, und aus dieser Perspektive muss der Compiler dieselben Regeln für eineconstexpr
Funktion alsinline
Funktion befolgen .Ich sollte auch hinzufügen, dass die Regeln für Funktionen in C ++ 11 unabhängig davon
constexpr
implizierteninline
,constexpr
dass sie so einfach waren, dass sie oft gute Kandidaten für eine Inline-Erweiterung waren (die Hauptausnahme sind diejenigen, die rekursiv sind). Seitdem sind die Regeln jedoch zunehmend lockerer geworden undconstexpr
können daher auf wesentlich größere, komplexere Funktionen angewendet werden.quelle
constexpr
Funktionen vermutlich überhaupt keine Codegenerierung verursachen ...constexpr
Funktionen werden möglicherweise zur Kompilierungszeit ausgewertet. Der C ++ 14-Standard ist jedoch mit solchen übersät, die sehr wahrscheinlich zur Laufzeit aufgerufen werden. Zum Beispiel:std::array<T,N>::at
constexpr
bedeutet nichtinline
für nicht statische Variablen (C ++ 17 Inline-Variablen)Während
constexpr
bedeutetinline
für Funktionen, hat es nicht , dass die Wirkung für nicht-statische Variablen, C ++ unter Berücksichtigung 17 Inline - Variablen.Wenn Sie zum Beispiel das minimale Beispiel nehmen, das ich unter gepostet habe: Wie funktionieren Inline-Variablen? und entfernen Sie das
inline
, lassen Sie nurconstexpr
, dann erhält die Variable mehrere Adressen, was die Hauptsache ist, die Inline-Variablen vermeiden.constexpr
statische Variablen sind jedoch implizit statisch.Minimal Beispiel , das
constexpr
bedeutetinline
für FunktionenWie unter https://stackoverflow.com/a/14391320/895245 erwähnt, besteht der Haupteffekt
inline
darin, nicht zu inline, sondern mehrere Definitionen einer Funktion zuzulassen. Standardzitat unter: Wie kann eine C ++ - Headerdatei die Implementierung enthalten?Wir können das beobachten, indem wir mit dem folgenden Beispiel spielen:
main.cpp
notmain.hpp
notmain.cpp
Kompilieren und ausführen:
Wenn wir entfernen
inline
ausshared_func
, würde Link nicht mit:weil der Header in mehrere
.cpp
Dateien aufgenommen wird.Aber wenn wir ersetzen
inline
mitconstexpr
, dann funktioniert es wieder, dennconstexpr
auch impliziertinline
.GCC implementiert dies, indem die Symbole in den ELF-Objektdateien als schwach markiert werden: Wie kann eine C ++ - Headerdatei die Implementierung enthalten?
Getestet in GCC 8.3.0.
quelle
constexpr
immer noch inline. cppreference.com : Eineconstexpr