web-dev-qa-db-fra.com

Obtention d'un tas d'erreurs d'initialisation de croix

J'ai ces extraits de code extraits d'un exemple téléchargé:

bool ChatServer::event(QEvent * event)
{
    if(event->type() == QEvent::User)
    {
        UserEvent * ue = static_cast<UserEvent *>(event);
        switch(ue->userType)
        {
            case CR::ErrorEvent:
            case CR::LogEvent:
            {   
                TraceEvent * te = static_cast<TraceEvent *>(ue);
                if(te->userType == CR::ErrorEvent)
                {
                    error(te->msg);
                }
                else
                {
                    log(te->msg);
                }
            }
                break;
            default:
                return false;
        }
    }
    else
    {
        return QTcpServer::event(event);
    }
    return true;
}

Maintenant, si je compile le programme, j'obtiens ces erreurs:

g++ -c -pipe -O2 -Wall -W -DQT_NO_DEBUG -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/local/share/qt4/mkspecs/freebsd-g++ -I. -I/usr/local/include/qt4/QtCore -I/usr/local/include/qt4/QtNetwork -I/usr/local/include/qt4 -I. -I/usr/local/include/qt4 -I/usr/local/include -o chatserver.o chatserver.cpp
g++ -c -pipe -O2 -Wall -W -DQT_NO_DEBUG -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/local/share/qt4/mkspecs/freebsd-g++ -I. -I/usr/local/include/qt4/QtCore -I/usr/local/include/qt4/QtNetwork -I/usr/local/include/qt4 -I. -I/usr/local/include/qt4 -I/usr/local/include -o clientservice.o clientservice.cpp
clientservice.cpp: In member function 'virtual bool ClientService::event(QEvent*)':
clientservice.cpp:37: error: jump to case label
clientservice.cpp:34: error:   crosses initialization of 'MessageEvent* me'
clientservice.cpp:41: error: jump to case label
clientservice.cpp:38: error:   crosses initialization of 'UserInfoEvent* uie'
clientservice.cpp:34: error:   crosses initialization of 'MessageEvent* me'
clientservice.cpp:44: error: jump to case label
clientservice.cpp:38: error:   crosses initialization of 'UserInfoEvent* uie'
clientservice.cpp:34: error:   crosses initialization of 'MessageEvent* me'
clientservice.cpp:31: warning: enumeration value 'EventTypeBegin' not handled in switch
clientservice.cpp:31: warning: enumeration value 'LogEvent' not handled in switch
clientservice.cpp:31: warning: enumeration value 'ErrorEvent' not handled in switch
clientservice.cpp:31: warning: enumeration value 'ClientConnected' not handled in switch
clientservice.cpp:31: warning: enumeration value 'ClientReg' not handled in switch
clientservice.cpp:31: warning: enumeration value 'ClientDisconnect' not handled in switch
clientservice.cpp:31: warning: enumeration value 'ServerConnected' not handled in switch
clientservice.cpp:31: warning: enumeration value 'ServerDisconnect' not handled in switch
clientservice.cpp:31: warning: enumeration value 'DoConnect' not handled in switch
clientservice.cpp:31: warning: enumeration value 'DoDisconnect' not handled in switch
clientservice.cpp:31: warning: enumeration value 'GotMessage' not handled in switch
clientservice.cpp:31: warning: enumeration value 'GotUserInfo' not handled in switch
clientservice.cpp:31: warning: enumeration value 'SendUserInfo' not handled in switch
clientservice.cpp:31: warning: enumeration value 'GotClientInfo' not handled in switch
clientservice.cpp:31: warning: enumeration value 'SendClientInfo' not handled in switch
clientservice.cpp:31: warning: enumeration value 'EventTypeEnd' not handled in switch
clientservice.cpp: In member function 'void ClientService::readClient()':
clientservice.cpp:63: warning: comparison between signed and unsigned integer expressions
clientservice.cpp:87: error: jump to case label
clientservice.cpp:83: error:   crosses initialization of 'Message* msg'
clientservice.cpp:92: error: jump to case label
clientservice.cpp:88: error:   crosses initialization of 'UserInfo* ui'
clientservice.cpp:83: error:   crosses initialization of 'Message* msg'
clientservice.cpp:97: error: jump to case label
clientservice.cpp:93: error:   crosses initialization of 'ClientInfo* ci'
clientservice.cpp:88: error:   crosses initialization of 'UserInfo* ui'
clientservice.cpp:83: error:   crosses initialization of 'Message* msg'
clientservice.cpp: In member function 'bool ClientService::sendToClient(CR::MsgType::MsgType, SendAble*)':
clientservice.cpp:124: warning: comparison of unsigned expression < 0 is always false
clientservice.cpp: In member function 'void ClientService::gotUserInfo(UserInfo*)':
clientservice.cpp:176: error: cast from 'ClientService*' to 'quint32' loses precision
*** Error code 1

