Sto utilizzando una parola chiave specifica MS per forzare una funzione globale inline, ma ho notato che la funzione non riesce ad essere in linea se utilizza un oggetto che ha un distruttore banale esplicito.Informazioni sulla funzione C++ Inlining
Citando MSDN
Anche con
__forceinline
, il compilatore non può codice inline in tutte le circostanze . Il compilatore non può inline una funzione se:
La funzione o il suo chiamante è compilato con
/Ob0
(l'opzione predefinita per build di debug).La funzione e il chiamante utilizzano diversi tipi di gestione delle eccezioni (gestione delle eccezioni C++ in una gestione delle eccezioni strutturata nell'altro).
La funzione ha un elenco di argomenti variabili.
La funzione utilizza assembly inline, a meno compilato con
/Og
,/Ox
,/O1
o/O2
.La funzione è ricorsiva e non è corredata di
#pragma inline_recursion(on)
. Con il pragma, le funzioni ricorsive sono integrate in una profondità predefinita di 16 chiamate. Per ridurre la profondità di allineamento, utilizzare il pragmainline_depth
.La funzione è virtuale e viene chiamata virtualmente. Le chiamate dirette alle funzioni virtuali possono essere sottolineate.
Il programma prende l'indirizzo della funzione e la chiamata viene effettuata tramite il puntatore alla funzione. Le chiamate dirette alle funzioni che hanno ricevuto il loro indirizzo possono essere sottolineate.
La funzione è contrassegnata anche con il modificatore
__declspec
nudo.
sto cercando il seguente programma autonomo per testare il comportamento
#include <iostream>
#define INLINE __forceinline
template <class T>
struct rvalue
{
T& r_;
explicit INLINE rvalue(T& r) : r_(r) {}
};
template <class T>
INLINE
T movz(T& t)
{
return T(rvalue<T>(t));
}
template <class T>
class Spam
{
public:
INLINE operator rvalue<Spam>() { return rvalue<Spam>(*this); }
INLINE Spam() : m_value(0) {}
INLINE Spam(rvalue<Spam> p) : m_value(p.r_.m_value) {}
INLINE Spam& operator= (rvalue<Spam> p)
{
m_value = p.r_.m_value;
return *this;
}
INLINE explicit Spam(T value) : m_value(value) { }
INLINE operator T() { return m_value; };
template <class U, class E> INLINE Spam& operator= (Spam<U> u) { return *this; }
INLINE ~Spam() {}
private:
Spam(Spam<T>&); // not defined
Spam& operator= (Spam&); // not defined
private:
T m_value;
};
INLINE int foo()
{
Spam<int> p1(int(5)), p2;
p2 = movz(p1);
return p2;
}
int main()
{
std::cout << foo() << std::endl;
}
Con il distruttore banale INLINE ~Spam() {}
a posto, abbiamo il seguente smontaggio
int main()
{
000000013F4B1010 sub rsp,28h
std::cout << foo() << std::endl;
000000013F4B1014 lea rdx,[rsp+30h]
000000013F4B1019 lea rcx,[rsp+38h]
000000013F4B101E mov dword ptr [rsp+30h],5
000000013F4B1026 call movz<Spam<int> > (013F4B1000h)
000000013F4B102B mov rcx,qword ptr [__imp_std::cout (013F4B2050h)]
000000013F4B1032 mov edx,dword ptr [rax]
000000013F4B1034 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (013F4B2040h)]
000000013F4B103A mov rdx,qword ptr [__imp_std::endl (013F4B2048h)]
000000013F4B1041 mov rcx,rax
000000013F4B1044 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (013F4B2058h)]
}
dove come senza il distruttore INLINE ~Spam() {}
abbiamo il seguente smontaggio
int main()
{
000000013FF01000 sub rsp,28h
std::cout << foo() << std::endl;
000000013FF01004 mov rcx,qword ptr [__imp_std::cout (013FF02050h)]
000000013FF0100B mov edx,5
000000013FF01010 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (013FF02040h)]
000000013FF01016 mov rdx,qword ptr [__imp_std::endl (013FF02048h)]
000000013FF0101D mov rcx,rax
000000013FF01020 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (013FF02058h)]
}
000000013FF01026 xor eax,eax
}
io sto riuscendo a capire, perché in presenza del distruttore, il compilatore non riesce a inline la funzione T movz(T& t)
- Nota Il comportamento è coerente 2008-2013
- Nota Ho controllato con cygwin-gcc ma il compilatore non fa il codice.Non posso verificare altri compilatori in questo momento, ma aggiornerei nelle prossime 12 ore se necessario
chiedere alle persone che hanno scritto il compilatore, e, eventualmente, un bug report. –
@ N.m .: vorrei, ma prima voglio chiedere alla comunità, se sono a conoscenza di questo problema, o se mi manca qualcosa ovvio :-) – Abhijit
Esiste un '# define' manca? 'INLINE __forceinline' – dyp