2016-08-04 2 views
-4

Pour des raisons de compatibilité, je veux définir une macro itérateur qui fonctionne comme ceci:Ce code est-il valide?

elem_type *ptr; 
ITERATE(&container, ptr) { 
    // This will loop through every element of the container 
    // ptr will point to the current element. 
} 

J'ai un type iterator qui doit être initialisé avec un appel de fonction, et fonctionne comme ceci:

iter_type iter; 
iter_init(&container, &iter); 
while((ptr = iter_next(&iter))) { 
    // ... 
} 

Alors, voici la solution que je suis venu presser cette séquence dans la macro:

#define ITERATE(container_ptr,elem_ptr) \ 
    for(iter_type _iter = (\ 
     iter_init(container_ptr, &_iter), _iter); \ 
     (elem_ptr = iter_next(&_iterator));) 

donc, comme vous pouvez le voir, il y a une petite astuce w avec l'opérateur virgule, afin de s'adapter à la fois à une déclaration de variable et à l'initialisation de l'appel de fonction dans le premier deux-points du for. Ce code est-il valide C99, et fonctionnera toujours?

+4

valide? Définir valide. compile-t-il pourrait être un premier pas. Aussi, vous n'êtes pas le premier à inventer cette macro, c'est une chose courante - Vérifiez le noyau Linux –

+0

Ma définition de valide est donnée dans: "et fonctionnera toujours". Si ce n'est pas assez clair, par «toujours», je veux dire chaque mise en œuvre de la plainte C99. Et il est hors de propos que je ne sois pas le premier à inventer cette macro, si je ne savais pas où la chercher. Enfin, comment peut-il être dans le code noyau si le commutateur C99 n'est pas activé dans les options de construction? – lvella

+0

Le mot que vous cherchez est "portable" –

Répondre

1

Oui, c'est valide et fonctionnera toujours.

Juste prendre votre boucle,

for(iter_type _iter = (iter_init(container_ptr, &_iter), _iter); \ 
     (elem_ptr = iter_next(&_iterator));) 

et plus précisément la clause d'initialisation iter_type _iter = (iter_init(container_ptr, &_iter), _iter), vous pouvez voir que l'opérateur virgule est impliqué ici.

L'opérateur de virgule est toujours évalué de gauche à droite et il y a une séquence entre chacun de ses opérandes.

+0

En fait, l'opérateur de virgule est un opérateur binaire, donc il n'a que deux opérandes. Et je pense que vous voulez dire _sequence ** point ** _? – Olaf