Boo
Lionel Debroux - Posté le 15/11/2010 à 06:57 Membre depuis le 28/10/2001, 7564 messages
Pour faire de l'arithmétique de pointeurs, l'utilisation de char * au lieu de void * peut en effet nécessiter davantage de casts.
Cependant, c'est comme ça qu'on fait en C standard. Ici, tu ne te soucies pas de portabilité entre les principaux compilos existants, mais dans le cas général, cette extension non standard casse la compatibilité avec certains des principaux compilos.
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
Brunni - Posté le 15/11/2010 à 06:58 Membre depuis le 03/11/2002, 11554 messages
La solution en réalité c'est la réponse D: ça ne marche pas. Un void* n'a pas de type et donc de taille unitaire. Mais je ne sais pas pourquoi je crois que ça passait sous GCC. Une très mauvaise habitude en tous cas ^^
avatar Avatar fait avec GIMP. Parce que les outils libres ça peut servir à autre chose que casser les pieds aux autres.

"La vie est un grand terrain de jeu. On le sait quand on est enfant mais on l’oublie en grandissant."

http://www.mobile-dev.ch/
Lionel Debroux - Posté le 15/11/2010 à 07:01 Membre depuis le 28/10/2001, 7564 messages
Voir plus haut: ça passe sur GCC, parce que c'est GCC qui a introduit cette extension non standard wink
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
GoldenCrystal - Posté le 15/11/2010 à 07:02 Membre depuis le 15/06/2003, 7902 messages
Brunni > C'est le truc qui a été dit plus tôt dans le topic. tongue
T'aurais pu lire quand même grin

(cross)
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
Folco - Posté le 15/11/2010 à 09:01 Membre depuis le 18/06/2001, 29806 messages
J'ai même posté les deux liens TIGCC/GNU #hehe#

Merci en tout cas pour cette explication. Pour la priorité des opérateurs, j'utilise ce lien que m'avait filé Bob : http://www.commentcamarche.net/contents/c/cop.php3
Il n'y est pas question d'opérateurs, et je croyais que les casts avaient une priorité encore plus forte. Mais de toute façon, j'avais mal interprêté tongue
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
Folco - Posté le 15/11/2010 à 12:03 Membre depuis le 18/06/2001, 29806 messages
Si j'ai bien comprendru, ces trois formulations sont équivalentes, avec Ptr de type void* et sizeof(short) == 2 :
((short*) Ptr)[1];
*((short*)Ptr + 1);
*(short*)(Ptr + 2);

?
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
Godzil - Posté le 15/11/2010 à 12:07 Membre depuis le 30/06/2001, 57130 messages
Normalement non ce n'est pas la meme chose, enfin suivant le compilo, et ce qu'il optimise (etc...) tu peux avoir une comportement différent

Et l'arithmetique sur void* est a proscrire ^^

(Ptr+1) / (Ptr+2)
avatar
Proud to be CAKE©®™
The cake is a lie! - Love your weighted companion cube

->986-Studio's Wonder Project!<-
Sally - Posté le 15/11/2010 à 12:19 Membre depuis le 16/06/2003, 24345 messages
Folco > il me semble que les deux premiers sont équivalents (sauf que je ne suis pas sûr des priorités donc j'aurais tendance à écrire plutôt dans le deuxième cas : *(((short*)Ptr) + 1) ^^) ; pour que le troisième renvoie la même chose ce qu'il faut précisément c'est que Ptr soit de type t* avec sizeof(short) = 2*sizeof(t)
avatar « Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Forum Cultures du mondeforum littéraire
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``[u]·[/u] powaaaaaaaaa ! #love#
Godzil - Posté le 15/11/2010 à 12:23 Membre depuis le 30/06/2001, 57130 messages
En fait pour que le second marche de maniere sure, il faut mieux faire un

*(((short*)Ptr) + 1);
avatar
Proud to be CAKE©®™
The cake is a lie! - Love your weighted companion cube

->986-Studio's Wonder Project!<-
Folco - Posté le 15/11/2010 à 12:26 Membre depuis le 18/06/2001, 29806 messages
Sally (./187) :
(((short*)Ptr) + 1)

Ouah en effet. J'éspère quand même qu'un cast est prioritaire sur une addition quand même. Bon, je vais vraiment devoir lire un truc sur la priorité des casts et le retenir. La surcharge des parenthèses c'est efficace en fiabilité, mais bonjour la lecture. grin
Sally (./187) :
pour que le troisième renvoie la même chose ce qu'il faut précisément c'est que Ptr soit de type t* avec sizeof(short) = 2*sizeof(t)

Comme pour Godzil, j'ai posé la question au ./173, on m'a répondu en dessous, et j'ai posté les liens au ./177 : j'utilise l'extension GNU de GCC qui donne sizeof(void) == 1.

Donc ici, ça marche. Ce n'est ni standard ni portable, mais ça reste parfaitement safe (c'est ça les extensions non-standard).


