Boo
./1
Folco - Posté le 02/01/2010 à 22:27 Membre depuis le 18/06/2001, 29821 messages
J'ai un souci avec les déclarations, au niveau des const.

Quand je fais un
const unsigned char* truc;

quelle est la différence avec un
unsigned char* truc;

? Dans les deux cas, j'arrive à faire un
truc++;
(*truc)++;

Quand je fais un
unsigned char* const truc;

Je ne peux plus modifier le pointeur, mais toujours les éléments pointés.

Comment faire pour définir :
- un pointeur modifiables sur des données non modifiables ?
- un pointeur non modifiables sur des données modifiables ?
- un pointeur non modifiable sur des données non modifiables ?

Mici happy
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./2
geogeo - Posté le 02/01/2010 à 22:33 - Edité par geogeo le 02/01/2010 à 22:42 Membre depuis le 06/02/2003, 7215 messages
unsigned char* p = La variable p et son contenu peuvent être modifiés
const unsigned char* p = Le contenu pointé par la variable p ne peut être modifié.
unsigned char* const p = La variable p ne peut être modifiée.
Et suspense, const unsigned char* const p = La variable et son contenu pointé ne peuvent être modifiés.
avatar la Nature nous montre seulement la queue du lion. Mais je suis certain que le lion a qui elle appartient pense qu'il ne peut pas se révéler en une fois en raison de son immense taille.

- Fondateur de Ti-Gen -: http://www.tigen.org

- Membre du Groupe Orage Studio -: http://oragestudio.free.fr/

- Mon site perso -: http://tisofts.free.fr

Projets TI68K en cours:
GFA-Basic = http://www.tigen.org/gfabasic
Arkanoid.
PolySnd 3.0.
./3
Folco - Posté le 02/01/2010 à 22:36 - Edité par Folco le 02/01/2010 à 22:44 Membre depuis le 18/06/2001, 29821 messages
[22:31:15] <@Vertyos> (18:39:34) (Vertyos) const char* const maChaine = "kikoo";
[22:31:16] <@Vertyos> (18:39:51) (Vertyos) le bleu veut dire que les données pointées sont constantes (tu ne peux pas écrire maChaine[0] = 'a')
[22:31:16] <@Vertyos> (18:40:06) (Vertyos) le rouge veut dire que le pointeur est constant (tu ne peux pas écrire maChaine = (void*)0)