Stop in ~/SimpleChatRoomServer

Maintenant, si les crochets de case statment sont supprimés, j'obtiens cette erreur:

g++ -c -pipe -O2 -Wall -W -DQT_NO_DEBUG -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/local/share/qt4/mkspecs/freebsd-g++ -I. -I/usr/local/include/qt4/QtCore -I/usr/local/include/qt4/QtNetwork -I/usr/local/include/qt4 -I. -I/usr/local/include/qt4 -I/usr/local/include -o chatserver.o chatserver.cpp
chatserver.cpp: In member function 'virtual bool ChatServer::event(QEvent*)':
chatserver.cpp:108: error: jump to case label
chatserver.cpp:98: error:   crosses initialization of 'TraceEvent* te'
chatserver.cpp:94: warning: enumeration value 'EventTypeBegin' not handled in switch
chatserver.cpp:94: warning: enumeration value 'ClientConnected' not handled in switch
chatserver.cpp:94: warning: enumeration value 'ClientReg' not handled in switch
chatserver.cpp:94: warning: enumeration value 'ClientDisconnect' not handled in switch
chatserver.cpp:94: warning: enumeration value 'ServerConnected' not handled in switch
chatserver.cpp:94: warning: enumeration value 'ServerDisconnect' not handled in switch
chatserver.cpp:94: warning: enumeration value 'DoConnect' not handled in switch
chatserver.cpp:94: warning: enumeration value 'DoDisconnect' not handled in switch
chatserver.cpp:94: warning: enumeration value 'GotMessage' not handled in switch
chatserver.cpp:94: warning: enumeration value 'SendMessage' not handled in switch
chatserver.cpp:94: warning: enumeration value 'GotUserInfo' not handled in switch
chatserver.cpp:94: warning: enumeration value 'SendUserInfo' not handled in switch
chatserver.cpp:94: warning: enumeration value 'GotClientInfo' not handled in switch
chatserver.cpp:94: warning: enumeration value 'SendClientInfo' not handled in switch
chatserver.cpp:94: warning: enumeration value 'EventTypeEnd' not handled in switch
*** Error code 1

Stop in ~/SimpleChatRoomServer.

Le code source complet de SimpleChatRoomServer.cpp:

#include <QTextStream>
#include <QDateTime>
#include "traceevent.h"
#include "chatserver.h"
#include "chatcenterthread.h"
#include "clientservicethread.h"
#include "message.h"
#include "server.h"

ChatServer::ChatServer(QObject * parent)
        :QTcpServer(parent)
{
    QFile * inFile = new QFile(this);
    QFile * outFile = new QFile(this);
    QFile * errFile = new QFile(this);
    inFile->open(stdin,QIODevice::ReadOnly);
    outFile->open(stdout,QIODevice::WriteOnly);
    errFile->open(stderr,QIODevice::WriteOnly);
    setIO(inFile,outFile,errFile);

    qobject_cast<Server *>(qApp)->csrId = this;
    csrId = (QObject *)(0+CR::ServerId);
}

ChatServer::~ChatServer()
{
    for(int i = 0; i < ccs.size(); i++)
    {
        ccs.at(i)->deleteLater();
    }
}

void ChatServer::setIO(QFile * inFile,QFile * outFile,QFile * errFile)
{
    in.setDevice(inFile);
    out.setDevice(outFile);
    err.setDevice(errFile);
}

