1

J'ai tapé le code suivant et observé l'assembleur généré.
void _main(void)
{
    int i;
    char c;
    
    
    i= 0;
    c= -1;
    
    (char)i= c;

    printf(" * %i * ", i);
}
D'abord, je suis surpris que le compilateur accepte. Comment interprète-t-il "(char)i= c" ? Je n'en comprends pas le sens.
D'ailleurs, concrètement, ça ne change rien avec ou sans le cast : le code ASM propage le bit de poids faible de c pour étendre sa valeur sur 16 bits, et il place le résultat dans i.
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

2

a mon avis il fait *((char*)&i), il prend le char à l'adresse de i. t'as de la chance sur certains cpus, et pas sur d'autres, à cause de l'endianess!

3

smile
En fait ma question, c'est : ça signifie quoi ?

Je veux bien accepter la signification que tu donnes, mais ce n'est pas celle que donne le compilateur. Lui, il fait comme si y'avait pas de cast : il affecte le char au short de manière classique. (j'ai oublié de préciser que je travaille sur M68000, donc int = short).
Si on admet ta signification, que se passerait-il si on castait un char pour lui affecter un short ? ... C'est délicat !
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

4

!call Pollux
--- Call : Pollux appelé(e) sur ce topic ...

?
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

5

ça signifie que tu stockes une valeur qq part, et que tu supposes que ce qq part est un char. donc y'a forcément des pertes de données si tu mets qc qui rentre pas directement dans un char.

6

Eh bien non justement smile

Dans le code du post ./2, le char est étendu sur les 16 bits du short (int).

Si on déclare que c est un short ou un long, la valeur -1 est écrite dans sur la totalité des bits de i. Le cast sur i n'a visiblement aucun effet.
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

7

Au fait tu obtiens quoi précisément comme code ? (pour du 68k stp)
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

8

move.w #-1, -x(a7)Avec GCC comme avec GTC.
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

9

enfin faut avouer que c'est strange, de faire des casts de lvalues. même si c'est autorisé... bof quoi... T'en as vraiment besoin ou c'est "pour la recherche" ?

10

est-ce que ça ne signifie pas tout simplement (char) (i = c) ? (ie le cast porte sur toute l'expression, et n'a donc aucune influence sur l'affectation)
essaie peut-être de taper ((char)i) = c pour vérifier si ça fait pareil
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#

11

A cast is a valid lvalue if its operand is an lvalue. A simple assignment whose left-hand side is a cast works by converting the right-hand side first to the specified type, then to the type of the inner left-hand side expression. After this is stored, the value is converted back to the specified type to become the value of the assignment. Thus, if a has type char*, the following two expressions are equivalent:

(int)a = 5
(int)(a = (char *)(int)5)

An assignment-with-arithmetic operation such as += applied to a cast performs the arithmetic using the type resulting from the cast, and then continues as in the previous case. Therefore, these two expressions are equivalent:

(int)a += 5
(int)(a = (char *)(int) ((int)a + 5))
http://tigcc.ticalc.org/doc/gnuexts.html#SEC70

Autrement dit (blabla) truc = machin c'est la même chose que truc = (blabla) machin, à la seule différence près que la valeur globale de l'expression (qui de toute façon ne sert presque jamais à rien tongue) aura le type blabla dans le premier cas alors qu'elle aura le type de truc dans le second. À moins que j'aie mal compris.
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#

12

Pas bête, merci smile D'après les règles de priorités, le cast porte sur i, mais on va tenter de forcer la priorité pour voir...

squalyl : Pour la recherche smile En fait je m'intéresse un peu au fonctionnement d'un parser C donc je suis amené à imaginer ce genre de codes tordus.
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

13

OK d'accord... C'est bizarre comme interprétation. La sémantique selon les règles de priorités ne correspond pas à la sémantique effective.
Beurk le C...
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

14

...et donc le code généré serait différent avec et sans le cast seulement si tu utilisais la valeur renvoyée par ton affectation, ce qui n'est pas le cas dans ton exemple ^^
edit (cross) : ouais c'est un peu fortement bizarre grin
(ceci dit a priori le cast de lvalue n'est pas dans le standard, là en l'occurrence c'est une extension GNU apparemment)
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#

15

Sally [edit] : C'est toute l'expression qui est castée. Ce n'est pas équivalent à "truc = (blabla) machin" car "(char)i= l" génère un move.w et pas un move.b + extension smile

./14 : OK smile
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

16

dans ton exemple, l a quel type ? int ? le comportement que tu décris ne me semble pas correspondre à la doc...

en effet d'après ce que je comprends de la doc... supposons que truc a le type blibli et machin le type blublu, alors ils disent que :
(blabla) truc = machin
est défini comme équivalent à :
(blabla) (truc = (blibli) ((blabla) machin))

mais il me semble qu'à partir du moment où on affecte à une variable de type blibli il y a un cast implicite non¹ ? (c'est peut-être là que je me trompe...)
donc que c'est équivalent à : (blabla) (truc = (blabla) machin) tout simplement, lequel, du point de vue des effets de bord, est équivalent à truc = (blabla) machin (le fait que le résultat de l'affectation soit recasté ne change quelque chose que si tu utilises ce résultat...)

Pour revenir à ton exemple, ils disent bien « converting the right-hand side first to the specified type », donc le l devrait d'abord être converti en char quoi qu'il arrive... ça correspond pas sorry (mais tu compiles en -O0 ? parce que sinon il peut avoir simplifié... par exemple il sait très bien au moment de la compilation que -1 sur 16 bits c'est pareil que -1 sur 8 bits puis une extension...)


¹c'est-à-dire que si j'écris truc = machin et que truc est de type blibli c'est équivalent à truc = (blibli) machin, non ? (sauf que j'aurai peut-être un warning dans le premier cas... bon effectivement ça fait déjà une différence ^^)
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#

17

-Os
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

18

Oui donc c'est normal, il n'est pas tenu de compiler rigoureusement tes instructions une à une, la seule contrainte est que l'assembleur généré ait *globalement* un comportement correspondant à la sémantique du code que tu as tapé, ce qui est le cas ici
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#

19

Oui
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

20

Attention, les lvalue casts sont interdits dans les GCC actuels, sauf TIGCC qui les rajoute dans un patch pour la compatibilité antérieure.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

21

22

Thibaut (./3) :
smile
En fait ma question, c'est : ça signifie quoi ?

L'intérêt principal est de pouvoir faire des += ou des ++ sur des pointeurs quand la taille d'un élément est différente :
void save(void *p) {
#define intp ((int *)p)
#define charp ((char *)p)
  while (varlist)
    *intp++ = varlist->data, varlist = varlist->next;
  *intp++ = 0;
  *charp++ = 'a';
  *charp++ = 'b';
  *intp++ = checksum;
}

-- ce serait plus lourd à écrire sans cette extension...

Par contre pour les entiers l'intérêt est quasiment nul, et pour les affectations toutes bêtes ça ne sert pas à grand-chose non plus (autant faire le cast dans le membre de droite)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

23

ça sert à quoi les expressions séparées par des virgules? confus j'ai déja vu ça mais quelle est la différence avec:

void save(void *p) { 
#define intp ((int *)p) 
#define charp ((char *)p) 
  while (varlist) 
    *intp++ = varlist->data;
    varlist = varlist->next; 
  *intp++ = 0; 
  *charp++ = 'a'; 
  *charp++ = 'b'; 
  *intp++ = checksum; 
}

24

C'est moins lisible, donc plus impressionnant cheeky
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

25

squalyl> la différence c'est que ton programme est buggé parce que t'as oublié les accolades -- je pense que ça répond à ta question tongue

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

26

lolpaf
et si j'ajoute des accolades autour de ces deux lignes ça devient équivalent à ce que t'as écrit?

la virgule sert à quoi, à faire une instruction multiple en une ligne?

27

oui, ça sert juste à regrouper deux expressions dans une même expression ^^

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

28

Très utile pour du free(p), p=NULL; : Tu peux le mettre dans une macro, utiliser ça juste après un if, et les indenteurs automatiques gardent ça sur une seule ligne.
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.

29

bref, je peux écrire tout mon programme avec des virgules a la place des pt virgules quoi... grin

30

Non.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »