[Résolu] Math.min
ancrou
Membre
Bonjour,
Avec Java il existe la Méthode statique Math.min(val1,val2);
Et en Objective-C ?
Car j'ai 2 chiffres de type UI32_ à comparer.
Comment faire ?
:-\\
Avec Java il existe la Méthode statique Math.min(val1,val2);
Et en Objective-C ?
Car j'ai 2 chiffres de type UI32_ à comparer.
Comment faire ?
:-\\
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Sinon, c'est l'exemple typique pour une macro à arguments :
Merci
Moi ça m'embête toujours de conseiller une macro avec ses effets de bord (MIN(i++, j), et compagnie)
Je propose donc :
-soit faire appel à Objective-C++ (dans ce cas on renomme le fichier toto.m en toto.mm et on a le droit d'utiliser std::max() et std::min())
-soit faire appel au C99 (si je ne me trompe pas, c'est le mode par défaut en Obj-C), et on a le droit de faire des fonctions inline et surchargées pour écrire soi-même les fonctions min et max
+
Chacha
Pas d'accord, pour deux raisons :
1) Beaucoup d'expressions du C standard restent des macros
2) Les effets de bords ne sont pas que dans les macros
exemple :
int main (int argc, const char * argv[]) {
int i=2,j=3;
printf("%d %d\n ",i+=j,j--);
return 0;
}
A l'essai, j'obtiens 4 3. :P
Il faut donc savoir les utiliser et connaà®tre le danger des effets de bords.
Enfin c'est quand même le genre de code qu'il vaut mieux éviter
J'ai essayé depuis plusieurs ce code, et chaque fois, c'est ainsi. Ceci dit,ce n'est dit nulle part dans la norme.
Dans ce code, il y a aussi le comportement du -- qui est rigolo, expliquable mais rigolo.
Ce genre de problèmes est souvent masqué dans des instructions du type sprintf(s, " format ", .... )
Oui, ou alors peut-être pour taquiner ... ::) ::)
C'est pour cela que la réserve sur les macros me semble excessive. Je préfère dire
"il ne faut pas utiliser un code susceptible de faire des effets de bords"
Pour aller néammoins dans le sens de Chacha, on remarquera que certaines exrpessions comme isalpha() sont des fonctions inline appelant des macros, les arguments étant donc en quelque sorte "nettoyés" avant d'être traités par la macro.
C'est post-fixé, donc évalué avant la décrémentation... qui est effective pour l'évaluation de l'argument suivant (enfin précédent du coup puisque c'est de droite à gauche)
Avec un nombre variable d'arguments, et donc l'utilisation de va_args et va_list, on va directement lire les arguments sur la pile, l'execution des opérateurs de droite à gauche pourrait donc être lié à cet empilement à l'envers, non ?
Logique certes, mais bon quand on est dans le bizarre ...
Voilà de la logique bizarre :
#include <stdlib.h>
#include <stdio.h>
void fn(int i,int j){
printf("%d %d\n ",i,j);
}
int main (int argc, const char * argv[]) {
int i=2;
int j;
j=(i++,i+3);
printf("%d %d\n",i,j);
i=2;
fn(i++,i+++3);
return 0;
}
réponse :
% pgm
3 6
3 5 :brule:
%
exemples à fuir ...
Ouououououououarffffffffffffffff ;D ;D ;D ;D ;D ;D ;D
Suffit de connaà®tre les règles de sens d'évaluation...
() -> gauche à droite, donc pour le premier exemple, i++ est fait d'abord, puis j=i+3=6
arguments d'une fonction -> droite à gauche
i++ + 3 -> 5 (car ++ postfixé, donc incrémentation faite après l'évaluation)
i++ -> 3 (de par l'incrémentation au dessus ; à nouveau postfixé, donc i vaudra 4 après l'affichage)
En fait, oui, c'est logique... Peu importe le sens de va_args et va_list, les arguments ont déjà été empilés et évalués avant même l'appel...
Et ensuite dans la fonction on les dépile, certes de gauche à droite (enfin celui du dessus de la pile d'abord, donc le dernier à avoir été empilé [LIFO] = celui qui était le plus à gauche lors de l'appel en premier), mais à ce moment les opérateurs ont déjà été appliqués.
Conclusion, les arguments sont évalués de droite à gauche, lorsqu'ils sont empilés... mais les post-incrémentations et post-décrémentations sont effectuées uniquement après le retour de la fonction. C'est bien ce que tu sembles expliquer schlum, hein ? Et ça me semble plutôt logique décrit comme tel.
Le problème est que ça va à l'encontre de l'exemple du [tt]printf("%d %d\n", i+=j , j--);[/tt] de Philippe49, où le "j--" est effectué qd mm avant l'appel à la fonction, passant i+=j donc du coup 4 comme premier chiffre au printf, et non 2+3=5...
Troublant tout ça... Même si ça n'a jamais été une bonne idée de jouer avec le feu de ce côté, ben quand même... pfiou !
printf("%d %d\n", i+=j , j--);
- J'empile "j"
- Je décrémente "j"
- i = i+j
- J'empile "i"
C'est quand même fort, pour un sujet marqué [Résolu] depuis quelques temps qu'on arrive à continuer si loin ;D
Bon ben pour la peine, et vu qu'il fait encore chaud ici dehors (pourquoi on doit être enfermés dans des bureaux alors qu'on pourrait bosser sur la pelouse, hein ?), un petit avant que le temps ne se couvre :P
Non, il n'y a rien de logique là -dedans, c'est simplement comme ça, et on peut trouver une raison acceptable. La norme n'impose rien (j'ai compris depuis très longtemps la différence entre j++ et ++j)
D'ailleurs ce n'est pas la même logique pour l'expression j=(i++,i+3), qui lui doit suivre l'ordre de la gauche vers la droite inscrit dans la norme.
Non, non, on arrêtera pas ! surtout si à la clé il y a :kicking:
Ben qu'est-ce qui n'est pas logique ?
l'opérateur "," est bien défini dans la norme comme opérateur à évaluation de gauche à droite, et les arguments empilés dans le sens inverse, c'est standard aussi ???
Pourquoi donc ? Les arguments sont copiés, ce n'est pas par référence...
On est pas sensés connaà®tre forcément la façon dont le compilateur empile les arguments dans la stack pour savoir programmer, donc ce comportement là est loin de sembler logique (pardon, "naturel") et sauter aux yeux, on s'attend plutôt à ce que l'incrémentation se fasse à la fin de l'instruction, "au moment du point-virgule" si je puis dire, avant de passer à l'instruction suivante.
Donc oui les arguments sont copiés, mais on s'attend à ce que la post-incrémentation se fasse après... la copie de tous les arguments dans le contexte de la fonction.
Mais bien sûr, d'un point de vue technique, vu les explications qu'on vient de fournir, c'est "logique" ou plutôt "ça s'explique vu comment le C fonctionne, avec l'empilement des arguments en ordre inverse etc", ça n'empêche que c'est pas trivial
J'avais déjà entendu cette histoire d'empilage à l'envers plusieurs fois...
Tu dois avoir pas mal de verre brisé, chez toi, si tu tentes de dépiler les verres en FIFO!
;D ;D
Voilà ce que dit Ritchie :
Pour les arguments de fonctions :
"L'ordre des évaluations des arguments n'est pas défini : notez bien qu'il varie selon le compilateur. Toutefois tous les arguments et le désignateur de fonction sont entièrement évalués, y compris leurs effets de bord, avant d'entrer dans la fonction."
Vague donc sur le moment d'évaluation de ces dits effets de bord ... Mais il y a peut être des références plus précises depuis, ou une "jurisprudence" ... je ne demande qu'à voir.
Pour l'opérateur virgule, par contre c'est clair : "Tous les effets de bord de l'opérande de gauche sont effectués avant de commencer à opérer l'opérande de droite."
Mais que ça soit Intel ou PPC c'est dans le sens inverse si je ne m'abuse