Я получаю 3 ошибки C4703 по переменным. Я думаю, что я правильно инициализировал, и я не уверен, что мне не хватает - PullRequest
0 голосов
/ 12 мая 2019

Я пишу проект для класса, и мне нужно, чтобы моя программа считала арифметические выражения из входного файла и оценила их. К сожалению, всякий раз, когда я пытаюсь реализовать мой заголовок ternaryCondition.h, моя отладка выдает три

subexpression.cpp (75): ошибка C4703: потенциально неинициализированная переменная локального указателя 'первая' использованная

subexpression.cpp (75): ошибка C4703: потенциально неинициализированная переменная локального указателя 'second' используется

subexpression.cpp (75): ошибка C4703: потенциально неинициализированная переменная локального указателя «третья» используется

Это мой второй опыт работы с C ++, поэтому я чувствую, что просто что-то упустил полностью.

Я пытался отключить проверки / sdl, но когда я это сделал, я обнаружил, что моя программа больше не может читать построчно через мой входной файл и оценивать выражения.

Это файл subexpressions.cpp, который выбрасывает ошибку до 75-й строки, где происходит ошибка:

#include <iostream>

using namespace std;

#include "expression.h"
#include "subexpression.h"
#include "operand.h"
#include "plus.h"
#include "minus.h"
#include "times.h"
#include "divide.h"
#include "greaterThan.h"
#include "lessThan.h"
#include "equal.h"
#include "and.h"
#include "or.h"
#include "negation.h"
#include "ternaryCondition.h"


#include <sstream>


SubExpression::SubExpression(Expression* left, Expression* right)

{

    this->left = left;
    this->right = right;

}

SubExpression::SubExpression(Expression* first, Expression* second, Expression* third)
{
    this->first = first;
    this->second = second;
    this->third = third;
}

SubExpression::SubExpression(Expression* left)
{
    this->left = left;
}

Expression* SubExpression::parse(stringstream& in)

{
    Expression* left;
    Expression* right;
    Expression* first;
    Expression* second;
    Expression* third;
    char operation, paren;
    bool isTernary = false;

    left = Operand::parse(in);
    cin >> operation;
    right = Operand::parse(in);
    if (operation == ':')
    {
        first = left;
        second = right;
        left = Operand::parse(in);
        cin >> operation;
        right = Operand::parse(in);
        if (operation == '?')
        {
            third = right;
            isTernary = true;
        }
    }
    cin >> paren;
    if (isTernary == true)
    {
        return new TernaryCondition(first, second, third); 
//THE LINE ABOVE IS LINE 75 WHERE THE ERROR IS BEING THROWN
    }
    switch (operation)
    {

И это заголовок ternaryCondition.h на случай, если это может вызвать проблемы:

class TernaryCondition : public SubExpression
{
public:
    TernaryCondition(Expression* first, Expression* second, Expression* third) :
        SubExpression(first, second, third)
    {
    }
    int evaluate()
    {
        return third->evaluate() ? first->evaluate() : second->evaluate(); 
    }
};

Смысл этой части моего кода в том, что программа может вычислять выражения вроде

(((z <(50 + aa)) & (bb!)) * ((3 / cc) | (1: 0? (Z> aa)), z = 4, aa = 2, bb = 4, куб.см = 2;

Извините, если я отправил это в неподходящем формате, это моя первая публикация.

ДОБАВЛЕНО подвыражение.h ФАЙЛ ЖАТКИ:

class SubExpression : public Expression
{
public:
    SubExpression(Expression* left, Expression* right);
    SubExpression(Expression* left);
    SubExpression(Expression* first, Expression* second, Expression* third);
    static Expression* parse(stringstream& in);

protected:
    Expression* left;
    Expression* right;
    Expression* first;
    Expression* second;
    Expression* third;
};

Ответы [ 3 ]

0 голосов
/ 12 мая 2019

Вы должны инициализировать всех членов вашего SubExpression класса, а не переводить их в противоречивое, неинициализированное состояние.

Вот как должна выглядеть инициализация:

class SubExpression : public Expression
{
public:
    SubExpression(Expression* left, Expression* right);
    SubExpression(Expression* left);
    SubExpression(Expression* first, Expression* second, Expression* third);
    static Expression* parse(stringstream& in);

protected:
    Expression* left;
    Expression* right;
    Expression* first;
    Expression* second;
    Expression* third;
};

SubExpression::Subexpression(Expression* left_, Expression* right_) : left(left_), right(right_), first(nullptr), second(nullptr), third(nullptr)
{}

SubExpression::Subexpression(Expression* left_) : left(left_), right(nullptr), first(nullptr), second(nullptr), third(nullptr)
{}

SubExpression::Subexpression(Expression* first_, Expression* second_, Expression* third_) : left(nullptr), right(nullptr), first(first_), second(second_), third(third_)
{}

Во-вторых, из-за того, что указатели не инициализируются, вам будет намного сложнее отлаживать программу, использующую одно из этих неинициализированных значений. Если по крайней мере указатель установлен на nullptr, у вас больше шансов исправить любые ошибки.


Другая потенциальная причина предупреждения - это код в функции parse:

Expression* left;
Expression* right;
Expression* first;
Expression* second;
Expression* third;

В функции parse вы полагаетесь на оператор if(), который будет истинным, чтобы установить указатели выше. Не делайте этого - здесь применимо то же самое, что и к вашим ученикам, - инициализируйте все эти переменные в nullptr.

0 голосов
/ 12 мая 2019

first, second и third являются членами класса и локальными переменными в parse().Первые действительно неинициализированы, если только операция == ':'.При использовании без this-> компилятор выбирает локальные.

Конфликт имен, вот и все.

0 голосов
/ 12 мая 2019

Создание собственных анализаторов похвально.Это поможет вам лучше понять, как работают компиляторы.

Здесь, по-видимому, ваша ошибка вызывается в следующей строке

    return new TernaryCondition(first, second, third);

Во время логической речи, если истерический Значение true, тогда first, second и 3rd должны быть уже инициализированы.Либо компилятор запутывается, либо строка №75 находится где-то еще.Если компилятор запутывается, это происходит потому, что инициализация происходит в условном блоке, поэтому он может никогда не произойти.И тогда после попытки использования переменных, по крайней мере, без проверки логических зависимостей, можно было бы неинициализироваться

...