Peut std :: vector utiliser une petite optimisation de tampon?

Je me demandais avec mon collègue si std :: vector peut être implémenté pour utiliser une petite optimisation de tampon. En consultant le brouillon C ++ 11, j’ai lu au 23.3.1p8

L’expression a.swap (b), pour les conteneurs a et b d’un type de conteneur standard autre que array, doit échanger les valeurs de a et b sans invoquer d’opérations de déplacement, de copie ou d’échange sur les éléments de conteneur individuels.

Cela semble au premier abord proscrire l’optimisation des petits tampons, mais sous la règle des «si», nous serions autorisés à effectuer une petite optimisation des tampons pour les types non-classes (car nous ne pouvons pas observer la copie en cours). Le prochain texte semble être plus difficile à “tromper”

Chaque iterator faisant référence à un élément dans un conteneur avant le swap fera référence au même élément dans l’autre conteneur après le swap.

Est-ce suffisant pour empêcher l’implémentation de la petite optimisation de tampon pour std :: vector? Y a-t-il d’autres barrages routiers ou est-il possible d’avoir un std :: vector avec SBO?

23.2.1 / p10 / b6:

Sauf indication contraire …

  • Aucune fonction swap () n’invalide les références, les pointeurs ou les iterators faisant référence aux éléments des conteneurs échangés. …

Nulle part il ne “spécifie autrement” pour le vector . Donc, cela interdit le SBO pour le vector .

ssortingng n’est pas lié par cette règle car il “spécifie autrement” dans 21.4.1 / p6:

Les références, les pointeurs et les iterators faisant référence aux éléments d’une séquence basic_ssortingng peuvent être invalidés par les utilisations suivantes de cet object basic_ssortingng:

  • comme argument de toute fonction de bibliothèque standard, en prenant comme référence un non-const basic_ssortingng.

234) Par exemple, comme argument pour les fonctions non membres swap () (21.4.8.8), operator >> () (21.4.8.9) et getline () (21.4.8.9), ou comme argument de basic_ssortingng: :échanger()

Outre le problème de l’invalidation de l’iterator, il existe un argument de sécurité pour éviter l’optimisation du petit tampon.

Si les écritures dépassent un std::vector , vous obtenez une corruption de tas, ce qui est assez difficile à prédire ce qui est écrasé et très difficile à exploiter pour l’exécution de code arbitraire.

Si le tampon est plutôt incorporé dans une variable locale, un dépassement écrase la stack et l’attaquant prendra probablement le contrôle de l’adresse de retour, ce qui est beaucoup plus utile (attaques de retour à la libc, par exemple).