Probleme macro et cast !!! argh !!!

ToasTy62 Messages postés 47 Date d'inscription mardi 4 septembre 2001 Statut Membre Dernière intervention 12 mars 2004 - 19 nov. 2003 à 23:35
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 - 21 nov. 2003 à 11:23
bon voila le pb : g fé une tite macro ac une condition mais ca marchas pas des masses... un ti peu d'aide serait vraiment le bienvenue !!! marchi !
regardez cette tite macro

(pr precision : #define BSK_TYPE_INTEGER 6)

#define returnType(p, t) (((t)==BSK_TYPE_INTEGER) ? *(int*)p : *(float*)p)

cette macro sert a caster un void* vers le type souhaité.
apparemment quoi que je fasse, c'est toujours le sinon qui est executé...
dc ca transforme toujours le pointeur void* p en *(float*)p... bouhouhou!
je vois vraiment pas le pb, c pitete le ? : ki est mal utilisé?
enfin bref, si qqun pouvait m'aider, ca m'eviterait de balance le pc... merci d'avance !

15 réponses

garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
20 nov. 2003 à 08:07
Si j'ai bien compris p peut être un pointeur sur float ou sur int, et tu veux pouvoir le caster indifférement en float ou en int, c'est ça ?

Quoiqu'il en soit ce n'est pas toujours le sinon qui est executé!

il faut comprendre comment une valeur est stockée en mémoire.

Quand tu fais
float f = 123.4;
4 octets sont réservés pour stocker la valeur 123.4 mais dans un format spécial (les fameuses virgules flottantes). Ca s'appelle IEEE 754 si ça t'interesse : http://www.programmationworld.com/site/cours.asp?Action=cours&numero=179

Je suppose que pour ton test tu as fait:
float f = 123.4;
void* pointeur = &f;
int n = returnType(pointeur, BSK_TYPE_INTEGER);

Là n ne va pas être égal à 123 mais à une valeur apparement incompréhensible. En fait dans ta macro tu récupère l'adresse des 4 octets du float, et tu dis "considère que c'est un entier". Donc l'ordi comprend que les 4 octets en question doivent être les cases-mémoire de ton entier. C'est pour ça que n vaut n'importe quoi (en fait tu utilisé un très bon moyen de faire une conversion IEEE !).

On ne force pas une curiosité, on l'éveille.
.................................................Daniel Pennac
0
ToasTy62 Messages postés 47 Date d'inscription mardi 4 septembre 2001 Statut Membre Dernière intervention 12 mars 2004
20 nov. 2003 à 09:37
nan mais je sais tres bien tout ske tu me racontes...
bon je v mieux t'expliker l'utilisation
imagine ca :
typedef (void*) (*PFv) (...)

ensuite on assigne un pointeur de fonction dans
PFv call;
call = nianiania on s'en fout c un pointeur de fonction;
apres ->
call(returnType(p1, p1->type), returnType(p2, p2->type), etc...)
en fait le but c de faire un appel de fonction sachant qu'il faut caster void* p en le bon type.
p1 sera casté en int si p1->type == BSK_TYPE_INTEGER
p1 sera casté en float si p1->type == BSK_TYPE_FLOAT
mais il n'yaura JAMAIS de perte de données ! car justement le type des données est stocké dans p1->type.
je pe pa faire de call(*(float*)p1, etc...) paske p1 pourrait être un entier, tout depend de ce que le programme lui a assigné avant.... tu vois un peu le bazar?
0
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
20 nov. 2003 à 11:49
Ok alors j'ai bien plus simple pour toi!

Utilise Union

Je ne sais pas si tu connais.
Ex:
Union IntFloat
{
int n;
float f;
}

typedef struct Variable
{
char type;
IntFloat valeur;
}

Ton IntFloat prendra toujours 4 octets et selon que tu utilises n ou f tu aura un entier ou un flottant.

Tu n'as plus qu'à faire une fonction que te retourne le float si le type est FLOAT et le int si le type est INT.

Va dans mes sources, j'utilise un truc dans ce genre ("langage de script pour automatiser les actions dans Windows")
0
ToasTy62 Messages postés 47 Date d'inscription mardi 4 septembre 2001 Statut Membre Dernière intervention 12 mars 2004
20 nov. 2003 à 12:06
javé deja regardé la possibilité de l'union mais ya tjs un pb.
deja g pa précisé mé ya aussi le double, dc 8 octets... ensuite vu k'il est impossible de surcharger un retour de fonction c pa possible de faire une fonction ki retourne un entier, un float ou un double ! le pb se pose vraiment ds le cast...
g regardé ds ton code(ke g pa testé mé ki a l'air sympa) et en gros ta fé une fonction GetNombre() ki retourne un float a partir d'un float ou d'une chaine, mais moi fo vraiment ke ca retourne le type souhaité!!!
il me faut vraiment UNE SEULE fonction ou UNE SEULE macro ki retourne le type souhaité et le cast, vu ke ca doit pas rester un void*... :oP
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ToasTy62 Messages postés 47 Date d'inscription mardi 4 septembre 2001 Statut Membre Dernière intervention 12 mars 2004
20 nov. 2003 à 12:08
g oublié de preciser, la fonction ki retourne le float si c'est un FLOAT et un int si c un INT c justement la macro ke g fait, en contournant le pb d'overload de retour... snifouille! y arriverais-je???
0
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
20 nov. 2003 à 14:25
Je te propose ce code:

union IntFloat
{
float type0;
int type1;
};

typedef struct
{
IntFloat* valeur;
char type;
} Variable;

#define GetIntFloatA(valeur, num) valeur->type##num
#define GetIntFloat(variable) variable.type==0 ? (float)GetIntFloatA(variable.valeur, 0) : (int)GetIntFloatA(variable.valeur, 1)

int main(int argc, char* argv[])
{
// pour les float
IntFloat valFloat
valFloat.type1 = 123;
Variable varFloat
varFloat.type = 0
varFloat.valeur = &val;

float f = GetIntFloat(var);

// pour les int
IntFloat valInt;
valInt.type1 = 123;
Variable varInt;
varInt.type = 1;
varInt.valeur = &val;

int i = GetIntFloat(var);
return 0;
}

comme ça GetIntFloat te donne un int quand ta Variable est du type int et un float quand ta varaible est du type float.

PS: pour les double ça ne pose pas vraiment de pb. Le seul truc c'est que ton union fera tjrs 8 octets même si c'est pour stocker un int ou un float.

On ne force pas une curiosité, on l'éveille.
.................................................Daniel Pennac
0
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
20 nov. 2003 à 14:31
Et même tu peux ne mettre que
#define GetIntFloat(variable) variable.type==0 ? variable.valeur->type0 : variable.valeur->type1

comme macro!

On ne force pas une curiosité, on l'éveille.
.................................................Daniel Pennac
0
ToasTy62 Messages postés 47 Date d'inscription mardi 4 septembre 2001 Statut Membre Dernière intervention 12 mars 2004
20 nov. 2003 à 18:47
// g créé ce tit code pr faire des tests et les resultats st vraiment surprenants !
// je c pa si c'est dû a des bugs ou o compilo...
// fo bidouiller ac la macro et le printf du case 0...

#include <windows.h>
#include <stdio.h>

struct param {
int type;
union {
char *c;
int i;
float f;
double d;
};
};

#define returnType(p, t) (t==0) ? p.i : p.f

int main(int args, char argv[]) {
param prm;
prm.i = 5;
prm.type = 0;

switch(prm.type) {
case 0:
printf("i -> %i(%i)\n", returnType(prm, prm.type), prm.i);
break;
case 1:
printf("f -> %f(%f)\n", prm.f, returnType(prm, prm.type));
break;
}
system("pause");
}

// dis-moi toré pa icq, msn ou aim pr k'on puisse discuter de ca? jte montreré les trucs bizarres ke g trouvé ac ce code...
// aim : toasty62
// msn : toasty62@aol.com
// icq : 225399580
// voila! @pluche !
// ps : ca marche tjs pas... bouhouhou !!!
0
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
20 nov. 2003 à 20:19
C normal que ce que tu as fait ne marche pas : quand tu fais returnType(prm, prm.type) c'est pas comme returnType(prm, 0) même si prm.type vaut 0 !

Quoiqu'il en soit voici un code que j'ai testé (celui d'au dessus c'était un peu à l'aveuglette....dslé) et ça marche nickel :
typedef struct
{
char type;

union
{
float type0;
int type1;
};

} param;

#define GetIntFloat(variable) variable.type==0 ? variable.type0 : variable.type1

int main(int argc, char* argv[])
{
// pour les float
param paramFloat;
paramFloat.type = 0;
paramFloat.type0 = 123.4;

float f = GetIntFloat(paramFloat);

// pour les int
param paramInt;
paramInt.type = 1;
paramInt.type1 = 123;

int i = GetIntFloat(paramInt);

printf("float=%f\tint=%d\n", f,i);

system("pause");
return 0;
}

Bonne continuation

On ne force pas une curiosité, on l'éveille.
.................................................Daniel Pennac
0
ToasTy62 Messages postés 47 Date d'inscription mardi 4 septembre 2001 Statut Membre Dernière intervention 12 mars 2004
20 nov. 2003 à 21:49
ca marche preske ! enfin c pa ke ca va pas, ca fonctionne mais le pb est pa tt a fait resolu !
g changé la ligne du printf par ca :

printf("float=%f\tint=%d\n", GetIntFloat(paramFloat), GetIntFloat(paramInt));

g inséré la macro ds la fonction. et en fait moi c ds un cas comme ca ke j'en ai besoin et... ca marche pas !
pr le float ca passe, mais pr le paramInt ca indique 0...
bouhouhou ! g encore fait qqch de travers?
j'en finirais decidement jms ac de pb...
0
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
20 nov. 2003 à 21:56
T'es un coriace!

Fais donc ça

printf("float=%f\tint=%d\n", GetIntFloat(paramFloat), (int)(GetIntFloat(paramInt)));

On ne force pas une curiosité, on l'éveille.
.................................................Daniel Pennac
0
ToasTy62 Messages postés 47 Date d'inscription mardi 4 septembre 2001 Statut Membre Dernière intervention 12 mars 2004
20 nov. 2003 à 21:59
1) ca marche pas javé deja tenté
2) ca fait apparaitre un cast ki devré pa être là...
hihihi tjs pas fini !
0
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
20 nov. 2003 à 22:04
Si ça marche!

Par contre pour le cast c'est vrai que c'est un peu lourd...

Bon je te laisse je vais gouter pour la 3ème fois le beaujolais nouveau! (qui n'est du coup un peu moins nouveau....)

On ne force pas une curiosité, on l'éveille.
.................................................Daniel Pennac
0
ToasTy62 Messages postés 47 Date d'inscription mardi 4 septembre 2001 Statut Membre Dernière intervention 12 mars 2004
20 nov. 2003 à 22:06
dsl g essayé sous vc++ 6.0 et devc++ 4.0 snirfllllllll!
bonne picole :oP
0
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
21 nov. 2003 à 11:23
Dslé mais je ne vois rien d'autre.

Je v qd mêm t'expliquer le pb pour que tu puisses poursuivre si tu veux...moi j'abandonne !

Quand on utilise
condition ? valeur1 : valeur 2

le type du résultat est automatiquement casté comme le type de valeur1. C'est pour ça que ça marche avec les float mais pas avec les int (sauf si on caste encore derrière!)

Bon courgae

On ne force pas une curiosité, on l'éveille.
.................................................Daniel Pennac
0
Rejoignez-nous