2010-06-04 3 views
3

En essayant d'écrire quelques macros simples pour simplifier la tâche de réglage et d'effacement des bits, ce qui devrait être une tâche simple, mais je n'arrive pas à les faire fonctionner correctement.Macros pour définir et effacer les bits

#define SET_BIT(p,n) ((p) |= (1 << (n))) 
#define CLR_BIT(p,n) ((p) &= (~(1) << (n))) 
+2

Il serait utile si vous disiez comment, exactement, les macros ne fonctionnent pas. –

+1

désolé de négliger cela ... Je pensais que l'erreur serait évidente pour certains des programmeurs c mieux versés ici, plutôt que moi * essayant * d'expliquer ... – volting

+0

Je pouvais voir deux problèmes potentiels, mais sans aucun contexte, il est impossible de dire ce qui s'applique à votre situation et ce qui ne fonctionne pas. –

Répondre

8

Essayez

#define CLR_BIT(p,n) ((p) &= ~((1) << (n))) 

Toutefois, pour diverses raisons du mal macro général, je vous conseille de ne pas utiliser une macro. Utilisez une fonction en ligne et passer par référence, quelque chose comme ceci:

static inline void set_bit(long *x, int bitNum) { 
    *x |= (1L << bitNum); 
} 
+1

Merci qui a fonctionné. Iv entendu tout sur les "maux" des macros et je restreins généralement mon utilisation d'entre eux, mais dans ce cas Im juste pour simplifier la tâche de réglage et d'effacement des broches de port sur un contrôleur AVR par exemple CLR_BIT (PORTA, PIN3), je pensais définitions étaient acceptables dans ce contexte? mais je suppose que l'utilisation de fonctions inline permettrait d'éliminer tous les maux de tête .. – volting

+0

Ils sont acceptables, il y a certainement des façons bien pire d'utiliser le préprocesseur: http://stackoverflow.com/questions/652788 mais un jour, vous aurez un bug étrange cela s'avère être lié à la macro. – Artelius

+0

Vrai, j'ai vu beaucoup de ces horreurs de macros threads .. Son effrayant comment les gens peuvent facilement écraser la langue c ... Je pense que je m'en tiens à des fonctions inline quand je peux aussi longtemps qu'ils sont aussi rapides que des macros il n'y a rien être perdu seulement gagné. – volting

7

Une question évidente est que ((p) &= (~(1) << (n))) devrait être ((p) &= ~(1 << (n))). En dehors de cela, vous devez faire attention à la largeur de vos types entiers. Si vous utilisiez unsigned long, vous devrez peut-être utiliser (par exemple) ((p) |= (1UL << (n)))

+0

Oui votre droit qui était le problème, merci. – volting

+0

+1 pour signaler les problèmes de dimensionnement d'entier. –

0

Ugh. N'avez-vous pas un ensemble de fonctions localement pour le faire pour vous? Cela cacherait toute sorte de magie qui se produirait en sautant à travers les frontières des mots.

A défaut, comment cela échoue-t-il? Ils ont l'air 'ok', mais je préfère quand même faire ce genre de chose à la main si les fonctions ne sont pas disponibles. Les macros cachent juste des bogues désagréables quand elles font ce genre de chose. Passer signé vs non signé, etc. Ne sera pas attrapé avec des macros.

Questions connexes