180

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.

181

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
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

182

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.

183

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

184

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

185

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);

?

186

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©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

187

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.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

188

En fait pour que le second marche de maniere sure, il faut mieux faire un

*(((short*)Ptr) + 1);
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

189

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.

190

lus correct, ton*(short*)(Ptr + 2);Folco > Pour être peof(short));devrait être*(short*)(Ptr + siz
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.
coute rien si ton compilateur optimise correctement), tu devrais déclarer une nouvelle variableshort* shortPtr = (short*)Ptr;Et pour être propre (ce qui ne

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

191

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

192

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

193

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

194

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

195

GoldenCrystal (./190) :
coute rien si ton compilateur optimise correctement), tu devrais déclarer une nouvelle variableshort* shortPtr = (short*)Ptr;Et pour être propre (ce qui ne
Ç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

196

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.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

197

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©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

198

RHJPP (./195) :
GoldenCrystal (./190) :
coute rien si ton compilateur optimise correctement), tu devrais déclarer une nouvelle variableshort* shortPtr = (short*)Ptr;Et pour être propre (ce qui ne
Ç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

199

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 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.

200

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.

201

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 ?

202

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

203

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.

204

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).
avatar
Zeroblog

« 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

205

Ok, merci.