Probleme macro et cast !!! argh !!!

Messages postés
47
Date d'inscription
mardi 4 septembre 2001
Statut
Membre
Dernière intervention
12 mars 2004
- - Dernière réponse : garslouche
Messages postés
584
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 !
Afficher la suite 

15 réponses

Messages postés
584
Date d'inscription
mardi 26 novembre 2002
Statut
Membre
Dernière intervention
29 mai 2015
0
Merci
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
Commenter la réponse de garslouche
Messages postés
47
Date d'inscription
mardi 4 septembre 2001
Statut
Membre
Dernière intervention
12 mars 2004
0
Merci
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?
Commenter la réponse de ToasTy62
Messages postés
584
Date d'inscription
mardi 26 novembre 2002
Statut
Membre
Dernière intervention
29 mai 2015
0
Merci
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")
Commenter la réponse de garslouche
Messages postés
47
Date d'inscription
mardi 4 septembre 2001
Statut
Membre
Dernière intervention
12 mars 2004
0
Merci
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
Commenter la réponse de ToasTy62
Messages postés
47
Date d'inscription
mardi 4 septembre 2001
Statut
Membre
Dernière intervention
12 mars 2004
0
Merci
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???
Commenter la réponse de ToasTy62
Messages postés
584
Date d'inscription
mardi 26 novembre 2002
Statut
Membre
Dernière intervention
29 mai 2015
0
Merci
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
Commenter la réponse de garslouche
Messages postés
584
Date d'inscription
mardi 26 novembre 2002
Statut
Membre
Dernière intervention
29 mai 2015
0
Merci
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
Commenter la réponse de garslouche
Messages postés
47
Date d'inscription
mardi 4 septembre 2001
Statut
Membre
Dernière intervention
12 mars 2004
0
Merci
// 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 !!!
Commenter la réponse de ToasTy62
Messages postés
584
Date d'inscription
mardi 26 novembre 2002
Statut
Membre
Dernière intervention
29 mai 2015
0
Merci
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
Commenter la réponse de garslouche
Messages postés
47
Date d'inscription
mardi 4 septembre 2001
Statut
Membre
Dernière intervention
12 mars 2004
0
Merci
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...
Commenter la réponse de ToasTy62
Messages postés
584
Date d'inscription
mardi 26 novembre 2002
Statut
Membre
Dernière intervention
29 mai 2015
0
Merci
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
Commenter la réponse de garslouche
Messages postés
47
Date d'inscription
mardi 4 septembre 2001
Statut
Membre
Dernière intervention
12 mars 2004
0
Merci
1) ca marche pas javé deja tenté
2) ca fait apparaitre un cast ki devré pa être là...
hihihi tjs pas fini !
Commenter la réponse de ToasTy62
Messages postés
584
Date d'inscription
mardi 26 novembre 2002
Statut
Membre
Dernière intervention
29 mai 2015
0
Merci
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
Commenter la réponse de garslouche
Messages postés
47
Date d'inscription
mardi 4 septembre 2001
Statut
Membre
Dernière intervention
12 mars 2004
0
Merci
dsl g essayé sous vc++ 6.0 et devc++ 4.0 snirfllllllll!
bonne picole :oP
Commenter la réponse de ToasTy62
Messages postés
584
Date d'inscription
mardi 26 novembre 2002
Statut
Membre
Dernière intervention
29 mai 2015
0
Merci
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
Commenter la réponse de garslouche