web-dev-qa-db-fra.com

En C ++ 14, est-il valide d'utiliser un double dans la dimension d'une nouvelle expression?

En C++ 14, à l'aide du code suivant:

void foo() {
  double d = 5.0;
  auto p1 = new int[d];
}

clang le compile sans diagnostic, tandis que gcc produit le diagnostic suivant ( le voir vivre dans le diable ):

error: expression in new-declarator must have integral or enumeration type
    7 |     auto p1 = new int[d];
      |                       ^

J'ai spécifiquement appelé ce C++ 14 car en mode C++ 11, Clang le traite comme étant mal formé et produit le diagnostic suivant ( le voir en direct dans godbolt ):

error: array size expression must have integral or unscoped enumeration type, not 'double'
    auto p1 = new int[d];
              ^       ~

Clang est-il correct? Si c'est le cas, qu'est-ce qui a changé en C++ 14 pour permettre cela?

42
Shafik Yaghmour

Clang est correct, la formulation clé dans [expr.new] p6 est différente de celle ci-dessous dans le brouillon C++ 11:

Chaque expression-constante dans un noptr-new-declarator doit être une expression constante intégrale ([expr.const]) et évaluée à une valeur strictement positive. L'expression dans un noptr-new-declarator doit être de type intégral, de type énumération non découpée ou de type de classe pour lequel une seule fonction de conversion non explicite au type d’énumération intégrale ou non délimitée existe ([class.conv]). Si l'expression est de type classe, elle est convertie en appelant cette fonction de conversion et le résultat de la conversion est utilisé à la place de l'expression d'origine. …

to ceci dans le brouillon C++ 14 :

Chaque expression-constante dans un noptr-new-declarator doit être une expression constante convertie ([expr.const]) de type std::size_t et doit être évalué à une valeur strictement positive. L'expression dans un noptr-new-declarator est implicitement convertie en std::size_t _ . …

En C++ 14, l'exigence relative à l'expression dans un noptr-new-declarator était affaiblie pour ne pas nécessiter d'énumération intégrale non délimitée ni de classe avec une seule fonction de conversion non explicite en un des éléments suivants: ces types, mais autorisent uniquement les conversions implicites vers size_t.

Le changement de formulation provient de la proposition Proposition visant à peaufiner certaines conversions contextuelles C++, v .

44
Shafik Yaghmour

De c ++ 14 à c ++ 17 (pour ceux qui me demandent comme moi), le phrasé reste pratiquement le même (contrairement à C++ 11 à C + +14 comme @ShafikYaghmour a répondu), comme indiqué dans ce brouillon C++ 17 :

Chaque expression-constante dans un noptr-new-declarator doit être une expression constante convertie de type std::size_t et doit être évalué à une valeur strictement positive. L'expression dans un noptr-new-declarator est implicitement convertie en std::size_t _ . [..]

avec seulement cette partie ([expr.const]) absent du brouillon C++ 17.

1
gsamaras