web-dev-qa-db-fra.com

Sizeof (void ()) est-il une expression légale?

De [5.3.3/1] , j'ai trouvé que:

L'opérateur sizeof ne doit pas être appliqué à une expression ayant une fonction ou un type incomplet

De [3.9/5] J'ai trouvé que:

Les types d'objets incomplètement définis et cv void sont des types incomplets

Quoi qu'il en soit, car sizeof n'évalue pas ses opérandes, j'aurais dit que sizeof(void()) était une expression légale (en fait, GCC le compile et le résultat est 1).
De l'autre côté, de ici , void n'est pas mentionné lors de la discussion de sizeof, ni lorsque les types ayant la taille 1 sont mentionnés, ni dans la liste de ceux ayant une implémentation définie taille.

La question est donc: sizeof(void()) est-elle une expression légale?
Est-il garanti que la taille est égale à 1?
Ou est-ce une expression légale aboutissant à un UB et c'est tout?

50
skypjack

void() est un type de fonction (c'est une fonction qui ne prend aucun argument et ne renvoie rien), donc ce n'est pas un type valide dans sizeof().

58

En regardant CppReference.com - opérateur sizeof , la documentation indique littéralement:

sizeof ne peut pas être utilisé avec les types de fonction , les types incomplets ou les valeurs de champ binaires.

Et puisque void() est un type de fonction, alors sizeof(void()) n'est pas une expression légale.

Dans leur exemple d'utilisation, nous pouvons voir leur commentaire d'erreur sur cette ligne:

std::cout << "size of function: " << sizeof(void()) << '\n'; // error
39
Khalil Khalaf

Une petite prémisse.

La question est née d'une mauvaise interprétation de l'opérateur sizeof.
En fait, l'OP a considéré void() une expression de type incomplet dans le contexte de sizeof et la question elle-même peut être lue comme - pourquoi sizeof accepte l'expression void(), qui est un type incomplet et ne doit pas être acceptée comme mentionné dans le projet de travail?
C'est pourquoi [3.9/5] est mentionné en fait, sinon cela n'aurait pas eu de sens.

Cela dit, le fait est que la question contient en fait deux questions intéressantes:

  • Pourquoi sizeof(void()) n'est-il pas légal?
    C'est la vraie question à partir du titre lui-même.

  • Pourquoi sizeof((void())) n'est-il pas légal?
    Telle est la question prévue du PO.

Réponses ci-dessous:

  • void() dans sizeof(void()) est interprété comme un type de fonction et il est mal formé comme pour [5.3.3/1] (accent sur le mien):

    L'opérateur sizeof ne doit pas être appliqué à une expression de type fonction ou incomplète , au nom entre parenthèses d'un tel types , [...]

  • (void()) Dans sizeof((void())) est une expression de type incomplet void (notez que sizeof est un contexte non évalué) et elle est mal formée comme pour - [5.3.3/1] (soulignement le mien):

    L'opérateur sizeof ne doit pas être appliqué à une expression qui a une fonction ou de type incomplet , au nom entre parenthèses de ces types, [...]

Dans les deux cas, GCC compile le code avec un avertissement.

6
skypjack

Comme déjà souligné dans les documents ici http://en.cppreference.com/w/cpp/language/sizeof

Notes

sizeof() ne peut pas être utilisé avec les types de fonction , les types incomplets ou les valeurs gl de champ binaire.

Puisque void() est un type de fonction, ce n'est donc pas un type valide de sizeof()

Remarque:

void() est une fonction qui ne prend aucun argument et ne renvoie rien

Citant un exemple de documents:

//<< "size of function: " << sizeof(void()) << '\n'  // error

Alors réponses à vos questions:

1) Non, ce n'est pas une expression légale.

2) Il affichera 1, mais affichera un avertissement

3) identique à 1).

1
ColdFire