void ChatServer::incomingConnection(int socketId)
{
    ClientServiceThread *cst = new ClientServiceThread(socketId,this);
    cst->start();
    connect(cst,SIGNAL(finished()),cst,SLOT(deleteLater()));
}

bool ChatServer::init(quint16 & port)
{
    if(!port)
    {
        bool ok = false;
        while(!ok)
        {
            out<<tr("Port[5555]: ");
            out.flush();
            QString p;
            p = in.read(1);
            if(p!=QString("\n"))
            {
                QString strport;
                strport = in.readLine(10);
                strport = p + strport;
                port = strport.toUInt(&ok);
            }
            else
            {
                port = 5555;
                ok = true;
            }
        }
    }

    //ADD ONE ChatCenter
    ChatCenterThread * cct = new ChatCenterThread(this);
    cct->start();
    connect(cct,SIGNAL(finished()),cct,SLOT(deleteLater()));

    if(!listen(QHostAddress::Any,port))
    {
        error(tr("Listen at [%1] fail!").arg(port));
        deleteLater();
        exit(1);
        return false;
    }
    log(tr("Listen at [%1]").arg(port));
    return true;
}

bool ChatServer::event(QEvent * event)
{
    if(event->type() == QEvent::User)
    {
        UserEvent * ue = static_cast<UserEvent *>(event);
        switch(ue->userType)
        {
            case CR::ErrorEvent:
            case CR::LogEvent:
                TraceEvent * te = static_cast<TraceEvent *>(ue);
                if(te->userType == CR::ErrorEvent)
                {
                    error(te->msg);
                }
                else
                {
                    log(te->msg);
                }
                break;
            default:
                return false;
        }
    }
    else
    {
        return QTcpServer::event(event);
    }
    return true;
}

void ChatServer::error(QString msg)
{
    err<<QDateTime::currentDateTime().toString(Qt::ISODate)
            <<" !ERROR! "<<msg<<endl;
}

void ChatServer::log(QString msg)
{
    out<<QDateTime::currentDateTime().toString(Qt::ISODate)
            <<" "<<msg<<endl;
}

1) Est-ce que j'utilise mal les supports?

2) Pourquoi utiliser des crochets dans l'instruction case montre crosses initialization vers d'autres lignes de code.

45
SIFE

La norme C++ dit:

Il est possible de transférer dans un bloc, mais pas d'une manière qui contourne les déclarations avec l'initialisation. Un programme qui passe d'un point où une variable locale avec une durée de stockage automatique n'est pas dans la portée à un point où elle est dans la portée est mal formé, sauf si la variable a le type POD (3.9) et est déclarée sans initialiseur.

Les cas dans switch sont considérés comme un "saut".

Mettez simplement tous les objets et les initialisations de variables avant votre changement, et tout ira bien.

Considérez ce code:

switch(k)
{
    case 1:
        int t = 4;
    break;
    default:
    break;
}

Cela provoquera une erreur "d'initialisation croisée", car il est possible d'ignorer l'initialisation de t, mais après cela, il restera être dans la portée, même s'il n'a jamais été créé en premier lieu.

Considérez maintenant ceci:

switch(k)
{
    case 1:
    {
        int t = 4;
    }
    break;
    default:
    break;
}

Ici, vous aurez pas l'erreur, car la variable est à l'intérieur d'un bloc et mourra à la fin du bloc (à la fermeture {), donc après cela, pas sera de toute façon dans la portée.

Pour corriger le premier cas, il vous suffit de faire:

int t = 0;
switch(k)
{
    case 1:
        t = 4;
    break;
    default:
    break;
}
101
SingerOfTheFall

Suis en train de porter du vieux code de C vers C++, avec beaucoup de goto (vers des sorties d'erreur). Ce problème se pose également en dehors des instructions switch.

Ma solution simple pour gcc/g ++ (testé avec arm-linux-androideabi-gcc v4.6):

Si tu as

goto err_exit;
int a = 1;

il se plaint.

Ajoutez -fpermissive à votre ligne de commande et remplacez:

goto err_exit;
int a;
a = 1;

aucune plainte.

6
st68