Considérez la fonction intégrée suivante:
// 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]));
}
et la version équivalente de constexpr:
// 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]));
}
Ma question est la suivante: le constexpr
spécificateur implique-t-il le inline
spécificateur dans le sens où si un argument non constant est passé à une constexpr
fonction, le compilateur essaiera inline
la fonction comme si le inline
spécificateur était placé dans sa déclaration?
La norme C ++ 11 garantit-elle cela?
inline
spécificateur. (Ou peut-être que j'ai mal compris votre formulation.)inline
prescripteur n'a plus rien à voir avec l' inlininginline
est directement liée à l'inlining. Donc non, leconstexpr
spécificateur n'implique pas leinline
spécificateur dans ce sens, car ce sens n'existe pas.Réponses:
Oui ([dcl.constexpr], §7.1.5 / 2 dans le standard C ++ 11): "Les fonctions constexpr et les constructeurs constexpr sont implicitement en ligne (7.1.2)."
Notez, cependant, que le
inline
spécificateur a vraiment très peu (le cas échéant) d'effet sur le fait qu'un compilateur est susceptible de développer une fonction en ligne ou non. Cependant, cela affecte la règle de définition unique et, de ce point de vue, le compilateur doit suivre les mêmes règles pour uneconstexpr
fonction en tant queinline
fonction.Je devrais également ajouter que, indépendamment de l'
constexpr
implicationinline
, les règles pour lesconstexpr
fonctions en C ++ 11 exigeaient qu'elles soient suffisamment simples pour qu'elles soient souvent de bons candidats pour l'expansion en ligne (la principale exception étant celles qui sont récursives). Depuis lors, cependant, les règles se sont progressivement assouplies etconstexpr
peuvent donc être appliquées à des fonctions beaucoup plus grandes et plus complexes.la source
constexpr
fonctions ne provoqueront aucune génération de code ...constexpr
fonctions @KerrekSB sont potentiellement évaluées au moment de la compilation. Cependant, le standard C ++ 14 est jonché de ceux qui seront très probablement appelés à l'exécution. Par exemple:std::array<T,N>::at
constexpr
n'implique pasinline
pour les variables non statiques (variables en ligne C ++ 17)Bien que
constexpr
cela impliqueinline
pour les fonctions, cela n'a pas cet effet pour les variables non statiques, compte tenu des variables en ligne C ++ 17.Par exemple, si vous prenez l'exemple minimal que j'ai publié sur: Comment fonctionnent les variables en ligne? et supprimez le
inline
, en laissant justeconstexpr
, alors la variable obtient plusieurs adresses, ce qui est la principale chose que les variables en ligne évitent.constexpr
les variables statiques sont cependant implicitement statiques.Exemple minimal qui
constexpr
impliqueinline
pour les fonctionsComme mentionné à l' adresse : https://stackoverflow.com/a/14391320/895245, l'effet principal de
inline
n'est pas d'insérer en ligne mais d'autoriser plusieurs définitions d'une fonction, citation standard à l' adresse : Comment un fichier d'en-tête C ++ peut-il inclure une implémentation?On peut l'observer en jouant avec l'exemple suivant:
main.cpp
notmain.hpp
notmain.cpp
Compilez et exécutez:
Si nous supprimons
inline
deshared_func
, le lien échouerait avec:car l'en-tête est inclus dans plusieurs
.cpp
fichiers.Mais si nous remplaçons
inline
parconstexpr
, cela fonctionne à nouveau, car celaconstexpr
implique aussiinline
.GCC implémente cela en marquant les symboles comme faibles sur les fichiers objets ELF: Comment un fichier d'en-tête C ++ peut-il inclure une implémentation?
Testé dans GCC 8.3.0.
la source
constexpr
est toujours en ligne. cppreference.com : une variable membre statique (mais pas une variable de portée d'espace de noms) déclaréeconstexpr
est implicitement une variable en ligne.