Erros, bugs, perguntas - página 1034

 
TheXpert:
De facto, faz sentido, porque o que está escrito parece um pouco ilusório.
C++ não pensa assim. E quanto aos disparates, este é um exemplo tão simplificado quanto possível para fazer passar o ponto de vista.
 
A100:
C++ não considera assim.

Sim, C++ não conta muitas coisas, mas a questão é que a inicialização dos membros estáticos não está provavelmente na ordem em que são inicializados, mas na ordem em que são declarados.

Vou ter de ler a norma sobre este assunto.

Документация по MQL5: Основы языка / Объектно-ориентированное программирование / Статические члены класса
Документация по MQL5: Основы языка / Объектно-ориентированное программирование / Статические члены класса
  • www.mql5.com
Основы языка / Объектно-ориентированное программирование / Статические члены класса - Документация по MQL5
 

Tornei tudo demasiado fácil - não me movi de forma constante - como podem ver agora tudo está claro - uma constante é inicializada por outra:

class A {
protected: //если заменить на public: то все работает
        static const int s1;
        static const int s2;
};

const int A::s1 = 0x1;
const int A::s2 = A::s1; //ошибка компиляции

O compilador indica como um erro que o membro s1 está protegido. Se substituirmos protegido por público, tudo funciona como um relógio. Mas estar protegido não tem nada a ver com a ordem de inicialização ou ordem de atribuição, nem com a possibilidade de inicialização com um valor particular

 
TheXpert:

Vou ter de ler o padrão sobre isto.

Concordo, em geral, o compilador não é o mesmo que o compilador e é preciso ordená-lo.

Aqui está outro exemplo

enum _ENUM { en = 0x1 };
const int cc = 0x2;
static int s_array1[] = { cc }; //ошибка
static int s_array2[] = { en }; //нормально

class A {
public:
        static const int s;
        static int Array[];
};
const int A::s = 0x3;
int A::Array[] = {
        en,     //нормально
        A::s,   //ошибка
        cc      //ошибка
};

O compilador MQL aqui não quer inicializar o array com o valor const int (enumera - passa)

Mais uma vez, apelo ao facto de C++ o copiar e inicializar correctamente.

Документация по MQL5: Операции с массивами / ArrayInitialize
Документация по MQL5: Операции с массивами / ArrayInitialize
  • www.mql5.com
Операции с массивами / ArrayInitialize - Документация по MQL5
 
Provavelmente um erro na sequência de chamada
class A {
public:
        A *operator<<( int x ) { Print( x ); return ( GetPointer( this )); }
        A *operator<<( string s ) { Print( s ); return ( GetPointer( this )); }
};

int f( int& x ) { return ( x = 4 ); }

void OnStart()
{
        Print( "" );
        A a;
        int x = 3;
        a << "(1)" <<  "(2)" << "(3)"; // Результат: (1) (2) (3) //нормально
        a <<  x   << f( x ) <<  x;   // Результат:  4   4   3 ??? как же так?
}
No último caso estava à espera do resultado: 3 4 4 semelhante ao anterior. Não é normal que alguns tipos tenham uma sequência de chamadas e outros tenham uma sequência diferente.
 
A100:
Provavelmente um erro na sequência de chamada
Em C++, a ordem em que os operandos de uma expressão são avaliados é UB. Porque é que está a confiar numa encomenda específica aqui?
 
TheXpert:
Em C++, a ordem de avaliação dos operandos de uma expressão é UB. Porque é que está a confiar numa encomenda específica aqui?
Alguma vez viu em algum lugar que
 cout << "Hello " << "word";

foi produzido como "palavra Olá" ?

Isto é o que acontece neste caso para um operador sobrecarregado para o tipo int, enquanto que para o tipo string tudo é produzido normalmente.

Além disso, não tem nada a ver com C++. Suponha que escreveu no seu código

f(); // a << x;
g(); // a << f( x );
h(); // a << x;
E tem estas funções executadas em ordem inversa ou de todo para diferentes tipos de argumentos - em qualquer ordem
 
A propósito - a sequência de operações de turno da esquerda para a direita é também definida na própria MQL5, como o exemplo confirma:
void OnStart()
{
        int a = 0x1;
        int b = a << 2 << a;   //b = 8
        int c = (a << 2) << a; //c = 8
        int d = a << (2 << a); //d = 16
        Print ( "b=", b, ", c=", c, ", d=", d );
}
 

Saudações!

Ajude-me a corrigir o 'acesso ao ponteiro inválido'.

No OnInit() temos:

SymbolsCollection = new CSymbolsCollection();
SymbolsCollection.RefreshRealSymbols();

CSymbolsCollection::RefreshRealSymbols() tem um métodoCleanSymbolsArray(myRealSymbols) call;

Este método e variável são declarados na classe como:

public:
   CSymbol* myRealSymbols[];
   void CleanSymbolsArray(CSymbol* &inArray[]);

O problema é que oRefreshRealSymbols() executa normalmente se chamado no construtorCSymbolsCollection.

No entanto, chamar SymbolsCollection.RefreshRealSymbols(); em OnInit(); resulta em:

invalid pointer access in 'SymbolsCollection.mqh' (55,22)

O erro aponta para o método CleanSymbolsArray(myRealSymbols); linha no corpo do CSymbolsCollection::RefreshRealSymbols(), a posição é logo após o parêntese de abertura.

Alguma ideia?

 
vlad_123:
...

Alguma ideia?

Não é isto?