Mea culpa, mes courtes vaccances m'ont fait oublier ce qu'on m'avait posté plus tôt. Qui plus est, certains de mes tests ont dû foirer du coup.
J'ai cru comprendre qu'on ne recevait pas de warning si un test (genre *Ptr++) ne générait aucun code binaire "efficace" dans le programme, et donc le warning attendu ne se produit pas. Il faut alors faire un "return *Ptr++" pour être sûr que ce soit pris en compte (mais c'est chiant, faut modifier le proto dans le source et le header #sick#)

cross -> Merci quand même geogeo pour ton explication happy
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./4
geogeo - Posté le 02/01/2010 à 22:44 Membre depuis le 06/02/2003, 7215 messages
Non mais j'ai fumé aussi. Je viens d'édité mon post.
avatar la Nature nous montre seulement la queue du lion. Mais je suis certain que le lion a qui elle appartient pense qu'il ne peut pas se révéler en une fois en raison de son immense taille.

- Fondateur de Ti-Gen -: http://www.tigen.org

- Membre du Groupe Orage Studio -: http://oragestudio.free.fr/

- Mon site perso -: http://tisofts.free.fr

Projets TI68K en cours:
GFA-Basic = http://www.tigen.org/gfabasic
Arkanoid.
PolySnd 3.0.
./5
Lionel Debroux - Posté le 03/01/2010 à 08:32 Membre depuis le 28/10/2001, 7564 messages
"const" est faible en C, dans le sens où un cast permet quand même de modifier une variable "const", si elle est stockée en RAM non protégée par une MMU:
const int toto;
*(int*)&toto = 1; // no problem, à moins qu'une MMU existe et protège en écriture la page contenant toto -> segmentation fault

En C++, le compilo refuse de faire ça.
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
./6
Folco - Posté le 03/01/2010 à 09:04 Membre depuis le 18/06/2001, 29821 messages
Je comprends mal pourquoi... Comment le compilateur pourrait-il interprêter autrement *(int*)&toto que en int toto ? Donc comment se fait-il berner si facilement ?
Bon puis toute façon, j'aime pas trop l'idée de tricher de cette manière, j'essaye tant que possible de rester propre, et j'ai du mal, je débute.

D'ailleurs un de ces 4, je vais poster mon code pour le soumettre à la critique et à l'audit populaire afin d'en retirer quelques fructueux conseils. cheeky
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
./7
Sasume - Posté le 03/01/2010 à 10:39 Membre depuis le 28/08/2003, 8213 messages
Folco (./6) :
Je comprends mal pourquoi... Comment le compilateur pourrait-il interprêter autrement *(int*)&toto que en int toto ? Donc comment se fait-il berner si facilement ?
Il ne se fait pas berner, le langage C permet simplement de faire ce genre de choses, c'est tout. Ce n'est pas un langage qui force à être propre.
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
GoldenCrystal - Posté le 03/01/2010 à 10:53 Membre depuis le 15/06/2003, 7902 messages
Oui et puis c'est pas tricher, c'est juste forcer le compilateur à générer du code incorrect. Mais le compilateur s'en fout, il fait juste ce que tu lui demandes tant qu'il comprend ce que tu lui demandes.
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
./9
Brunni - Posté le 03/01/2010 à 11:10 - Edité par Brunni le 03/01/2010 à 11:18 Membre depuis le 03/11/2002, 11561 messages
Lionel Debroux (./5) :
"const" est faible en C, dans le sens où un cast permet quand même de modifier une variable "const", si elle est stockée en RAM non protégée par une MMU:
const int toto;
*(int*)&toto = 1; // no problem, à moins qu'une MMU existe et protège en écriture la page contenant toto -> segmentation fault

En C++, le compilo refuse de faire ça.

Ha bon? Je vois pas de raison qu'il te refuse ça (et avec MSVC++ ça marche en tous cas).
Mais de toute Folco c'est comme en assembleur, rien ne t'empêche de faire un truc du genre en pseudo-asm:
[nosmile]
    .section text
pwet:
.long 0

$main
mov r0, :pwet
mov (r0), 1
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/
GoldenCrystal - Posté le 03/01/2010 à 11:17 Membre depuis le 15/06/2003, 7902 messages
Normalement il est sensé refuser le cast de [truc] constant vers [truc] non constant. Tout au moins il doit émettre un warning si mes souvenirs sont bons.
Mais de toutes façons (c'est plus visible en C++) le fait que tu réussisse à modifier la mémoire (en supposant que ce soit le cas) ne signifie pas que tu es arrivé à tes fins. Le const a une signification trop importante dans le code pour que ça soit aussi simple que ça.
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
PpHd - Posté le 03/01/2010 à 11:19 Membre depuis le 11/06/2001, 19223 messages
g++ aussi (sans warning).
Mais je ne suis pas un expert C++ (surtout que le const C++ ne veut pas dire la même chose que le const C).
Et le code généré est à moitié correct.
Brunni - Posté le 03/01/2010 à 11:19 Membre depuis le 03/11/2002, 11561 messages
Ha ben j'ai même pas essayé de le lancer, c'est certain que ça va faire un segfault...
[Edit] Ha ben non!
	const int i = 0;
*(int*)&i = 1;
std::cout << i << std::endl;

Donne 0 en sortie... (en mode debug)
En fait VC++ pousse directement 0 sur la pile puisqu'il prend ça pour une constante et crée un emplacement dans la section des variables pour référencer i, donc c'est un mauvais exemple.
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/
GoldenCrystal - Posté le 03/01/2010 à 11:29 Membre depuis le 15/06/2003, 7902 messages
Effectivement, pas de warning, mais:
thunder:~ Fabien$ cat test.cpp && g++ -Wall test.cpp -o test && ./test
#include <iostream>

const int val = 1;

using namespace std;

int main(int argc, char *argv[])
{
const int *pValOk = &val;
int *pValNok = (int*)&val;

*pValNok = 2;
cout << "Val: " << val << endl << "Val 1: " << *pValOk << endl << "Val 2: " << *pValNok << endl;

return 0;
}

Bus error
(Mac OS X 10.5.8)
EDIT: ./12 > Ouais c'est ce que je voulais dire par "signification trop importante" 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
Brunni - Posté le 03/01/2010 à 11:36 Membre depuis le 03/11/2002, 11561 messages
Pareil sous VC++ à ce moment. Ca n'a pas causé de problème avec mon exemple parce que les const int comme ça sont traités d'une façon plus proche du #define. C'est le genre de bidouille qui permet d'écrire:
struct {
static const unsigned TAILLE = 32;
int truc[TAILLE];
};
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/
Folco - Posté le 03/01/2010 à 12:27 Membre depuis le 18/06/2001, 29821 messages
Vous voulez me mettre le pied à l'étrier pour lc C++ ou quoi ? cheeky
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
Lionel Debroux - Posté le 03/01/2010 à 12:55 Membre depuis le 28/10/2001, 7564 messages
Nan, je voulais juste compléter la sémantique de "const" par rapport à ./2 et ./3 (avec une information qui s'avère finalement fausse... il me semblait que les compilos courants étaient plus stricts que ça !) grin
Comme GC le montre en ./13, il faut que la variable "const" soit globale pour qu'il puisse y avoir une protection de la MMU. C'était évident dans ma tête, mais j'aurais dû le marquer.
avatar Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.
squalyl - Posté le 03/01/2010 à 14:12 Membre depuis le 16/06/2001, 59735 messages
et que donne ça? (parce que la pile c'est tricher, les pages de pile sont à accès RW)

GoldenCrystal (./13) :
Effectivement, pas de warning, mais:
thunder:~ Fabien$ cat test.cpp && g++ -Wall test.cpp -o test && ./test
#include <iostream>

const int val = 1;
const int *pValOk = &val;
int *pValNok = (int*)&val;

using namespace std;

int main(int argc, char *argv[])
{

*pValNok = 2;
cout << "Val: " << val << endl << "Val 1: " << *pValOk << endl << "Val 2: " << *pValNok << endl;

return 0;
}

Bus error
(Mac OS X 10.5.8)
EDIT: ./12 > Ouais c'est ce que je voulais dire par "signification trop importante" tongue

GoldenCrystal - Posté le 03/01/2010 à 14:24 Membre depuis le 15/06/2003, 7902 messages
La même chose tongue J'ai quand même testé au cas où cheeky
Le truc important c'est que la variable soit globale (mais pas static ^^) pour pas qu'elle ne soit optimisée par le compilo. Pour le reste les deux autres auront le même comportement apparent en local ou global donc pas vraiment important. (Evidemment pour des raisons d'optimisation/performance/propreté c'est toujours mieux de mettre en local quand c'est possible)
(Et bien sur pour la version où la variable est mise/optimisée en local, voir ./12)
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
Zerosquare - Posté le 03/01/2010 à 17:01 Membre depuis le 27/04/2006, 43233 messages
Quelqu'un pourrait poster un exemple de programme Windows qui plante à cause d'un accès en écriture à une variable const ?
Je suis curieux de voir comment c'est implémenté dans l'exécutable.
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
Zerosquare - Posté le 03/01/2010 à 17:08 Membre depuis le 27/04/2006, 43233 messages
Ah oui, et si vous voulez pas que le compilo s'amuser à optimiser les accès aux variables, suffit de mettre volatile comme attribut.
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
GoldenCrystal - Posté le 03/01/2010 à 17:16 Membre depuis le 15/06/2003, 7902 messages
Normalement c'est tout bêtement fait avec les différentes sections de l'éxécutable. De mémoire pour les variables [globales] en lecture seule c'est .rdata .
Et le volatile ça a quand même une signification un peu différente, c'est pas bien d'utiliser ça pour ça 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
squalyl - Posté le 03/01/2010 à 17:24 Membre depuis le 16/06/2001, 59735 messages
j'aurais dit comme GC, les const en .rdata avec des pages read only.
Zerosquare - Posté le 03/01/2010 à 17:26 Membre depuis le 27/04/2006, 43233 messages
C'est ce que je pensais, mais j'avais oublié l'existence des sections .rdata.

Pour le volatile, c'est vrai que c'est pas explicitement le but de ce mot-clé, mais ça a l'effet secondaire désiré. ^^
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
Ximoon - Posté le 03/01/2010 à 18:24 Membre depuis le 30/06/2001, 35345 messages
Zerosquare (./19) :
Quelqu'un pourrait poster un exemple de programme Windows qui plante à cause d'un accès en écriture à une variable const ?
Je suis curieux de voir comment c'est implémenté dans l'exécutable.

Je peux te donner des exemples en embarqué si tu veux grin
avatar Que cache le pays des Dieux ? - Ximoon's Box - Forum Ghibli - Forum Littéraire

La fin d'un monde souillé est venue. L'oiseau blanc plane dans le ciel annonçant le début d'une longue ère de purification. Détachons-nous à jamais de notre vie dans ce monde de souffrance. Ô toi l'oiseau blanc, l'être vêtu de bleu, guide nous vers ce monde de pureté. - Sutra originel dork.
Zerosquare - Posté le 03/01/2010 à 18:32 Membre depuis le 27/04/2006, 43233 messages
Je parle du fait que ce soit protégé en écriture, pas du fait que ça plante #hehe#
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
Ximoon - Posté le 03/01/2010 à 19:34 Membre depuis le 30/06/2001, 35345 messages
Si c'est mappé en mémoire en lecture seule, hop !
avatar Que cache le pays des Dieux ? - Ximoon's Box - Forum Ghibli - Forum Littéraire

La fin d'un monde souillé est venue. L'oiseau blanc plane dans le ciel annonçant le début d'une longue ère de purification. Détachons-nous à jamais de notre vie dans ce monde de souffrance. Ô toi l'oiseau blanc, l'être vêtu de bleu, guide nous vers ce monde de pureté. - Sutra originel dork.
Kevin Kofler - Posté le 05/01/2010 à 19:26 Membre depuis le 10/06/2001, 34843 messages
C'est .rodata pour la lecture seule.
avatar Mes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
squalyl - Posté le 06/01/2010 à 00:32 Membre depuis le 16/06/2001, 59735 messages
pas sous windows
Folco - Posté le 10/02/2010 à 01:01 Membre depuis le 18/06/2001, 29821 messages
Bon, je reprends un vieux topic pour une simple question :

C'est normal de devoir écrire des casts aussi brutaux ?
if (!memcmp((void*)CustomType, (void*)&(((char*)FilePtr)[FileSize - 5]), 6))

FilePtr est un void*, qui me sert à calculer l'adresse d'un char (FileSize - 5), mais je dois passer à memcmp un pointeur sur un void, d'où le (void*)&.
Ya pas moyen de faire plus lisible ? Plus intelligent ? Là ça me semble fouilli... Pourtant, en assembleur, ça serait tout con de calculer ce pointeur :

movea.l FilePtr(pc),a0
move.w FileSize(pc),d0
lea -5(a0,d0.w),a0

Ca y est, je l'ai mon pointeur void avec ça... Ya pas plus clean et compréhensible à l'oeil ?

ok, ça foirerait pour FileSize >= 2^15 mais là on s'en fout cheeky
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
Kevin Kofler - Posté le 10/02/2010 à 04:23 Membre depuis le 10/06/2001, 34843 messages
Ce n'est pas normal de devoir écrire ce genre de casts, c'est plutôt un indice que tu essaies d'écrire du C comme si c'était de l'assembleur. #hehe#
avatar Mes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é