Maison > développement back-end > C++ > Un compilateur C peut-il optimiser les « nouveaux » appels d'opérateur ?

Un compilateur C peut-il optimiser les « nouveaux » appels d'opérateur ?

DDD
Libérer: 2024-12-02 08:49:09
original
907 Les gens l'ont consulté

Can a C   Compiler Optimize Away `new` Operator Calls?

Un compilateur peut-il optimiser les allocations de mémoire du tas ?

Considérez le code C simple suivant qui alloue de la mémoire à l'aide du nouvel opérateur :

int main()
{
    int* mem = new int[100];
    return 0;
}
Copier après la connexion

Le compilateur peut-il optimiser le nouvel appel, évitant ainsi la mémoire dynamique allocation ?

Comportement du compilateur

Différents compilateurs se comportent différemment dans cette situation. g et Visual Studio 2015 n'optimisent pas le nouvel appel, contrairement à clang, comme observé dans les tests avec les optimisations complètes activées.

Raison d'être de l'optimisation du compilateur

Selon N3664 : Clarifiant l'allocation de mémoire, qui est devenue plus tard une partie de C 14, le compilateur est autorisé à optimiser les allocations de mémoire. Cette optimisation est basée sur l'hypothèse que le nouvel appel n'a pas d'effets secondaires observables.

Règle comme si

Cependant, la règle comme si dans le projet La section 1.9 de la norme C requiert des implémentations conformes pour émuler le comportement observable de la machine abstraite. Lancer une exception à new aurait des effets secondaires observables, on pourrait donc affirmer que le compilateur n'est pas autorisé à optimiser le nouvel appel.

Détails de l'implémentation

On d'un autre côté, on pourrait faire valoir que la décision de savoir quand lever une exception à la nouveauté est un détail de mise en œuvre. Clang pourrait potentiellement déterminer que l'allocation ne provoquerait pas d'exception et donc éluder le nouvel appel sans violer la règle du "comme si".

Allocations sans lancement

Utilisation du la version non lancée de new, new (std::nothrow) int[100], permet toujours à clang d'optimiser l'allocation. En effet, clang peut être en mesure de prouver qu'il n'existe pas d'opérateur de remplacement global new qui pourrait provoquer un comportement observable.

Optimisation agressive

Dans les versions antérieures de clang, même des optimisations plus agressives ont été effectuées, comme le montre ce code :

#include <cstddef>

extern void* operator new(std::size_t n);

template<typename T>
T* create() { return new T(); }

int main() {
    auto result = 0;
    for (auto i = 0; i < 1000000; ++i) {
        result += (create<int>() != nullptr);
    }
    return result;
}
Copier après la connexion

Ce code a été optimisé à :

main:                                   # @main
    movl    00000, %eax          # imm = 0xF4240
    ret
Copier après la connexion

Effectivement, toute la boucle a été optimisée. Les versions ultérieures de clang n'effectuent pas d'optimisations aussi agressives.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal