Вы совершенно правы. Это массив из одного элемента, и при таком расположении он будет в стеке. Со всеми его полями: alloc, size и mp_d. При выходе из функции есть шансы, что он будет затёрт, и так действовать нельзя.
Кто затрёт? Да кто угодно. Хоть драйвер, пожелавший воспользоваться твоим стеком. Хоть последующий вызов какой-нибудь функции.
С другой стороны, на то и помечена структура __mpz_struct двумя подчерками, чтобы её не использовали.
__mpz_struct* foo()
{
mpz_t var;
return (__mpz_struct *)var;
// C:\TestApps\RetLocal\main.cpp|15|warning: address of local variable 'var' returned [-Wreturn-local-addr]|
}
А так работает: всё в куче. Только не забывайте очищать через delete[].
__mpz_struct* bar()
{
__mpz_struct* var = new mpz_t;
return var;
}