7
votes

Cette initialisation de const à Const_cast a-t-elle un comportement indéfini?

Selon mes petits tests, ce code fonctionne. Mais, a-t-il un comportement indéfini? Modification de l'objet Const à l'aide de Const_cast a abouti à des violations d'accès à temps d'exécution dans mes tests précédents, mais je ne me souviens pas de la manière dont ils étaient différents. Donc, y a-t-il fondamentalement quelque chose de mal ici ou non? XXX PRE>


// test.cpp
#include "test.h"

const BigLut constBigLut;
BigLut::BigLut()
{
    for(int i = 0; i < 100000; ++i) {
        this->at(i) = i;
    }
}


1 commentaires

Outre le reste, void principal est illégal en C ++. Main Doit Toujours Ayez le type de retour int . Vous pouvez omettre en toute sécurité la déclaration de retour , cependant.


3 Réponses :


6
votes

Vous modifiez un objet défini comme const. Peu importe quand vous le faites, lors de l'initialisation ou non, c'est toujours un comportement indéfini. Suppression de la constance avec const_cast n'est définie que si le pointeur Const a été obtenu à partir d'un pointeur non constitué à cet objet à une étape plus tôt. Ce n'est pas votre cas.

La meilleure chose que vous puissiez faire est xxx

et espérons que le compilateur optimisera le statique temporaire.


0 commentaires

3
votes

Vous avez une mauvaise utilisation de l'opérateur Const_Cast qui est malheureusement possible, et dans ce cas génère un comportement non défini ... Vous pouvez utiliser une initialiseur dynamique pour constbiglu en invoquant son constructeur de copie implicite (en supposant que boost :: Array est le même concept que std :: gray ): xxx

édition: semble que VC ++ 10 applique parfaitement la RVO, donc que le temporaire est directement déplacé dans l'objet de la durée statique. Donc, je n'ai pas besoin de déclarer des statiques locales ou des références aux torporres ...

Editer 2: Ouais, j'ai raté la question de la taille. Recommander en emballage dans un type non trivial avec constructeur comme ci-dessus ...


6 commentaires

L'OP a explicitement dit que "Tailleof (BigLUT_T) est trop pour s'adapter à la pile."


+1 pour l'idée de structure. En fait, vous pouvez le rendre encore meilleur: rendre la structure dérive de BigLUT_T, puis le code utilisant ConstBiglut ne sera pas enregistré.


En fait, je ne ferais pas quelque chose comme ça du tout ... Les objets de durée statique ne devraient être qu'une solution d'urgence absolument exceptionnelle. Formulaire de dérivation std :: Array ferait que même "Hirkier" IMHO, car il violerait clairement le but de l'héritage. Si quelque chose comme ça devient nécessaire, vous aurez probablement une sorte de problème architectural, qui devrait être résolu en premier. Si cela ne fonctionne pas, enveloppez quelque chose comme instance BIGLUT_TINIT dans un Single Singleton, de sorte qu'il ne puisse pas être utilisé plus mal ...


@ Paul_71: Pour que ma demande de travail fonctionne, ces objets GLOBAL CONSTRY doivent toujours exister, donc je ne vois aucune raison de retarder leur initialisation. En outre, la classe de base de ConstBiglut n'est pas conceptuellement de singleton (et pas nécessairement STD :: Array non plus). Ce qui signifie que j'ai besoin de (ailleurs dans le code) construire et détruire des objets des mêmes types que certains de ces objets globaux consons sont. Pouvez-vous me donner une autre raison pour laquelle les objets de la durée statique ne devraient être une solution d'urgence exceptionnelle que, en plus de les considérer comme un problème architectural?


N'est-ce pas assez? :) Non, la statique C ++ a plusieurs problèmes inhérents.


Désolé, ils ne me laisseront pas abandonner le commentaire, alors je commence à partir de zéro ... N'est-ce pas assez? :) Non, il y a plusieurs problèmes inhérents à la statique C ++, comme aucun contrôle (ou mauvais) de leur initialisation et de leur destruction (ordre d'initialisation / destruction, sont-ils initialisés du tout ...). Il existe bien sûr des problèmes de testabilité, multi-threading, introduction de dépendances qui ne sont pas évidentes et ainsi de suite. Mon expérience est que tout programme qui repose sur la statique C ++ est cassé tôt ou tard ...



1
votes

C'est un UB, car ce tableau pouvait être stocké dans ROM.

Vous pouvez le faire: P>

// test.h
#include <boost/array.hpp>

typedef boost::array<int,100000> bigLut_t;
const bigLut_t& Lut();


// test.cpp
#include "test.h"

bool initialized=false;

const bigLut_t& Lut()
{
  static bigLut_t lut;

  if (!initialized)
  {
    for(int i = 0; i < 100000; ++i) {
        lut.at(i) = i;
    }
  }
    return lut;
}


0 commentaires