Donc merci bien our vos réponses, je vai choisir la notation que je trouve la plus claire ou la plus adaptée à un cas donné. Donc je ne sais pas encore laquelle je vais choisir en fait. grin

cross -> Godzil : certainement. Mais je vais quand même rechercher quelle est la règle.
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
GoldenCrystal - Posté le 15/11/2010 à 12:27 Membre depuis le 15/06/2003, 7902 messages
Folco > Pour être plus correct, ton
*(short*)(Ptr + 2);
devrait être
*(short*)(Ptr + sizeof(short));

Plus généralement, je dirais que la première forme est préférable à la seconde la plupart du temps. Et la troisième est à proscrire.
Et pour être propre (ce qui ne coute rien si ton compilateur optimise correctement), tu devrais déclarer une nouvelle variable
short* shortPtr = (short*)Ptr;


Godzil > Tu ne veux pas plutôt dire un assembleur généré différent ? Car les 3 devraient quand même donner la même chose il me semble (en supposant un processus monotâche, et une plateforme avec sizeof(short) = 2 évidemment tongue)
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
RHJPP - Posté le 15/11/2010 à 12:28 Membre depuis le 04/05/2005, 3503 messages
Folco (./189) :
J'éspère quand même qu'un cast est prioritaire sur une addition quand même.
C'est le cas smile (quand même)
avatar
Folco - Posté le 15/11/2010 à 12:36 Membre depuis le 18/06/2001, 29806 messages
RHJPP -> Ok merci (quand même grin)
GoldenCrystal (./190) :

Folco > Pour être plus correct, ton
*(short*)(Ptr + 2);
devrait être
*(short*)(Ptr + sizeof(short));

Ok. Mais en fait, les deux premiers octets sont la taille d'un fichier sous AMS, AFAIK ce n'est pas défini comme un unsigned short quelque part. C'est juste le cas. Par contre, les deux octets suivants sont définis en tant que tel par moi. Donc un Ptr + 2 ne me choque pas plus que ça dans ce cas-là.

Mais ta méthode est plus correcte sur le principe.
GoldenCrystal (./190) :
Plus généralement, je dirais que la première forme est préférable à la seconde la plupart du temps. Et la troisième est à proscrire.

Ok.
GoldenCrystal (./190) :
Et pour être propre (ce qui ne coute rien si ton compilateur optimise correctement), tu devrais déclarer une nouvelle variable

Je déteste perdre en lisibilité, même si t'as raison, ça ne couterait sûrement rien. grin
Je n'utilise des variables bidon que quand ça simplifie l'écriture justement. cheeky
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
Folco - Posté le 15/11/2010 à 12:39 Membre depuis le 18/06/2001, 29806 messages
http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence

Voilà, ce tableau donne la réponse.
Ca montre aussi qu'un *(truc*)Ptr est parfaitement valide, et vaut la valeur de type truc située à Ptr. Au niveau des priorités, "ça passe juste" mais ça passe grin
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
GoldenCrystal - Posté le 15/11/2010 à 12:48 Membre depuis le 15/06/2003, 7902 messages
Folco (./192) :
Je déteste perdre en lisibilité, même si t'as raison, ça ne couterait sûrement rien. grin
Je n'utilise des variables bidon que quand ça simplifie l'écriture justement. cheeky

