1

Ce sujet est issu d'une discussion ayant dérivé sur deux thèmes distincts. Pour vous rendre sur le sujet d'origine, merci de cliquer sur ce lien
avatar
Ben, bouh, quoi :D

2

Zerosquare (./2675) :
sizeof(void) = 1


C'est possible, mais pas obligatoire, ça peux être 4
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.

3

Est-ce que ça peut être 5 ?

4

Pourquoi pas. De toute façon on s'en fout complètement. smile

5

trop pas non.

c'est pratique que ça vaille 1, ça permet de copier des octets sans avoir a caster tous les void* en char*.

6

Godzil (./2678) :
C'est possible, mais pas obligatoire, ça peux être 4
Je parlais pour GCC uniquement, cf le lien posté juste avant smile
squalyl (./2681) :
c'est pratique que ça vaille 1, ça permet de copier des octets sans avoir a caster tous les void* en char*.
Ouais mais ton code ne sera pas portable si tu fais ça.
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

7

c'est ptet le but...
avatar
Webmaster du site Ti-FRv3 (et aussi de DevLynx)
Si moins de monde enculait le système, alors celui ci aurait plus de mal à nous sortir de si grosses merdes !
"L'erreur humaine est humaine"©Nil (2006) // topics/6238-moved-jamais-jaurais-pense-faire-ca

8

heuuuuu, c'est standard ca, pouvoir faire une addition sur un void* ? trifus
parcequ'autant que je sache, normalement une addition de pointeur sur un void*, c'est pas valide, mais meme sizeof(void), c'est pas valide...
enfin c'est ptet une "feature" de gcc...
avatar
HURRRR !

9

(ah ben j'etais pas alle voir le lien dans le quote, mais ouai ok, c'est tout sauf standard... super tritop surtout vu ce que ca apporte...)
avatar
HURRRR !

10

sizeof(void) je l'ai jamais vu mais de l'arithmétique avec des void*, oui grin

je crois que c'est une extension GNU

d'ailleurs je crois qu'on peut demander à gcc un warning quand ça arrive et que VS doit faire le warning par défaut.

11

