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.