Ben je sais pas exactement ce que tu veux faire en fait. De la façon dont tu présentais ça, j'ai pensé que c'était pour accéder à une liste de short* tongue (C'est à cause du cast !)
Si c'est pour sauter des octets en comme un offset, alors évidemment, la troisième solution est à choisir… Enfin, tu aurais pu préciser l'intention quoi. (Et pareil dans ce cas, définir une variable débutFichier = Ptr + 2 peut être utile)
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
RHJPP - Posté le 15/11/2010 à 14:04 Membre depuis le 04/05/2005, 3503 messages
GoldenCrystal (./190) :
Et pour être propre (ce qui ne coute rien si ton compilateur optimise correctement), tu devrais déclarer une nouvelle variable
short* shortPtr = (short*)Ptr;
Ça ne me semble pas du tout plus propre comme ça tongue
Peut-être qu'il faudrait passer par une autre variable, mais il faudrait lui donner un nom plus explicite en relation avec ce qu'elle représente. Il n'y a aucune raison de mettre le type dans le nom, puisque c'est déjà le... type cheeky (Bon, c'est valable aussi pour Ptr qui veut probablement dire Pointeur alors que c'est déjà un pointeur. Enfin bref, j'espère que ce n'était que pour l'exemple embarrassed)
avatar
Sally - Posté le 15/11/2010 à 14:05 Membre depuis le 16/06/2003, 24345 messages
Folco (./193) :
*(truc*)Ptr
Euh oui enfin quand ce ne sont que des opérateurs unaires qui se mettent du même côté la question de la priorité ne se pose pas en fait hein ^^. L'étoile ne peut pas s'appliquer à juste (truc*) puisque ce n'est pas un opérande, donc obligatoirement elle s'applique à l'ensemble (truc*)Ptr.

Pour qu'il y ait une question de priorité il faudrait qu'il y ait des opérateurs des deux côtés, par exemple *(truc*)Ptr++, là effectivement ça pourrait vouloir dire : (*((truc*)Ptr)++ ou bien *(truc*)(Ptr++) ou bien *(((truc*)Ptr)++)

On remarque en passant que si ça devient rapidement illisible, c'est en grande partie grâce à l'idée géniale consistant à utiliser les parenthèses pour écrire l'opérateur de cast alors qu'elles servent déjà à indiquer le groupement, ça c'est une des merveilles du C (merveilleusement reprise en java aussi d'ailleurs, comme la plupart des aberrations syntaxiques du C...)

Sinon il y a quelques priorités contre-intuitives (genre >> qui a une priorité super faible) et dans le doute ça va plus vite de surparenthéser que d'aller voir la doc ou de faire des tests ^^. Mais si tu les connais bien effectivement c'est pas nécessaire smile
avatar « Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Forum Cultures du mondeforum littéraire
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``[u]·[/u] powaaaaaaaaa ! #love#
Godzil - Posté le 15/11/2010 à 14:12 Membre depuis le 30/06/2001, 57130 messages
Attention au fait, caster du char vers des types plus grand peu avoir des effets interessant, que le compilo est INCAPABLE de detecter smile

Adresse Error, Lecture de valeur incohérente (ou incompréhensible) etc...
avatar
Proud to be CAKE©®™
The cake is a lie! - Love your weighted companion cube

->986-Studio's Wonder Project!<-
GoldenCrystal - Posté le 15/11/2010 à 14:18 Membre depuis le 15/06/2003, 7902 messages
RHJPP (./195) :
GoldenCrystal (./190) :
Et pour être propre (ce qui ne coute rien si ton compilateur optimise correctement), tu devrais déclarer une nouvelle variable
short* shortPtr = (short*)Ptr;
Ça ne me semble pas du tout plus propre comme ça tongue
Peut-être qu'il faudrait passer par une autre variable, mais il faudrait lui donner un nom plus explicite en relation avec ce qu'elle représente. Il n'y a aucune raison de mettre le type dans le nom, puisque c'est déjà le... type cheeky (Bon, c'est valable aussi pour Ptr qui veut probablement dire Pointeur alors que c'est déjà un pointeur. Enfin bref, j'espère que ce n'était que pour l'exemple embarrassed)

Vu le peu d'explications dans le post de Folco je pouvais pas faire mieux …
Et préciser que la variable est un pointeur, ce n'est pas mal, au contraire.
Si j'appelle ma variable bananaCount, comment tu sais si c'est un int ou un int* après ? T'as un indice quelque part ? (Sachant que souvent les « variables » ainsi déclarées sont des champs dans des structures plus ou moins obscures ou des variables globales définies à un endroit indéterminé)
D'autre part, mettre le nom du type dans la variable, quand c'est autre chose qu'un simple nombre, ça a du sens. Parce que parfois tu veux juste un fruit qui soit un FRUIT, donc tu apelles ta variable fruit

Les assistants de code du langage C étant aussi efficaces aujourd'hui qu'il y a 20 ans (c'est pas tellement de leur faute, ils sont pas gatés avec une telle merde), je vois pas comment tu vas pouvoir deviner le type d'un champ qui est défini dans un .h inclus dans un .h inclus […] dans un .h sans être magicien. (Oui bon, les assistants de code modernes pas trop mal fichus arrivent encore à se démerder avec ça la plupart du temps, heureusement… Mais quand même !)
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
Folco - Posté le 15/11/2010 à 14:28 Membre depuis le 18/06/2001, 29806 messages
Godzil (./197) :
Attention au fait, caster du char vers des types plus grand peu avoir des effets interessant, que le compilo est INCAPABLE de detecter /v31/gfx/s/smile.gif

Je fais gaffe aux additions de short avec des pointeurs, à cause des extensions de signe du 68k. Il faut toujours marcher avec des unsigned pour obtenir le moveq #0,dn salvateur. Au fait, les extensions, on les retrouve aussi au niveau du x86 ?
GoldenCrystal (./198) :
Vu le peu d'explications dans le post de Folco je pouvais pas faire mieux …

J'avoue.
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
Link - Posté le 15/11/2010 à 17:40 Membre depuis le 24/04/2002, 4655 messages
Certains compilos ont des extensions pour ça. Sous Visual Studio, il y a la macro UNALIGNED qui devient rien du tout sur x86, mais peut correspondre à un mot-clé du compilo pour forcer des contrôles lors du déréférencement.
avatar Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.
Folco - Posté le 15/11/2010 à 17:42 Membre depuis le 18/06/2001, 29806 messages
ArcptrWrite est un unsigned long*, pourquoi n'accepte-t-il pas ça :
ArcPtrWrite[1] = ('p' << 16) + ('a' << 8) + 'r';

Même casté en long, il me dit que l'entier ne rentre pas #confus#
Pourtant mon bouquin dit bien que op1 << op2 décale op1 de op2 bits vers la gauche...
Ici, je veux tout simplement un :
move.l truc(pc),d0
truc: dc.b 0,"par"

Quid ?
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
GoldenCrystal - Posté le 15/11/2010 à 17:45 Membre depuis le 15/06/2003, 7902 messages
Ben un signed ne peut pas rentrer dans un unsigned (et vice-versa), donc tu dois faire un cast vers un unsigned, non ?

(Dans ton cas signed long vs unsigned long)
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
Lionel Debroux - Posté le 15/11/2010 à 18:40 Membre depuis le 28/10/2001, 7564 messages
Peut-être
ArcPtrWrite[1] = ((unsigned long)'p' << 16) + ((unsigned long)'a' << 8) + 'r';
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
Zerosquare - Posté le 16/11/2010 à 11:33 Membre depuis le 27/04/2006, 43218 messages
Folco (./199) :
Au fait, les extensions, on les retrouve aussi au niveau du x86 ?
Si tu veux parler d'un truc comme add.w d0, a0, le problème ne se pose pas parce que les instructions x86 ne permettent pas d'utiliser deux registres de taille différente (sauf exception).
avatarZeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo
Folco - Posté le 16/11/2010 à 11:50 Membre depuis le 18/06/2001, 29806 messages
Ok, merci.
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.