157 votes

Est-ce que constexpr implique inline ?

Considérons la fonction inlined 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 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 : est-ce que le constexpr impliquent le spécificateur inline dans le sens où si un argument non constant est passé à une commande de type constexpr le compilateur va essayer de inline la fonction comme si le inline a été placé dans sa déclaration ?

La norme C++11 le garantit-elle ?

181voto

Jerry Coffin Points 237758

Oui ([dcl.constexpr], §7.1.5/2 de la norme C++11) : "Les fonctions constexpr et les constructeurs constexpr sont implicitement inline (7.1.2)."

Notez toutefois que le inline Le spécificateur a vraiment muy peu d'effet (voire aucun) sur la probabilité qu'un compilateur développe une fonction inline ou non. Cependant, cela affecte la règle de la définition unique, et de ce point de vue, le compilateur est tenu de suivre les mêmes règles pour une fonction de type constexpr fonction en tant que inline fonction.

Je devrais également ajouter que, indépendamment de constexpr impliquant inline les règles pour constexpr en C++11 exigeaient qu'elles soient suffisamment simples pour être souvent de bons candidats à l'expansion en ligne (la principale exception étant celles qui sont récursives). Depuis lors, les règles se sont progressivement assouplies. constexpr peut être appliquée à des fonctions beaucoup plus grandes et plus complexes.

84voto

Ciro Santilli Points 3341

constexpr n'implique pas inline pour les variables non statiques (variables en ligne C++17)

Alors que constexpr implique inline pour les fonctions, elle n'a pas cet effet pour les variables non statiques, compte tenu des variables inline de C++17.

Par exemple, si vous prenez l'exemple minimal que j'ai posté à : Comment fonctionnent les variables en ligne ? et retirer le inline laissant juste constexpr alors la variable reçoit des adresses multiples, ce qui est la principale chose que les variables en ligne évitent.

constexpr Les variables statiques sont toutefois implicitement inline.

Exemple minimal que constexpr implique inline pour les fonctions

Comme mentionné à : https://stackoverflow.com/a/14391320/895245 l'effet principal de inline n'est pas de mettre en ligne mais de permettre des définitions multiples d'une fonction, guillemet standard à : Comment un fichier d'en-tête C++ peut-il inclure une implémentation ?

Nous pouvons l'observer en jouant avec l'exemple suivant :

main.cpp

#include <cassert>

#include "notmain.hpp"

int main() {
    assert(shared_func() == notmain_func());
}

notmain.hpp

#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP

inline int shared_func() { return 42; }
int notmain_func();

#endif

notmain.cpp

#include "notmain.hpp"

int notmain_func() {
    return shared_func();
}

Compilez et exécutez :

g++ -c -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'notmain.o' 'notmain.cpp' 
g++ -c -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'main.o' 'main.cpp' 
g++ -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'main.out' notmain.o main.o
./main.out

Si nous supprimons inline de shared_func le lien échouerait avec :

multiple definition of `shared_func()'

parce que l'en-tête est inclus dans plusieurs .cpp des fichiers.

Mais si nous remplaçons inline avec constexpr puis cela fonctionne à nouveau, car constexpr implique également inline .

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X