Skip to content

Commit 79a1dc9

Browse files
committed
Refactor parse_number_range to avoid spurious uninitialized warning
g++-7 -O3 spuriously warned that begin_range was accessed without being initialized: ``` ../src/util/format_number_range.cpp:102:5: error: ‘*((void*)& begin_range +4)’ may be used uninitialized in this function [-Werror=maybe-uninitialized] for(unsigned i = *begin_range; i < *number; ++i) ^~~ ../src/util/format_number_range.cpp:121:23: note: ‘*((void*)& begin_range +4)’ was declared here optionalt<unsigned> begin_range; ^~~~~~~~~~~ cc1plus: all warnings being treated as errors ``` Although optionalt may seem a bit more beautiful, it's perfectly possible to implement parse_number_range without any use of optionalt.
1 parent c7b4d21 commit 79a1dc9

File tree

1 file changed

+30
-29
lines changed

1 file changed

+30
-29
lines changed

src/util/format_number_range.cpp

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -73,82 +73,83 @@ std::string format_number_range(const std::vector<unsigned> &input_numbers)
7373
}
7474

7575
/// Appends \p number resp. numbers \p begin_range ... \p number to \p numbers
76-
static void append_numbers_and_reset(
76+
static void append_numbers(
7777
const std::string &number_range,
7878
std::vector<unsigned> &numbers,
79-
optionalt<unsigned> &begin_range,
80-
optionalt<unsigned> &number)
79+
bool last_number_is_set,
80+
bool is_range)
8181
{
82-
if(!number.has_value() && begin_range.has_value())
82+
if(!last_number_is_set && is_range)
8383
{
8484
throw deserialization_exceptiont(
85-
"unterminated number range '" + std::to_string(*begin_range) + "-'");
85+
"unterminated number range '" + std::to_string(*(++numbers.rbegin())) + "-'");
8686
}
8787

88-
if(!number.has_value())
88+
if(!last_number_is_set)
8989
{
9090
throw deserialization_exceptiont(
9191
"invalid number range '" + number_range + "'");
9292
}
9393

94-
if(number.has_value() && begin_range.has_value())
94+
if(is_range)
9595
{
96-
if(*begin_range > *number)
96+
unsigned end_range = numbers.back();
97+
numbers.pop_back();
98+
unsigned begin_range = numbers.back();
99+
if(begin_range > end_range)
97100
{
98101
throw deserialization_exceptiont(
99102
"lower bound must not be larger than upper bound '" +
100-
std::to_string(*begin_range) + "-" + std::to_string(*number) + "'");
103+
std::to_string(begin_range) + "-" + std::to_string(end_range) + "'");
101104
}
102-
for(unsigned i = *begin_range; i < *number; ++i)
105+
for(unsigned i = begin_range; i < end_range; ++i)
103106
numbers.push_back(i);
104107
// add upper bound separately to avoid
105108
// potential overflow issues in the loop above
106-
numbers.push_back(*number);
107-
begin_range = {};
108-
number = {};
109-
}
110-
else if(number.has_value() && !begin_range.has_value())
111-
{
112-
numbers.push_back(*number);
113-
number = {};
109+
numbers.push_back(end_range);
114110
}
115111
}
116112

117113
std::vector<unsigned> parse_number_range(const std::string &number_range)
118114
{
119-
std::vector<unsigned> numbers;
115+
std::vector<unsigned> numbers(1, 0);
116+
bool last_number_is_set = false;
117+
bool is_range = false;
120118

121-
optionalt<unsigned> begin_range;
122-
optionalt<unsigned> number;
123119
for(char c : number_range)
124120
{
125121
if('0' <= c && c <= '9')
126122
{
127-
if(!number.has_value())
128-
number = 0;
129-
*number = 10 * *number + (c - '0');
123+
numbers.back() *= 10;
124+
numbers.back() += c - '0';
125+
last_number_is_set = true;
130126
}
131127
else if(c == ',')
132128
{
133-
append_numbers_and_reset(number_range, numbers, begin_range, number);
129+
append_numbers(number_range, numbers, last_number_is_set, is_range);
130+
131+
numbers.push_back(0);
132+
last_number_is_set = false;
133+
is_range = false;
134134
}
135135
else if(c == '-')
136136
{
137-
if(!number.has_value())
137+
if(!last_number_is_set)
138138
{
139139
throw deserialization_exceptiont(
140140
"lower bound missing in number range '" + number_range + "'");
141141
}
142-
begin_range = number;
143-
number = {};
142+
numbers.push_back(0);
143+
last_number_is_set = false;
144+
is_range = true;
144145
}
145146
else
146147
{
147148
throw deserialization_exceptiont(
148149
std::string("character '") + c + "' not allowed in number range");
149150
}
150151
}
151-
append_numbers_and_reset(number_range, numbers, begin_range, number);
152+
append_numbers(number_range, numbers, last_number_is_set, is_range);
152153

153154
return numbers;
154155
}

0 commit comments

Comments
 (0)