Considere a seguinte função embutida:
// 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]));
}
e a versão equivalente 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]));
}
Minha pergunta é: o constexpr
especificador implica o inline
especificador no sentido de que se um argumento não constante for passado para uma constexpr
função, o compilador tentará inline
a função como se o inline
especificador tivesse sido colocado em sua declaração?
O padrão C ++ 11 garante isso?
inline
especificador faz. (Ou talvez eu não tenha entendido sua frase.)inline
especificador não tem mais nada a ver com inlininginline
está diretamente relacionada ao inlining. Portanto, não, oconstexpr
especificador não implica oinline
especificador nesse sentido, pois esse sentido não existe.Respostas:
Sim ([dcl.constexpr], §7.1.5 / 2 no padrão C ++ 11): "funções constexpr e construtores constexpr são implicitamente embutidos (7.1.2)."
Observe, entretanto, que o
inline
especificador realmente tem muito pouco (se houver) efeito sobre a probabilidade de um compilador expandir uma função embutida ou não. No entanto, isso afeta a regra de definição única e, dessa perspectiva, o compilador deve seguir as mesmas regras para umaconstexpr
função como umainline
função.Devo também acrescentar que, independentemente de
constexpr
implicarinline
, as regras paraconstexpr
funções em C ++ 11 exigiam que fossem simples o suficiente para que fossem frequentemente boas candidatas para expansão sequencial (a principal exceção sendo aquelas que são recursivas). Desde então, no entanto, as regras ficaram progressivamente mais flexíveis,constexpr
podendo ser aplicadas a funções substancialmente maiores e mais complexas.fonte
constexpr
funções não causará nenhuma geração de código ...constexpr
funções @KerrekSB são potencialmente avaliadas em tempo de compilação. No entanto, o padrão C ++ 14 está repleto de outros que muito provavelmente serão chamados em tempo de execução. Por exemplo:std::array<T,N>::at
constexpr
não implicainline
para variáveis não estáticas (variáveis embutidas C ++ 17)Embora
constexpr
impliqueinline
para funções, não tem esse efeito para variáveis não estáticas, considerando as variáveis inline do C ++ 17.Por exemplo, se você pegar o exemplo mínimo que postei em: Como funcionam as variáveis embutidas? e remove o
inline
, deixando apenasconstexpr
, então a variável obtém vários endereços, que é a principal coisa que as variáveis embutidas evitam.constexpr
variáveis estáticas são, entretanto, implicitamente estáticas.Exemplo mínimo que
constexpr
implicainline
funçõesConforme mencionado em: https://stackoverflow.com/a/14391320/895245, o principal efeito de
inline
não é embutir, mas permitir várias definições de uma função, citação padrão em: Como um arquivo de cabeçalho C ++ pode incluir implementação?Podemos observar isso brincando com o seguinte exemplo:
main.cpp
notmain.hpp
notmain.cpp
Compile e execute:
Se removermos
inline
deshared_func
, o link falhará com:porque o cabeçalho é incluído em vários
.cpp
arquivos.Mas se substituirmos
inline
porconstexpr
, ele funcionará novamente, porqueconstexpr
também implicainline
.O GCC implementa isso marcando os símbolos como fracos nos arquivos de objeto ELF: Como um arquivo de cabeçalho C ++ pode incluir a implementação?
Testado em GCC 8.3.0.
fonte
constexpr
ainda está embutida. cppreference.com : Uma variável de membro estático (mas não uma variável de escopo de namespace) declaradaconstexpr
é implicitamente uma variável embutida.