66 votes

Est-il possible d'imprimer la taille d'une classe C++ au moment de la compilation ?

Est-il possible de déterminer la taille d'une classe C++ au moment de la compilation ?

Je crois me souvenir d'une méthode de métaprogrammation par modèle, mais je peux me tromper...


Désolé de ne pas avoir été plus clair - je veux que la taille soit imprimée dans la fenêtre de sortie de la construction.

0 votes

Bien sûr - sizeof(C) où C est la classe. L'imprimer est votre problème.

142voto

grep Points 2963

Si vous avez vraiment besoin d'obtenir sizeof(X) dans la sortie du compilateur, vous pouvez l'utiliser comme paramètre pour un type de modèle incomplet :

template<int s> struct Wow;
struct foo {
    int a,b;
};
Wow<sizeof(foo)> wow;

$ g++ -c test.cpp
test.cpp:5: error: aggregate ‘Wow<8> wow’ has incomplete type and cannot be defined

0 votes

C'est ce que je cherche ! Merci !

3 votes

Et si vous ne voulez pas d'erreur, mais simplement un avertissement, utilisez-le comme paramètre de modèle pour un type complet, et définissez ensuite un objet de ce type, par ailleurs inutilisé. C'est à dire Wow<sizeof(foo)> unused_warning; .

0 votes

Pour VS2010, n'oubliez pas de regarder la fenêtre 'Output', car la 'Error List' ne contient qu'un message condensé qui n'indique pas la valeur de la taille.

13voto

aalpern Points 502

Pour répondre à la question mise à jour, c'est peut-être un peu exagéré, mais cela permet d'imprimer la taille de vos classes au moment de la compilation. Il existe un commutateur de ligne de commande non documenté dans le compilateur Visual C++ qui affichera les dispositions complètes des classes, y compris leurs tailles :

Ce commutateur est /d1reportSingleClassLayoutXXX, où XXX effectue des correspondances de sous-chaîne avec le nom de la classe.

https://devblogs.microsoft.com/cppblog/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022/

1 votes

Bien sûr, j'aurais dû dire que cela ne s'applique qu'à Visual C++, puisque la question initiale ne précisait pas de plate-forme. Je ne travaille aujourd'hui que sur Windows, d'où mon parti pris.

0 votes

Il serait intéressant de savoir quelles versions du compilateur supportent ce commutateur.

4voto

elcuco Points 3953

Qu'est-ce qui ne va pas avec sizeof ? Cela devrait fonctionner sur les objets et les classes.

void foo( bar* b )
{
  int i = sizeof bar;
  int j = sizeof *b;

  // please remember, that not always i==j !!!
}

Edit :

Voici l'exemple auquel je pensais, mais pour une raison quelconque, il ne fonctionne pas. Quelqu'un peut-il me dire ce qui ne va pas ?

#include <iostream>
using namespace std;
class bar {
public: int i;
        bar( int ii ) { i = ii; }
        virtual ~bar(){ i = 0; }
        virtual void d() = 0;
};

class bar2: public bar {
public: long long j;
        bar2( int ii, long long jj ):bar(ii){ j=jj; }
        ~bar2() { j = 0; }
        virtual void d() { cout <<  "virtual" << endl; };
};

void foo( bar *b )
{
        int i = sizeof (bar);
        int j = sizeof *b;
        cout << "Size of bar = " << i << endl;
        cout << "Size of *b  = " << j << endl;
        b->d();
}

int main( int arcc, char *argv[] )
{
        bar2 *b = new bar2( 100, 200 );
        foo( b );
        delete b;
        return 0;
}

L'application a été exécutée sous linux (gcc 4.4.2) :

[elcuco@pinky ~/tmp] ./sizeof_test
Size of bar = 8
Size of *b  = 8
virtual

0 votes

@elcuco - la deuxième ligne devrait être sizeof(*b)

0 votes

@R Samuel : Ou juste sizeof *b . sizeof est un opérateur qui ne nécessite pas de parenthèses, sauf que les noms de types doivent être entourés de parenthèses, comme dans la syntaxe du casting.

5 votes

Quand est-ce que i!=j ? sizeof est calculé au moment de la compilation, et tout ce qui est connu est le type de l'argument - dans les deux cas, il s'agit de bar . Si vous avez une classe enfant de bar qui est plus grande, et que vous passez un pointeur vers une instance de l'enfant dans cette fonction, vous obtenez toujours la taille de l'enfant. bar - Le polymorphisme ne fonctionne pas à ce niveau.

2voto

R Samuel Klatchko Points 44549

Sizeof() détermine la taille au moment de la compilation.

Il ne fonctionne qu'au moment de la compilation, et vous ne pouvez donc pas l'utiliser avec le préprocesseur.

0 votes

Mais cela ne répond pas tout à fait à la question. Il est préférable d'en faire un commentaire.

0voto

Gaim Points 2614

Il y a un opérateur sizeof( int ) , sizeof( char ) Je pense donc que c'est possible et que l'appel ressemblera probablement à ce qui suit sizeof( MyClass )

1 votes

sizeof est un opérateur, pas une fonction. Vous ne pouvez pas prendre l'adresse de sizeof (alors que vous pouvez prendre l'adresse des fonctions). :-P

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X