Skip to content

Commit f1b337e

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 f1b337e

File tree

1 file changed

+31
-29
lines changed

1 file changed

+31
-29
lines changed

src/util/format_number_range.cpp

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -73,82 +73,84 @@ 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())) +
86+
"-'");
8687
}
8788

88-
if(!number.has_value())
89+
if(!last_number_is_set)
8990
{
9091
throw deserialization_exceptiont(
9192
"invalid number range '" + number_range + "'");
9293
}
9394

94-
if(number.has_value() && begin_range.has_value())
95+
if(is_range)
9596
{
96-
if(*begin_range > *number)
97+
unsigned end_range = numbers.back();
98+
numbers.pop_back();
99+
unsigned begin_range = numbers.back();
100+
if(begin_range > end_range)
97101
{
98102
throw deserialization_exceptiont(
99103
"lower bound must not be larger than upper bound '" +
100-
std::to_string(*begin_range) + "-" + std::to_string(*number) + "'");
104+
std::to_string(begin_range) + "-" + std::to_string(end_range) + "'");
101105
}
102-
for(unsigned i = *begin_range; i < *number; ++i)
106+
for(unsigned i = begin_range; i < end_range; ++i)
103107
numbers.push_back(i);
104108
// add upper bound separately to avoid
105109
// 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 = {};
110+
numbers.push_back(end_range);
114111
}
115112
}
116113

117114
std::vector<unsigned> parse_number_range(const std::string &number_range)
118115
{
119-
std::vector<unsigned> numbers;
116+
std::vector<unsigned> numbers(1, 0);
117+
bool last_number_is_set = false;
118+
bool is_range = false;
120119

121-
optionalt<unsigned> begin_range;
122-
optionalt<unsigned> number;
123120
for(char c : number_range)
124121
{
125122
if('0' <= c && c <= '9')
126123
{
127-
if(!number.has_value())
128-
number = 0;
129-
*number = 10 * *number + (c - '0');
124+
numbers.back() *= 10;
125+
numbers.back() += c - '0';
126+
last_number_is_set = true;
130127
}
131128
else if(c == ',')
132129
{
133-
append_numbers_and_reset(number_range, numbers, begin_range, number);
130+
append_numbers(number_range, numbers, last_number_is_set, is_range);
131+
132+
numbers.push_back(0);
133+
last_number_is_set = false;
134+
is_range = false;
134135
}
135136
else if(c == '-')
136137
{
137-
if(!number.has_value())
138+
if(!last_number_is_set)
138139
{
139140
throw deserialization_exceptiont(
140141
"lower bound missing in number range '" + number_range + "'");
141142
}
142-
begin_range = number;
143-
number = {};
143+
numbers.push_back(0);
144+
last_number_is_set = false;
145+
is_range = true;
144146
}
145147
else
146148
{
147149
throw deserialization_exceptiont(
148150
std::string("character '") + c + "' not allowed in number range");
149151
}
150152
}
151-
append_numbers_and_reset(number_range, numbers, begin_range, number);
153+
append_numbers(number_range, numbers, last_number_is_set, is_range);
152154

153155
return numbers;
154156
}

0 commit comments

Comments
 (0)