nan nan, sous visual c'est une erreur, c'est juste pas valide (enfin, en C++, mais en C aussi a priori, vu que t'es cense pouvoir build du C en C++)

"error C2036: 'void *' : unknown size"
avatar
HURRRR !

12

13

C'est la taille d'un objet élémentaire pointé, donc c'est pas idiot non plus. C'est une extension, ça se désactive, donc ce n'est que proposé, et c'est parfois très commode.

14

bah, j'imagine que tout depend comment tu utilises void*

pour moi, cette extension, c'est assez stupide dans le sens ou ca casse la securite que tu as de ne PAS pouvoir faire d'arithmetique de pointeurs avec du void* (deja que c'est un type dangereux, vu qu'il ne represente rien), ca devient source d'erreurs potentielles et de bugs sournois.
si tu as un pointeur qui est cense pointer vers une zone de donnees/octets brute, dans ce cas, t'utilise pas un void*, mais genre un unsigned char *, ou un unsigned __int8 *. un void *, ca pointe vers un endroit abstrait. ca peut tres bien etre un pointeur sur fonction, une classe, un tableau de donnees compressees, une liste de coordonnees dans l'espace en float3, une vtable, un offset dans un vertex buffer, un handle quelconque qui est en fait un index, bref. tout et rien a la fois.
si tu decide de manipuler du void*, l'implementation interne des trucs qui le manipulent devraient le caster _explicitement_ vers le vrai type, et pas se baser sur l'assomption que c'est en fait un char* deguise...
la tu dois de toutes facons quand meme faire un cast explicite pour lire/ecrire dedans, donc je vois franchement pas a quoi ca sert. ca rend le void un type batard entre l'ancien void et le char/unsigned char.

a mon humble avis -> poubelle.

mais ok, on peut le desactiver... (encore heureux tsss)
avatar
HURRRR !

15

le vrai but de void* a été de pouvoir déclarer une fonction memcpy() sans avoir à faire des versions pour chaque type grin

le cast en void* est automatique, mais l'inverse ne devrait pas l'être.

16

sauf que même ça, c'est devenu faux avec le C++ qui est bien plus rigoureux à ce niveau ; du coup pencil momotte
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

17

bearbecue (./2690) :
si tu as un pointeur qui est cense pointer vers une zone de donnees/octets brute, dans ce cas, t'utilise pas un void*, mais genre un unsigned char *, ou un unsigned __int8 *. un void *, ca pointe vers un endroit abstrait

Je vois pas en quoi un pointeur vers des "données quelconques" devrait plus être un char* qu'un void*, au contraire, cf la suite
bearbecue (./2690) :
la tu dois de toutes facons quand meme faire un cast explicite pour lire/ecrire dedans, donc je vois franchement pas a quoi ca sert

Et c'est justement ça qui est bien : t'es obligé de dire ce que tu vas lire ou écrire via ton void*, tu risques donc pas de faire les erreurs que tu ferais avec un char*.
Un void* est un type incomplet, donc il est normal de le compléter à l'utilisation, et il doit être utilisé pour ce pour quoi il est fait : la désignation d'un lieu où se trove on ne sait pas quoi, contrairement aux autres pointeurs dont le type indique ce qu'il y a au bout.

Et encore une fois, un char* pointe vers un char, pas vers "je sais pas trop quoi", sinon char* ne veut plus rien dire.

Enfin c'est mon avis, je ne suis pas informaticien, on pourra toujours me dire "pour qui tu te prends t'y connait rien", et c'est vrai. Mais je n'arrive pas à comprendre ce qui vous fait coincer.

18

Hého, c'est pas des meilleures quotes, vos trucs embarrassed
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

19

Heu Folco, je crois que vous êtes d'accord en fait. Quand tu ne sais pas vers quoi pointe ton pointeur, c'est normal d'utiliser void *, et tu ne peux ni y lire ni y écrire si tu ne complètes pas un peu son type. Ce qu'ajoute bearbecue, c'est que tu ne devrais pas non plus faire de l'arithmétique dessus. En effet, lors d'une addition, on est censé le faire par tailles de l'élément pointé entières, ce qui rend le sizeof(void) = 1 illogique et source de bogues. Il dit aussi que si en fait, tu connais la taille des éléments, tu n'as qu'à utiliser un type de la bonne taille à la place de void.

!askfork 2677;2678;2679;2680;2681;2682;2683;2684;2685;2686;2687;2688;2689;2690;2691;2692;2693;2696
avatar

20

Une fois n'est pas coutume, mais pencil
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

21

bearbecue (./14) :
un void *, ca pointe vers un endroit abstrait. ca peut tres bien etre un pointeur sur fonction, une classe, un tableau de donnees compressees, une liste de coordonnees dans l'espace en float3, une vtable, un offset dans un vertex buffer, un handle quelconque qui est en fait un index

Ok sauf pour un pointeur sur fonction:
Le standard C indique que :

6.3.2.3 Pointers
A pointer to void may be converted to or from a pointer to any incomplete or object
type. A pointer to any incomplete or object type may be converted to a pointer to void
and back again; the result shall compare equal to the original pointer.

et un objet ne peut pas être une fonction (Voir par exemple section 6.2.4)
Donc void * ne peut pas représenter un pointeur de fonction.

22

ah... un pointeur sur membre non statique (EDIT: qui peut de toutes facons lui-meme etre vu comme une structure contenant un pointeur sur fonction "basique" et un nombre variable d'autres infos implementation-specific), ok, mais un pointeur sur fonction? #trihum#

interessant... il y a des cas concrets ou ca peut ne pas etre valide? genre des archis tordues ou les pointeurs data/code ne sont pas comparables / dans le meme espace d'adressage ?
enfin autant que je sache, sur x86/64 et PPC, ca ne pose aucun probleme. (GCC et visual acceptent les casts sans broncher en tout cas, sans passer par un union, et niveau asm/memoire virtuelle, je vois pas ce qui pourrait coincer)
avatar
HURRRR !

23

bon ben je dois etre un peu couillon mais je vois pas ce qui dit qu'une fonction n'est pas un objet dans la section 6.2.4 Oo (jsuis alle voir ca: http://c0x.coding-guidelines.com/6.2.4.html et ca: http://www.open-std.org/jtc1/sc22/wg14/www/docs/C99RationaleV5.10.pdf )

une fonction, en reprenant les termes du 6.2.4, ca peut avoir un storage "static" ou "allocated", il n'y a rien qui me parait contradictoire entre la definition d'un objet et ce qu'est une fonction. apres il y a peut-etre une distinction faite pour les adresses dans des pages avec les droits en execution, mais je vois ca nulle part.. pis de toutes facons c'est architecture-specific tout ca... confus
avatar
HURRRR !

24

bearbecue (./23) :
genre des archis tordues ou les pointeurs data/code ne sont pas comparables / dans le meme espace d'adressage ?


oh oui plein, surtout en embarqué trioui

architecture harvard ça s'appelle, avec ça tu peux foutre 64k de code ET 64k de data sur un bus 16 bits (datas de 8 bits évidemment).

c'est pas si tordu, c'est même assez commun. Intel 8051, Microchip PIC, y'en a d'autres probablement (les atmega je sais pas). tout ce qui est un peu "industriel" en fait.
du coup pas d'exec en RAM.

(a coté de ça le Z80 et le 68HC11 ont des espaces von neumann normaux unifiés, ils sont plus destinés à être des microprocesseurs que des microcontrôleurs.)

sur ces deux controleurs, avec sdcc, par exemple, on a des pointeurs __code de 3 octets (20 bits) qui peuvent pas pointer dans les __data, et des pointeurs __data qui font 2 octets et peuvent pas pointer vers du code.

et puis t'as des pointeurs génériques de 24 bits dans lesquels les 4 MSbits disent le type du pointeur, et puis chaque dereference est remplacé par un call vers _gptrget(adr) ou _gptrput(adr,val) , deux fonctions qui font ce qu'elles disent grin - et génèrent du code de merde si tu sais pas ce que tu fais ^^

du coup des fois t'as des merdes d'incompatibilités entre les tableaux et les pointeurs:
const unsigned char[] values = {1,2,3,4};
unsigned char *ptr = values; //FAIL : const implique __code mais ptr est générique!

et ils sont en train de généraliser le truc pour avoir le support du banking transparent et des zones de mem non mappées en mémoire style carte SD, avec des types de pointeurs pour lesquels tu dois filer explicitement les fonctions get et put #trimalade#

25

ha ouai marrant ^^
avatar
HURRRR !

26

bearbecue (./23) :
bon ben je dois etre un peu couillon mais je vois pas ce qui dit qu'une fonction n'est pas un objet dans la section 6.2.4 Oo (jsuis alle voir ca: http://c0x.coding-guidelines.com/6.2.4.html et ca: http://www.open-std.org/jtc1/sc22/wg14/www/docs/C99RationaleV5.10.pdf )

une fonction, en reprenant les termes du 6.2.4, ca peut avoir un storage "static" ou "allocated", il n'y a rien qui me parait contradictoire entre la definition d'un objet et ce qu'est une fonction. apres il y a peut-etre une distinction faite pour les adresses dans des pages avec les droits en execution, mais je vois ca nulle part.. pis de toutes facons c'est architecture-specific tout ca... confus

C'est en fait une extension du C standard :

J.5 Common extensions
1 The following extensions are widely used in many systems, but are not portable to all
implementations. The inclusion of any extension that may cause a strictly conforming
program to become invalid renders an implementation nonconforming. Examples of such
extensions are new keywords, extra library functions declared in standard headers, or
predefined macros with names that do not begin with an underscore.

J.5.7 Function pointer casts
1 A pointer to an object or to void may be cast to a pointer to a function, allowing data to be invoked as a function (6.5.4).
2 A pointer to a function may be cast to a pointer to an object or to void, allowing a
function to be inspected or modified (for example, by a debugger) (6.5.4).

27

PpHd (./26) :
1 A pointer to an object or to void may be cast to a pointer to a function, allowing data to be invoked as a function (6.5.4).

Oh excellent, ça permet alors de faire un trampoline à la main (jmp + LibsPtr (x) par exemple ^^)

28

PpHd> ok smile

Folco> ouai, d'ailleurs il me semble que j'ai du poster dur yN du code qui fait ca pour interfacer des delegates C# avec du C++, ca genere des stubs dans une page en execution, qui appellent des fonctions membres, avec le 'this' stocke dans le stub, jsais plus ou c'etait (peut-etre dans videz votre presse-papier triso)
avatar
HURRRR !

29

non je crois que tu avais créé un topic.

30

bearbecue (./28) :
Folco> ouai, d'ailleurs il me semble que j'ai du poster dur yN du code qui fait ca pour interfacer des delegates C# avec du C++, ca genere des stubs dans une page en execution, qui appellent des fonctions membres, avec le 'this' stocke dans le stub, jsais plus ou c'etait (peut-etre dans videz votre presse-papier triso.gif )

Très excitant, ya donc pas qu'en asm qu'on peut se faire des trips à la noix trilove