Problème insoluble de transtypage

Problème insoluble de transtypage - C - Programmation

Marsh Posté le 20-09-2008 à 21:37:06    

Bonjour à tous,
Je rencontre fréquemment ce problème et je pense que je suis loin d'être le seul.
 
J'ai ça:
 

Code :
  1. #include <stdio.h>
  2. void f(int t[5][5])
  3. {
  4.     printf("%d\n", t[3][2]);
  5. }
  6. int main()
  7. {
  8.     int t[25];
  9.     t[17] = 123;
  10.     f((void *) t);
  11.     return 0;
  12. }


 
Je veux ça (prototype imposé):

Code :
  1. #include <stdio.h>
  2. // prototype fixe
  3. void f(int __t[])
  4. {
  5. //    int t[5][5] = __t;
  6. //
  7. //    printf("%d\n", t[3][2]);
  8. }
  9. int main()
  10. {
  11.     int t[25];
  12.     t[17] = 123;
  13.     f(t);
  14.     return 0;
  15. }


 
Mais je n'ai trouvé que ça:

Code :
  1. #include <stdio.h>
  2. void f(int __t[])
  3. {
  4.     struct {int x[5];} * t = (void *) __t;
  5.     printf("%d\n", t[3].x[2]);
  6. }
  7. int main()
  8. {
  9.     int t[25];
  10.     t[17] = 123;
  11.     f(t);
  12.     return 0;
  13. }


 
Ce contournement est vraiment énervant et je reste convaincu qu'une solution plus élégante existe (et plus concise aussi). J'aimerais éviter le référencement par structure ( genre: t[].x[] ). Bref, si quelqu'un possède une telle solution.:) Merci d'avance


Message édité par dave_tetehi le 20-09-2008 à 23:44:40
Reply

Marsh Posté le 20-09-2008 à 21:37:06   

Reply

Marsh Posté le 20-09-2008 à 23:57:27    

Up

Reply

Marsh Posté le 21-09-2008 à 09:50:29    

oui mais non, t[x][y] est un type bien différent de t[z] ...
A part passer un pointeur puis recaster derrière, je vois pas comment tu peut t'en sortir.

Reply

Marsh Posté le 21-09-2008 à 11:49:47    

Ouai mais c'est dangereux,
le mieux c'est d'utiliser une fonction

Code :
  1. int getMatrixElement(int x,int y,int width,int *t)
  2. {
  3.     return t[x+y*width];
  4. }
  5. void f(int *t)
  6. {
  7.     printf("%d\n", getMatrixElement(3,2,5,t));
  8. }

Message cité 1 fois
Message édité par sligor le 21-09-2008 à 11:51:38
Reply

Marsh Posté le 21-09-2008 à 11:57:03    

Ouais, tu as raison. J'ai deux autres alternatives mais qui sont toujours un peu moches.
 
La première par doublon de f() :
 

Code :
  1. #include <stdio.h>
  2. void g(int t[5][5])
  3. {
  4.     printf("%d\n", t[3][2]);
  5. }
  6. // prototype imposé
  7. void f(int __t[])
  8. {
  9.     g((void *) __t);
  10. }
  11. int main()
  12. {
  13.     int t[25];
  14.     t[17] = 123;
  15.     f(t);
  16.     return 0;
  17. }


La deuxième qui est une redite du code n°3, en un peu mieux:
 

Code :
  1. #include <stdio.h>
  2. void f(int __t[])
  3. {
  4.     struct{ int x[5][5];} * t = (void *) __t;
  5.     printf("%d\n", t->x[3][2]);
  6. }
  7. int main()
  8. {
  9.     int t[25];
  10.     t[17] = 123;
  11.     f(t);
  12.     return 0;
  13. }


 
Franchement, je trouve ça bête que la norme autorise la création de (référence sur) tableaux (dim>1) en paramètre de fonction, et qu'il soit impossible d'en faire autant avec des variables automatiques.

Reply

Marsh Posté le 21-09-2008 à 12:00:11    

sligor a écrit :

Ouai mais c'est dangereux,
le mieux c'est d'utiliser une fonction


 
Oui mais une fonction, c'est lent

Reply

Marsh Posté le 21-09-2008 à 12:04:57    

dave_tetehi a écrit :

Oui mais une fonction, c'est lent


 
mais bien sur, sans profiling t'es capable de le dire ....
 
Sinon, j'ai déjà filer un code pour gérer proprement des tableaux multi-dim ...

Reply

Marsh Posté le 21-09-2008 à 12:05:50    

dave_tetehi a écrit :


 
Oui mais une fonction, c'est lent


 
pour la vitesse il y a toujours les inline du C99,
ou au pire les macro (mais on reste dans le moche là).
 
et sinon pour faire du calcul matriciel haute vitesse il vaut mieux utiliser des libraries optimisées je pense.


Message édité par sligor le 21-09-2008 à 12:09:44
Reply

Marsh Posté le 21-09-2008 à 12:10:12    

arreter de dire du caca :o
il code avec une fonction (meme si l'acces en polynome de horner est une horreur) et il bench ... on optimise pas un code sur ecran mais un code exécuté :o

Reply

Marsh Posté le 21-09-2008 à 12:58:12    

pourquoi tu utilises __t comme identifiant ?

Reply

Marsh Posté le 21-09-2008 à 12:58:12   

Reply

Marsh Posté le 21-09-2008 à 13:02:09    

Plutot que de caster vers une struct, cast vers un union. C'est la méthode qu'on utilise fréquemment quand on veut éviter que le compilateur se retrouve avec deux types différents pour un même pointeur dans son arbre, ce qui cause plus tard des problèmes marrants. On l'utilise plus pour caster des types simples à d'autre, cela dit, mais ca marche aussi.

 

Exemple:

 
Code :
  1. typedef union {
  2.         int array[5][5];
  3.         int * t;
  4. } myunion;
  5. #define CAST_TO_ARRAY(myvar) (((myunion *)(myvar))->array)
  6. ...
  7. void f(int __t[])
  8. {
  9.         printf("%d\n", CAST_TO_ARRAY(__t)[3][2]);
  10. }
 

Bien évidemment, c'est pas un vrai cast (on ne peut caster que vers des types scalaires, pas des agregats). Mais au moins, c'est la solution couramment retenue, et qui est propre (bien plus que de caster comme un barbare, qui entraine plus tard les problèmes que je mentionne au dessus).

 
sligor a écrit :


ou au pire les macro (mais on reste dans le moche là).

 

N'importe quoi.


Message édité par Gf4x3443 le 21-09-2008 à 13:03:34

---------------
Petit guide Kerberos pour l'administrateur pressé
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed