Si une classe A contient un champ de type T, est-il garanti que sizeof(A)
sera un multiple entier de sizeof(T) ?
Par exemple, si je définis
class A {
int un;
double deux;
}
(ou double d'abord et int ensuite) et que je compile avec le compilateur
Intel, j'obtiens sizeof(A)==16 (sachant que sizeof(int)==4 et
sizeof(double)==8). Est-ce imposé par la norme ? Est-ce un comportement
général des compilateurs courants ?
Je suppose que sa fonction prend un déplacement et un pointeur vers double. Lui faire comprendre qu'elle peut avoir des A nécessiterait soit de la dupliquer pour tous les types possibles, soit en faire un template de fonctions (ce est qui la meilleure solution en C++ pour l'interface, quite à ce que l'implémentation du template fasse suivre à une fonction partagée entre les instances si la duplication est réellement un problème).
Je ne sais pas faire tout ça (en gros, je fais du C with classes). Je précise que je n'ai aucun contrôle sur la fonction : BLAS, ou Vector Math Library d'Intel.
Il me semble que ça a été dit, il n'est en rien garanti que sizeof(A) soit un multiple entier de sizeof(double). (Un int de 4 bytes et un double aligné sur 4 bytes ne me semble pas une absurdité, en fait je serais même surpris qu'aucun compilateur n'ait jamais utilisé ce mode).
Comme Olivier, je n'avais pas compris ça, et effectivement je n'avais pas envisagé qu'un type simple ne soit pas aligné sur sa taille.
Ceci dit, je n'ai pas besoin de portabilité sur des architectures anciennes. Mais je reconnais qu'on ne sait pas de quoi demain sera fait.
-- LL
Le 8 octobre 2012, Jean-Marc Bourguet a écrit :
Je suppose que sa fonction prend un déplacement et un pointeur vers
double. Lui faire comprendre qu'elle peut avoir des A nécessiterait soit de
la dupliquer pour tous les types possibles, soit en faire un template de
fonctions (ce est qui la meilleure solution en C++ pour l'interface, quite
à ce que l'implémentation du template fasse suivre à une fonction partagée
entre les instances si la duplication est réellement un problème).
Je ne sais pas faire tout ça (en gros, je fais du C with classes). Je
précise que je n'ai aucun contrôle sur la fonction : BLAS, ou Vector Math
Library d'Intel.
Il me semble que ça a été dit, il n'est en rien garanti que sizeof(A) soit
un multiple entier de sizeof(double). (Un int de 4 bytes et un double
aligné sur 4 bytes ne me semble pas une absurdité, en fait je serais même
surpris qu'aucun compilateur n'ait jamais utilisé ce mode).
Comme Olivier, je n'avais pas compris ça, et effectivement je n'avais pas
envisagé qu'un type simple ne soit pas aligné sur sa taille.
Ceci dit, je n'ai pas besoin de portabilité sur des architectures
anciennes. Mais je reconnais qu'on ne sait pas de quoi demain sera fait.
Je suppose que sa fonction prend un déplacement et un pointeur vers double. Lui faire comprendre qu'elle peut avoir des A nécessiterait soit de la dupliquer pour tous les types possibles, soit en faire un template de fonctions (ce est qui la meilleure solution en C++ pour l'interface, quite à ce que l'implémentation du template fasse suivre à une fonction partagée entre les instances si la duplication est réellement un problème).
Je ne sais pas faire tout ça (en gros, je fais du C with classes). Je précise que je n'ai aucun contrôle sur la fonction : BLAS, ou Vector Math Library d'Intel.
Il me semble que ça a été dit, il n'est en rien garanti que sizeof(A) soit un multiple entier de sizeof(double). (Un int de 4 bytes et un double aligné sur 4 bytes ne me semble pas une absurdité, en fait je serais même surpris qu'aucun compilateur n'ait jamais utilisé ce mode).
Comme Olivier, je n'avais pas compris ça, et effectivement je n'avais pas envisagé qu'un type simple ne soit pas aligné sur sa taille.
Ceci dit, je n'ai pas besoin de portabilité sur des architectures anciennes. Mais je reconnais qu'on ne sait pas de quoi demain sera fait.
-- LL
Lucas Levrel
Le 8 octobre 2012, Alain Ketterlin a écrit :
C'est cela qu'il faut faire, à mon avis. Des templates pour chaque cas, spécialisés sur le type (A ici). C'est tellement petit ces calculs d'adresse (et constant) que le compilo va inliner tout ça. Et s'il n'inline pas, ça veut dire qu'on ne veut pas optimiser, et donc autant avoir quelque chose de type-safe.
Bizarrement, j'ai des fonctions membres d'une ligne (avec un seul point-virgule et pas de boucle ;-) ) qui ne sont pas inline-ées si je ne les déclare pas inline. Du type :
void A::set_toto(A *ptr){toto=ptr;}
(où toto est un membre d'A, de type A*). Pourtant je compile avec -O3.
-- LL
Le 8 octobre 2012, Alain Ketterlin a écrit :
C'est cela qu'il faut faire, à mon avis. Des templates pour chaque cas,
spécialisés sur le type (A ici). C'est tellement petit ces calculs
d'adresse (et constant) que le compilo va inliner tout ça. Et s'il
n'inline pas, ça veut dire qu'on ne veut pas optimiser, et donc autant
avoir quelque chose de type-safe.
Bizarrement, j'ai des fonctions membres d'une ligne (avec un seul
point-virgule et pas de boucle ;-) ) qui ne sont pas inline-ées si je ne
les déclare pas inline. Du type :
void A::set_toto(A *ptr){toto=ptr;}
(où toto est un membre d'A, de type A*). Pourtant je compile avec -O3.
C'est cela qu'il faut faire, à mon avis. Des templates pour chaque cas, spécialisés sur le type (A ici). C'est tellement petit ces calculs d'adresse (et constant) que le compilo va inliner tout ça. Et s'il n'inline pas, ça veut dire qu'on ne veut pas optimiser, et donc autant avoir quelque chose de type-safe.
Bizarrement, j'ai des fonctions membres d'une ligne (avec un seul point-virgule et pas de boucle ;-) ) qui ne sont pas inline-ées si je ne les déclare pas inline. Du type :
void A::set_toto(A *ptr){toto=ptr;}
(où toto est un membre d'A, de type A*). Pourtant je compile avec -O3.
-- LL
Lucas Levrel
(moi)>>> ptr += sizeof(A)/sizeof(double);
Le 08/10/2012 15:25, Jean-Marc Bourguet a écrit :
Tant qu'à jouer à bas niveau, j'aurais tendance à faire
ptr = (double*)(((char*)ptr) + sizeof(A));
Le 8 octobre 2012, Olivier Miakinen a écrit :
Oui. C'est un chouia plus lisible... ou du moins c'est plus courant.
C'est sans doute plus courant, mais je trouve ça moins lisible ; on passe par un type qui n'apparaît pas explicitement dans le problème. Quand je déclare un double*, je sais qu'il sera incrémenté par pas de sizeof(double). Il me paraît donc naturel de demander sizeof(A)/sizeof(double) pas. Mais pour ça je dois m'assurer de la divisibilité bien sûr, d'où ce fil...
-- LL
(moi)>>> ptr += sizeof(A)/sizeof(double);
Le 08/10/2012 15:25, Jean-Marc Bourguet a écrit :
Tant qu'à jouer à bas niveau, j'aurais tendance à faire
ptr = (double*)(((char*)ptr) + sizeof(A));
Le 8 octobre 2012, Olivier Miakinen a écrit :
Oui. C'est un chouia plus lisible... ou du moins c'est plus courant.
C'est sans doute plus courant, mais je trouve ça moins lisible ; on passe
par un type qui n'apparaît pas explicitement dans le problème. Quand je
déclare un double*, je sais qu'il sera incrémenté par pas de
sizeof(double). Il me paraît donc naturel de demander
sizeof(A)/sizeof(double) pas. Mais pour ça je dois m'assurer de la
divisibilité bien sûr, d'où ce fil...
Tant qu'à jouer à bas niveau, j'aurais tendance à faire
ptr = (double*)(((char*)ptr) + sizeof(A));
Le 8 octobre 2012, Olivier Miakinen a écrit :
Oui. C'est un chouia plus lisible... ou du moins c'est plus courant.
C'est sans doute plus courant, mais je trouve ça moins lisible ; on passe par un type qui n'apparaît pas explicitement dans le problème. Quand je déclare un double*, je sais qu'il sera incrémenté par pas de sizeof(double). Il me paraît donc naturel de demander sizeof(A)/sizeof(double) pas. Mais pour ça je dois m'assurer de la divisibilité bien sûr, d'où ce fil...
Un multiple entier du plus grand des champs, ou un multiple entier du plus grand des alignements requis ?
Multiple entier du ppcm des alignements. (En pratique, je n'ai jamais vu de contraintes d'alignement qui ne soit pas des puissances de 2, meme si je suis a peu pres sur d'avoir vu une telle contrainte proposee pour les instructions, en pratique donc multiple entier du plus grand des alignements).
Tu as des contraintes d'alignement de pile et de trame pour les instructions sse qui combinees ensemble te donnent des valeurs de type = 8 (module 16)...
In article <pxb391oyt39.fsf@bourguet.org>,
Jean-Marc Bourguet <jm@bourguet.org> wrote:
Un multiple entier du plus grand des champs, ou un multiple entier du
plus grand des alignements requis ?
Multiple entier du ppcm des alignements. (En pratique, je n'ai jamais vu
de contraintes d'alignement qui ne soit pas des puissances de 2, meme si
je suis a peu pres sur d'avoir vu une telle contrainte proposee pour les
instructions, en pratique donc multiple entier du plus grand des
alignements).
Tu as des contraintes d'alignement de pile et de trame pour les instructions
sse qui combinees ensemble te donnent des valeurs de type = 8 (module 16)...
Un multiple entier du plus grand des champs, ou un multiple entier du plus grand des alignements requis ?
Multiple entier du ppcm des alignements. (En pratique, je n'ai jamais vu de contraintes d'alignement qui ne soit pas des puissances de 2, meme si je suis a peu pres sur d'avoir vu une telle contrainte proposee pour les instructions, en pratique donc multiple entier du plus grand des alignements).
Tu as des contraintes d'alignement de pile et de trame pour les instructions sse qui combinees ensemble te donnent des valeurs de type = 8 (module 16)...
Lucas Levrel
Le 9 octobre 2012, Alain Ketterlin a écrit :
Jamais vu ce genre de cas en -O3 avec gcc. Assure-toi que le code est visible là ou elles sont appelées (sinon, pas d'inline évidemment), qu'elle ne sont pas virtual, etc.
Les one-liners sont définies dans le même fichier que toutes les fonctions qui y font appel. Ces fonctions, elles, sont appelées dans différents fichiers. Je compile avec icc.
-- LL
Le 9 octobre 2012, Alain Ketterlin a écrit :
Jamais vu ce genre de cas en -O3 avec gcc. Assure-toi que le code est
visible là ou elles sont appelées (sinon, pas d'inline évidemment),
qu'elle ne sont pas virtual, etc.
Les one-liners sont définies dans le même fichier que toutes les fonctions
qui y font appel. Ces fonctions, elles, sont appelées dans différents
fichiers. Je compile avec icc.
Jamais vu ce genre de cas en -O3 avec gcc. Assure-toi que le code est visible là ou elles sont appelées (sinon, pas d'inline évidemment), qu'elle ne sont pas virtual, etc.
Les one-liners sont définies dans le même fichier que toutes les fonctions qui y font appel. Ces fonctions, elles, sont appelées dans différents fichiers. Je compile avec icc.
Un multiple entier du plus grand des champs, ou un multiple entier du plus grand des alignements requis ?
Multiple entier du ppcm des alignements. (En pratique, je n'ai jamais vu de contraintes d'alignement qui ne soit pas des puissances de 2, meme si je suis a peu pres sur d'avoir vu une telle contrainte proposee pour les instructions, en pratique donc multiple entier du plus grand des alignements).
Tu as des contraintes d'alignement de pile et de trame pour les instructi ons sse qui combinees ensemble te donnent des valeurs de type = 8 (module 1 6)...
Interessant. J'ai pas le temps de regarder pour confirmer, mais il me semble qu'on sort du cadre de ce qui est exprimable comme contrainte d'alignement en C11 et C++11. (En passant, je me demande d'ailleurs si ces normes ne contraignent pas l'alignement a etre des puissances de 2, il faudra que je regarde).
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index. html Site de usenet-fr: http://www.usenet-fr.news.eu.org
espie@lain.home (Marc Espie) writes:
In article <pxb391oyt39.fsf@bourguet.org>,
Jean-Marc Bourguet <jm@bourguet.org> wrote:
Un multiple entier du plus grand des champs, ou un multiple entier du
plus grand des alignements requis ?
Multiple entier du ppcm des alignements. (En pratique, je n'ai jamais vu
de contraintes d'alignement qui ne soit pas des puissances de 2, meme si
je suis a peu pres sur d'avoir vu une telle contrainte proposee pour les
instructions, en pratique donc multiple entier du plus grand des
alignements).
Tu as des contraintes d'alignement de pile et de trame pour les instructi ons
sse qui combinees ensemble te donnent des valeurs de type = 8 (module 1 6)...
Interessant. J'ai pas le temps de regarder pour confirmer, mais il me
semble qu'on sort du cadre de ce qui est exprimable comme contrainte
d'alignement en C11 et C++11. (En passant, je me demande d'ailleurs si
ces normes ne contraignent pas l'alignement a etre des puissances de 2,
il faudra que je regarde).
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index. html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Un multiple entier du plus grand des champs, ou un multiple entier du plus grand des alignements requis ?
Multiple entier du ppcm des alignements. (En pratique, je n'ai jamais vu de contraintes d'alignement qui ne soit pas des puissances de 2, meme si je suis a peu pres sur d'avoir vu une telle contrainte proposee pour les instructions, en pratique donc multiple entier du plus grand des alignements).
Tu as des contraintes d'alignement de pile et de trame pour les instructi ons sse qui combinees ensemble te donnent des valeurs de type = 8 (module 1 6)...
Interessant. J'ai pas le temps de regarder pour confirmer, mais il me semble qu'on sort du cadre de ce qui est exprimable comme contrainte d'alignement en C11 et C++11. (En passant, je me demande d'ailleurs si ces normes ne contraignent pas l'alignement a etre des puissances de 2, il faudra que je regarde).
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index. html Site de usenet-fr: http://www.usenet-fr.news.eu.org
espie
In article , Jean-Marc Bourguet wrote:
Interessant. J'ai pas le temps de regarder pour confirmer, mais il me semble qu'on sort du cadre de ce qui est exprimable comme contrainte d'alignement en C11 et C++11. (En passant, je me demande d'ailleurs si ces normes ne contraignent pas l'alignement a etre des puissances de 2, il faudra que je regarde).
Je te rassure, mais le vieux code de pthread (et le code noyau de gestion de threads) qui gerait ca cree de toutes facons ses piles a la main, en assembleur.
Meme aujourd'hui, surtout en presence d'optimiseurs agressifs comme gcc.
Typiquement, il y a quelques options pour respecter ce genre de souci d'ABI dans ton compilo... parce que typiquement, l'alignement de ta pile est susceptible de changer selon les instructions que tu veux utiliser, et parfois tu peux te retrouver a devoir reforcer le bon alignement de pile en entree d'une fonction qui fait du sse, sachant que tu viens de trucs plus "packes" que le reste.
Ca a toujours ete comme ca, et meme si C++ gere de plus en plus de trucs bas niveau, les choses continuent quand meme d'evoluer.
(et je crois qu'on a des archis sur lesquelles on peut faire du multi-thread, mais ou le modele de C++2011 d'atomics ne mappe pas correctement sur l'archi).
In article <pxby5jfyb3t.fsf@bourguet.org>,
Jean-Marc Bourguet <jm@bourguet.org> wrote:
Interessant. J'ai pas le temps de regarder pour confirmer, mais il me
semble qu'on sort du cadre de ce qui est exprimable comme contrainte
d'alignement en C11 et C++11. (En passant, je me demande d'ailleurs si
ces normes ne contraignent pas l'alignement a etre des puissances de 2,
il faudra que je regarde).
Je te rassure, mais le vieux code de pthread (et le code noyau de gestion
de threads) qui gerait ca cree de toutes facons ses piles a la main, en
assembleur.
Meme aujourd'hui, surtout en presence d'optimiseurs agressifs comme gcc.
Typiquement, il y a quelques options pour respecter ce genre de souci
d'ABI dans ton compilo... parce que typiquement, l'alignement de ta pile
est susceptible de changer selon les instructions que tu veux utiliser,
et parfois tu peux te retrouver a devoir reforcer le bon alignement de
pile en entree d'une fonction qui fait du sse, sachant que tu viens
de trucs plus "packes" que le reste.
Ca a toujours ete comme ca, et meme si C++ gere de plus en plus de
trucs bas niveau, les choses continuent quand meme d'evoluer.
(et je crois qu'on a des archis sur lesquelles on peut faire du multi-thread,
mais ou le modele de C++2011 d'atomics ne mappe pas correctement sur l'archi).
Interessant. J'ai pas le temps de regarder pour confirmer, mais il me semble qu'on sort du cadre de ce qui est exprimable comme contrainte d'alignement en C11 et C++11. (En passant, je me demande d'ailleurs si ces normes ne contraignent pas l'alignement a etre des puissances de 2, il faudra que je regarde).
Je te rassure, mais le vieux code de pthread (et le code noyau de gestion de threads) qui gerait ca cree de toutes facons ses piles a la main, en assembleur.
Meme aujourd'hui, surtout en presence d'optimiseurs agressifs comme gcc.
Typiquement, il y a quelques options pour respecter ce genre de souci d'ABI dans ton compilo... parce que typiquement, l'alignement de ta pile est susceptible de changer selon les instructions que tu veux utiliser, et parfois tu peux te retrouver a devoir reforcer le bon alignement de pile en entree d'une fonction qui fait du sse, sachant que tu viens de trucs plus "packes" que le reste.
Ca a toujours ete comme ca, et meme si C++ gere de plus en plus de trucs bas niveau, les choses continuent quand meme d'evoluer.
(et je crois qu'on a des archis sur lesquelles on peut faire du multi-thread, mais ou le modele de C++2011 d'atomics ne mappe pas correctement sur l'archi).
ptyxs
Le 05/10/2012 21:38, Benoit Izac a écrit :
Quel est l'intérêt d'utiliser une classe sans méthode plutôt qu 'une structure ?
En C+++ une structure et une classe c'est exactement la même chose. C'est une simple convention fréquente mais en rien obligatoire d'appele r plutôt structure les classes qui ne possèdent que des données publi ques.
Le 05/10/2012 21:38, Benoit Izac a écrit :
Quel est l'intérêt d'utiliser une classe sans méthode plutôt qu 'une
structure ?
En C+++ une structure et une classe c'est exactement la même chose.
C'est une simple convention fréquente mais en rien obligatoire d'appele r
plutôt structure les classes qui ne possèdent que des données publi ques.
Quel est l'intérêt d'utiliser une classe sans méthode plutôt qu 'une structure ?
En C+++ une structure et une classe c'est exactement la même chose. C'est une simple convention fréquente mais en rien obligatoire d'appele r plutôt structure les classes qui ne possèdent que des données publi ques.