Переменная ‘pos’ используется без инициализации

#c #c 11

#c #c 11

Вопрос:

У меня ошибка в моем коде. Как я могу с этим справиться?

Не удается успешно скомпилировать, но я не могу найти ничего неправильного.

Day.h

 #pragma once
#include<iostream>
#include<string>
typedef unsigned ud;
using std::string;
class Day
{
public:
    Day() = default;
    Day(string a) {
        decltype(a.size()) pos;
        if (a.find("Jan") != string::npos)
            month = 1;
        else if (a.find("Feb") != string::npos)
            month = 2;
        else if (a.find("Mar") != string::npos)
            month = 3;
        else if (a.find("Apr") != string::npos)
            month = 4;
        else if (a.find("May") != string::npos)
            month = 5;
        else if (a.find("Jun") != string::npos)
            month = 6;
        else if (a.find("Jul") != string::npos)
            month = 7;
        else if (a.find("Aug") != string::npos)
            month = 8;
        else if (a.find("Sep") != string::npos)
            month = 9;
        else if (a.find("Oct") != string::npos)
            month = 10;
        else if (a.find("Nov") != string::npos)
            month = 11;
        else if (a.find("Dec") != string::npos)
            month = 12;
        else {
            pos = a.find_first_not_of("123456789");
            month = stoi(a.substr(0, pos));
        }
        pos  ;
        auto now = a.find_first_not_of("123456789", pos);
        day = stoi(a.substr(pos, now - pos));
        pos = now   1;
        year = stoi(a.substr(pos, a.size() - pos));
    }
    ud get_year() {
        return year;
    }
    ud get_month() {
        return month;
    }
    ud get_day() {
        return day;
    }
    std::ostreamamp; print(std::ostreamamp; os) {
        os << year << ' ' << month << ' ' << day;
        return os;
    }
private:
    ud year;
    ud month;
    ud day;
    bool iszm(char x) {
        return (x >= 'A'amp;amp;x <= 'z');
    }
};
  

main.cpp

 #include"pch.h"
#include<iostream>
#include<forward_list>
#include<deque>
#include<vector>
#include<string>
#include<list>
#include<array>
#include<cstdlib>
#include"Day.h"
using namespace std;
int main()
{
Day tmp("March 27,2019");
    tmp.print(cout);
return 0;
}
  

Комментарии:

1. Сообщение об ошибке довольно четкое. Вы используете pos без предварительной инициализации значения

2. Это не решает вопрос, но x >= 'A'amp;amp;x <= 'z' выглядит странно. Если предполагается, что код распознает букву, используйте std::isalpha . Если ваша система использует ASCII (что почти наверняка так и есть), найдите значение символов ASCII, чтобы увидеть, что на самом деле делает исходное выражение. Если ваша система использует EBCDIC (постоянный дочерний элемент проблемы), 'z' меньше 'A' , и это выражение всегда будет false.

3. @Pete Beckeя понимаю, большое вам спасибо.

Ответ №1:

 ...
else {
  pos = a.find_first_not_of("123456789");
  month = stoi(a.substr(0, pos));
}

pos  ;  //<<<<<<<<<<<<<<

auto now = a.find_first_not_of("123456789", pos);
day = stoi(a.substr(pos, now - pos));
...
  

Как только вы доберетесь до строки, pos ; она pos будет иметь известное значение, только если было выполнено else предложение выше, содержащее pos = a.find_first_not_of("123456789"); , и это происходит, только если a отличается от "Jan" , "Feb" и т.д.

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

Не по теме: этот код действительно уродлив, и может возникнуть больше проблем.

Комментарии:

1. Спасибо за ваш совет, преимущества велики!

2. @Kdlyh это другой вопрос, но обычно, если у вас есть код с повторяющимся шаблоном if s с небольшим количеством изменений, обычно есть способ получше.

3. Поймите, я собираюсь использовать map вместо duplicate if.

4. @Kdlyh да, std::map это одна из возможностей. Не забудьте сделать это static в противном случае карта будет заполняться при каждом вызове конструктора

5. Хорошо, я понимаю. Вы мне очень помогли в моем самообучении!

Ответ №2:

   decltype(a.size()) pos;
    if (a.find("Jan") != string::npos)
        month = 1;
    //    other else if statements removed
    else {
        pos = a.find_first_not_of("123456789");
        month = stoi(a.substr(0, pos));
    }
    pos  ;
  

В приведенном выше примере я удалил целую серию else if инструкций.

pos определена и неинициализирована.

If a.find("Jan") != string::npos then pos никогда не присваивается. Следующая операция pos извлекает значение pos для того, чтобы увеличить его. Поскольку pos она неинициализирована, поведение не определено.

В вашем коде единственное место, где pos присваивается значение в последовательности else if s, находится в final else . Любой другой путь в этом коде приводит к pos неопределенному поведению, поскольку — как предупреждает ваш компилятор — pos неинициализирован.

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

Одним из простых способов убедиться в этом было бы изменить определение на

 decltype(a.size()) pos = 0;
  

Правильно ли это для вашего кода или нет, зависит от того, что вы ожидаете, произойдет во всех случаях, отличных от окончательного else .

Комментарии:

1. Спасибо, в то время я не был серьезен.

2. Ваш ответ очень подробный, но Jabberwocky ответил ранее, поэтому я принял его ответ, пожалуйста, поймите

Ответ №3:

Спасибо.Я решил проблему.

 #pragma once
#include<iostream>
#include<string>
typedef unsigned ud;
using std::string;
class Day
{
public:
    Day() = default;
    Day(string a) {
        decltype(a.size()) pos=0;
        if (a.find("Jan") != string::npos)
            month = 1;
        else if (a.find("Feb") != string::npos)
            month = 2;
        else if (a.find("Mar") != string::npos)
            month = 3;
        else if (a.find("Apr") != string::npos)
            month = 4;
        else if (a.find("May") != string::npos)
            month = 5;
        else if (a.find("Jun") != string::npos)
            month = 6;
        else if (a.find("Jul") != string::npos)
            month = 7;
        else if (a.find("Aug") != string::npos)
            month = 8;
        else if (a.find("Sep") != string::npos)
            month = 9;
        else if (a.find("Oct") != string::npos)
            month = 10;
        else if (a.find("Nov") != string::npos)
            month = 11;
        else if (a.find("Dec") != string::npos)
            month = 12;
        else {
            pos = a.find_first_not_of("123456789");
            month = stoi(a.substr(0, pos));
        }
        pos = pos ? pos : a.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm");
        pos  ;
        auto now = a.find_first_not_of("123456789", pos);
        day = stoi(a.substr(pos, now - pos));
        pos = now   1;
        year = stoi(a.substr(pos, a.size() - pos));
    }
    ud get_year() {
        return year;
    }
    ud get_month() {
        return month;
    }
    ud get_day() {
        return day;
    }
    std::ostreamamp; print(std::ostreamamp; os) {
        os << year << ' ' << month << ' ' << day;
        return os;
    }
private:
    ud year;
    ud month;
    ud day;
};