2010-08-18 6 views
1

Existe-t-il un moyen compatible standard d'émuler 'return' avec macro?Emulation de 'retour' dans la macro

Actuellement, j'essaie d'encapsuler la fonction _alloca pour émuler un tableau de longueur variable sur la pile (qui est pris en charge dans C99) avec une macro en C++. Puisque la fonction _alloca manipule le pointeur de pile, je pense que la fonction inline n'est pas une solution appropriée pour cette fois.

Voici le code actuel que j'ai écrit.

template <typename T> 
inline void __placement_new_array(T arr[], const size_t size) { 
    assert(size > 0); 
    for (size_t i = 0; i < size; i++) { 
     new (&arr[i]) T; 
    } 
} 

template <typename T> 
class __arraydtor 
{ 
    public: 
     __arraydtor(T arr[], size_t size) : arr_(arr), size_(size) {} 
     ~__arraydtor() { 
      for (size_t i = size_ - 1; i != (size_t)(-1); i--) { 
       arr_[i].~T(); 
      } 
     } 

    private: 
     T* arr_; 
     size_t size_; 
}; 

#define stack_alloc(size) _alloca(size) 

#define stacknew(ptr, type, size) \ 
    ptr = static_cast<type*>(stack_alloc(sizeof(type) * size));\ 
    __placement_new_array(ptr, size);\ 
    __arraydtor<type> __##type##_dtor_instance(ptr,size) 

... 

    type* pos; 

    stacknew(pos, type, size); 

Je pense que le code est assez utile même pour l'instant (cela fonctionne pour la plupart des types au moins dans VS2005), mais finalement je veux acheive la macro qui peut être utilisé comme ci-dessous -

pos = stacknew(type, size); 

(Bien sûr pos = Type stacknew [size], serait plus cool, mais je ne pense pas qu'il y ait un moyen de acheive avec tout compilateur C++)

Depuis la macro contient une déclaration, émulant « retour » est impossible dans la forme actuelle - cela pourrait être impossible ou nécessiter une approche différente. Mais je manque d'expérience pour l'utilisation de la macro, je ne peux pas juger si c'est possible ou non.

Je tiens également à noter que le code ci-dessus n'est pas sûr lorsque le ctor du tableau cible émet une exception - Je serais également reconnaissant si quelqu'un suggère un moyen d'améliorer la macro.

+2

Oublier que les macros existent en C++. Oui, ils sont séduisants, mais ils font même un langage déjà plus mystérieux. S'il est difficile de coder, il sera encore plus difficile à comprendre et risque de se casser lorsque quelque chose change. – msw

+0

@msw, +1 pour éviter les macros, moins plusieurs milliards pour l'utilisation de l'expression "encore pire". Pas vraiment, juste le +1 :-) – paxdiablo

+0

J'ai volé "encore pire" de la part de Spalding Grey alors je ne peux même pas prendre le crédit de la phrase. Je ne prendrai pas la responsabilité si vous commencez à l'utiliser dans la conversation (et vous l'utiliserez, il tombe bien de la langue). – msw

Répondre

0

vous pouvez utiliser , opérateur:

v = (expr1, expr2); // evaluate both expressions, return rightmost 
+0

Un opérateur de virgule peut être utile si la partie dtor (qui contient la déclaration) est séparée. Merci :) – summerlight