1

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

2

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

[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

4

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

"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

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

7

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

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

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:
v (r0), 1
[nosmile]    .section text
pwet:
    .long 0

$main
    mov r0, :pwet
    mo
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

10

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

11

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.

12

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

13

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

14

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

15

Vous voulez me mettre le pied à l'étrier pour lc C++ ou quoi ? cheeky

16

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.

17

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

18

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

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

20

Ah oui, et si vous voulez pas que le compilo s'amuser à optimiser les accès aux variables, suffit de mettre volatile comme attribut.
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

21

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

22

j'aurais dit comme GC, les const en .rdata avec des pages read only.

23

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

24

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

25

Je parle du fait que ce soit protégé en écriture, pas du fait que ça plante hehe
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

26

Si c'est mappé en mémoire en lecture seule, hop !
avatar
Que cache le pays des Dieux ? - 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.

27

C'est .rodata pour la lecture seule.
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é

28

29

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

30

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