Γιατί η τόνωση :: προαιρετικά να αποτύχει για τις κατηγορίες που κληρονομούν εικονικές λειτουργίες

ψήφοι
5

ενισχύσει :: προαιρετικό <> λειτουργεί τέλεια για απλούς τύπους δεδομένων, αλλά μόλις χρησιμοποιηθεί για μια κλάση κληρονομεί από μια τάξη εφαρμογή μιας διεπαφής αποτυγχάνει όταν είναι ενεργοποιημένη η αυστηρή aliasing.

Παράδειγμα:

#include <boost/optional.hpp>

struct MyLine{
  double a;
  double b;
};

class Edge{
  public:
    MyLine toMyLine() const;
  private:
    virtual MyLine doToMyLine() const =0;
};

class Wall:public Edge {
  public:
    Wall(MyLine const& seg):mMyLine(seg){};
  private:
    MyLine doToMyLine() const{return MyLine();};
    MyLine mMyLine;
};

class SimpleWall {
  public:
    SimpleWall(MyLine const& seg):mMyLine(seg){};
  private:
    MyLine mMyLine;
};

int main(){
 //boost::optional<Wall> res;       //fails with strict aliasing error
 boost::optional<SimpleWall> res2; //compiles just fine
}

Καταρτίζονται με τα ακόλουθα χρήση gcc έκδοση 4.4.3 αυτό είναι λάθος:

g++ -c -pipe -Wall -Wextra -Wunused -Wmissing-declarations -Wpointer-arith -Wcast-align -Wwrite-strings -Wredundant-decls -Werror -std=c++0x -O2 -Wall -W -I/usr/local/boost_1_44_0 -o obj/main.o main.cpp

Ποιος είναι ο καλύτερος τρόπος για να λυθεί αυτό το πρόβλημα. Θα ήθελα πάρα πολύ να αφήσει την αυστηρή-aliasing προειδοποίηση enabled.I'm χρησιμοποιώντας ώθηση έκδοση 1.44.

ΕΚΣΥΓΧΡΟΝΙΖΩ:

Η κατάσταση χειροτερεύει !! Ας εξετάσουμε το ακόλουθο κώδικα:

#include <boost/optional.hpp>

class MyBase{
  public:
    int toFoo() const;
  private:
    virtual int doToFoo() const =0;
};

class Child:public MyBase {
  public:
    Child(int const& foo):mFoo(foo){};
  private:
    int  doToFoo() const{return 0;}
    int mFoo;
};

int main(){
 boost::optional<int> optint;       //comment out for surprise
 optint.get();                      //comment out for surprise
 boost::optional<Child> res2;
 res2.get();
}

Καταρτίζονται με την ακόλουθη χρησιμοποιείτε την έκδοση του gcc 4.4.3 αυτό συγκεντρώνει:

g++ -c -pipe -Wall -Wextra -Wunused -Wmissing-declarations -Wpointer-arith -Wcast-align -Wwrite-strings -Wredundant-decls -Werror -std=c++0x -O2 -Wall -W -I/usr/local/boost_1_44_0 -o obj/main.o main.cpp

Αν οι γραμμές που σημειώνονται με «// σχόλιο για έκπληξη» σχολιάζονται έξω, να πάρω μια αυστηρή προειδοποίηση aliasing. Έχω ελέγξει αυτό τουλάχιστον 20 φορές. Αυτό είναι ένα από τα πιο περίεργα πράγματα που είδα ποτέ. Μοιάζει με ώθηση :: προαιρετικό αρχικοποιεί sth. ανεξάρτητα από την παράμετρο προτύπου ή όπως gcc για να καταλάβουμε ώθηση :: προαιρετική μόνο αν ονομάζεται με sth. ασήμαντο πρώτη. Καμιά ιδέα ?

Δημοσιεύθηκε 22/06/2011 στις 01:40
πηγή χρήστη
Σε άλλες γλώσσες...                            


1 απαντήσεις

ψήφοι
4

Προσπάθησα αυτό το πρόγραμμα σε Boost 1.44.0. Το πρόβλημα αυτό το λόγο δεν μπορώ να παρακάμψετε doToSegment.

Segment doToSegment(){};

Θα πρέπει να προσθέσετε const:

Segment doToSegment() const {};
Απαντήθηκε 22/06/2011 στις 03:18
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more