Équivalent du module (fonction mathématique) en C?
Question
J'ai un morceau de code où je vois un avertissement dire
Je fais une comparaison entre le nombre signé et non signé.
Quelque chose comme int <= constant / sizef (expression)
Quelle est la meilleure façon de corriger cela? Je crois prendre le module du numéro signé, puis faire la comparaison, non? Je veux dire que j'obtiens le numéro non signé après division par sizeof opérateur sur une expression. Donc, l'inverse pourrait être de faire signer ce RHS
Si oui, y a-t-il une fonction en C qui me permettrait de faire cela? J'ai fait une recherche rapide et ils disent% pour modulo, ce qui n'est évidemment pas ce que je recherche.
C'est l'avertissement réel
Avertissement: comparaison entre les expressions entières signées et non signées
Et c'est la ligne de code réelle
functiona (......, int num, .....) {
affirmer (num <= max_size / sizeof (int)); // où max_size est #define max_size 1000
}
La solution
Jetez un côté à l'autre signée. Vous devez vous assurer que le nombre signé n'est pas négatif si vous jetez cela à un signé - sinon une comparaison de -1 < 100
n'aura pas le résultat souhaité, car (unsigned)(-1) == UINT_MAX
-, ou que le numéro non signé ne déborde pas si vous jetez cela à signer. Dans ces cas, ajoutez une condition supplémentaire pour les traiter.
Pour le cas particulier ci-dessus, j'utiliserais
assert(num <= (int)(MAX_SIZE/sizeof(int)));
// num <= MAX_SIZE/(int)sizeof(int) if I'm in a mean mood
si num
pourrait être négatif et
assert((unsigned)num <= MAX_SIZE/sizeof(int));
si num
est garanti d'être non négatif.
Autres conseils
Si vous savez que le bon opérande est <= INT_MAX
, tu peux le lancer à int
.
int bla;
...
if (bla < (int) sizeof expr) {
...
}
Mais si vous pouvez changer le type d'objet bla
à size_t
(qui est le type de la valeur qui sizeof
donne) ce serait encore mieux que de lancer.
Comme je le vois, votre int num
est autorisé à prendre toute valeur négative et valeurs positives jusqu'à MAX_SIZE/sizeof(int)
. Sinon, vous auriez déclaré num
En tant qu'entier non signé à coup sûr ...
Étendre votre déclaration d'affirmation par cette condition supplémentaire aiderait-il dans votre cas?
assert( num < 0 || /* make the signed check */
(unsigned int)num <= MAX_SIZE/sizeof(int) /* the unsigned remainder */
);