Opened 4 years ago

Closed 4 years ago

#884 closed ожидаются исправления (задача сдана)

WW_14

Reported by: Jura Khudyakov Owned by: Sokolov Viacheslav
Component: WW_array Version: 1.0
Keywords: Cc:

Description

В силу тестов компилируется только под C++20

Change History (9)

comment:1 Changed 4 years ago by Sokolov Viacheslav

╰─>$ make
g++ --std=c++2a -Wall -Wextra -Werror -Wshadow -Ofast -Iinclude -MMD -c src/main.cpp -o obj/main.o
In file included from include/my_array.h:90,

from src/main.cpp:1:

include/my_array_bool.h:70:11: error: declaration of ‘constexpr lab_13::my_array<bool, N>::my_array(const std::initializer_list<bool>&) noexcept’ has a different exception specifier

70 | constexpr my_array<bool, N>::my_array(const std::initializer_list<bool>& lst) noexcept

|

In file included from include/my_array.h:90,

from src/main.cpp:1:

include/my_array_bool.h:24:15: note: from previous declaration ‘constexpr lab_13::my_array<bool, N>::my_array(const std::initializer_list<bool>&)’

24 | constexpr my_array(const std::initializer_list<bool>&);

| ~

src/main.cpp: In function ‘constexpr void test_sizeof_constexpr(T, T, T) [with T = bool]’:
src/main.cpp:8:54: error: call to non-‘constexpr’ function ‘std::basic_ostream<_CharT, _Traits>::ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::ostream_type&)) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::ostream_type = std::basic_ostream<char>]’

8 | std::cerr << "Check failed: " << (x) << std::endl; \

| ~

src/main.cpp:118:9: note: in expansion of macro ‘ERR’

118 | ERR("sizeof(ar1) != 8");

|

src/main.cpp: In function ‘constexpr void test_sizeof_constexpr_const(T, T, T) [with T = bool]’:
src/main.cpp:8:54: error: call to non-‘constexpr’ function ‘std::basic_ostream<_CharT, _Traits>::ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::ostream_type&)) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::ostream_type = std::basic_ostream<char>]’

8 | std::cerr << "Check failed: " << (x) << std::endl; \

| ~

src/main.cpp:160:9: note: in expansion of macro ‘ERR’

160 | ERR("sizeof(ar1) != 8");

|

Makefile:62: recipe for target 'obj/main.o' failed
make: * [obj/main.o] Error 1

comment:2 Changed 4 years ago by Sokolov Viacheslav

Type: ожидается проверкаожидаются исправления

comment:3 Changed 4 years ago by Jura Khudyakov

Type: ожидаются исправленияожидается проверка
Version: 1.02.0

Да, плохая была идея всё это под 20-ыми плюсами собирать. За время, пока лежал тикет, g++ обновилось и оно перестало компилиться, в том числе и у меня :)
Так что я убрал constexpr-тестирование и теперь оно компилится и под 17-ыми плюсами.
В 20 это не получалось сделать, так как вывод в cerr был не constexpr. Я попробовал ещё пару вещей, но они пока на стадии разработки (вроде constexpr вектора), так что у меня не получилось.

comment:4 Changed 4 years ago by Sokolov Viacheslav

g++ --std=c++17 -Wall -Wextra -Werror -Wshadow -Ofast -Iinclude -MMD -c src/main.cpp -o obj/main.o
In file included from include/my_array_bool.h:4,

from include/my_array.h:90,
from src/main.cpp:1:

include/bin_operations.h: In function ‘void test_constexpr_const(T, T, T) [with T = bool]’:
include/bin_operations.h:24:10: error: ‘ar2.lab_13::my_array<bool, 2>::data_[0]’ is used uninitialized in this function [-Werror=uninitialized]

24 | data &= ~(1 << pos);

| ~~

src/main.cpp:441:26: note: ‘ar2.lab_13::my_array<bool, 2>::data_[0]’ was declared here

441 | const my_array<T, 2> ar2 { t1, t2 };

|

In file included from include/my_array_bool.h:4,

from include/my_array.h:90,
from src/main.cpp:1:

include/bin_operations.h:24:10: error: ‘ar3.lab_13::my_array<bool, 3>::data_[0]’ is used uninitialized in this function [-Werror=uninitialized]

24 | data &= ~(1 << pos);

| ~~

src/main.cpp:442:26: note: ‘ar3.lab_13::my_array<bool, 3>::data_[0]’ was declared here

442 | const my_array<T, 3> ar3 { t1, t2, t3 };

|

In file included from include/my_array_bool.h:4,

from include/my_array.h:90,
from src/main.cpp:1:

include/bin_operations.h:24:10: error: ‘ar1.lab_13::my_array<bool, 1>::data_[0]’ may be used uninitialized in this function [-Werror=maybe-uninitialized]

24 | data &= ~(1 << pos);

| ~~

src/main.cpp:440:26: note: ‘ar1.lab_13::my_array<bool, 1>::data_[0]’ was declared here

440 | const my_array<T, 1> ar1 { t1 };

|

In file included from include/my_array_bool.h:4,

from include/my_array.h:90,
from src/main.cpp:1:

include/bin_operations.h: In function ‘void test_constexpr(T, T, T) [with T = bool]’:
include/bin_operations.h:24:10: error: ‘ar1.lab_13::my_array<bool, 1>::data_[0]’ is used uninitialized in this function [-Werror=uninitialized]

24 | data &= ~(1 << pos);

| ~~

include/bin_operations.h:24:10: error: ‘ar10.lab_13::my_array<bool, 10>::data_[0]’ is used uninitialized in this function [-Werror=uninitialized]

24 | data &= ~(1 << pos);

| ~~

include/bin_operations.h:24:10: error: ‘ar10.lab_13::my_array<bool, 10>::data_[1]’ is used uninitialized in this function [-Werror=uninitialized]
cc1plus: all warnings being treated as errors
Makefile:62: recipe for target 'obj/main.o' failed
make: * [obj/main.o] Error 1

comment:5 Changed 4 years ago by Sokolov Viacheslav

Version: 2.01.0

comment:6 Changed 4 years ago by Sokolov Viacheslav

Type: ожидается проверкаожидаются исправления

comment:7 Changed 4 years ago by Jura Khudyakov

Type: ожидаются исправленияожидается проверка

Разобрался с ошибками. Надеюсь, окончательно.
Вышло довольно интересно: если добавить -Ofast (или другую степень оптимизации, кроме -O0), добавляются новые Warningи, а с ними и ошибки компиляции. Те ошибки, которые были в последний раз - переменная использовалась неинициализированной внутри функции, передаваясь туда по ссылке. Без оптимизации компилятор видимо не заглядывал так глубоко и не искал такие случаи, а с оптимизацией искал. В итоге обычный make не собирался, так как собирает make release с -Ofast, а все другие вызывают сборку debug, которая не добавляет оптимизаций.
Ещё интересно то, что -fsanitize=address также прячет ошибки, хоть даже с -Ofast.
Ещё я наконец-то поставил себе версию gcc от JonathonF, надеюсь, соответствующую актуальной у вас. gcc -dumpspecs совпадает. Ну правда я поставил gcc 7.5.0, а не 7.4.0, dumpspecs которой вы тогда скидывали.

А по сути ошибки - в array<bool> ставились биты неинициализированного int-а, и компилятор на это ругался. Теперь они по умолчанию заполняются нулями.

comment:8 Changed 4 years ago by Sokolov Viacheslav

Type: ожидается проверкаожидаются исправления

15 inline constexpr bool get(const uint8_t& data, size_t pos)

constexpr implies inline
ссылка занимает больше, чем uint8_t

24 data &= ~(1 << pos);
25 data |= (val << pos);

здесь стоило бы вести работу с беззнаковыми типами, потому что знаковые и беззнаковые битовые операции могут работать по-разному. Кроме того, лучше минимизировать количество implicit преобразований, в данном случае - integer promotion можно было бы избежать при помощи явного static_cast

методам стоит дописать noexcept

17 constexpr T& operator[](std::size_t index);
18 constexpr const T& operator[](std::size_t index) const;

noexcept?

10 struct my_array {
final?

44 if (!(index < N))
45 throw std::out_of_range("index out of range");

стоит вынести в отдельную функцию (дублируется), поскольку еще неплохо бы расширить сообщение об ошибке дополнительной информацией - по какому индексу происходило обращение

в operator[] все же стоит добавить assert, что обращение происхоидт по валидному индексу

72 return !N;

понятнее N > 0;

15 constexpr my_bool_proxy& operator=(const my_bool_proxy&) noexcept;
с rvalue версией тоже хорошо бы что-нибудь сделать

22 using T = my_bool_proxy;

лучше как и в стандартной библиотеке - именовать навроде reference. T плохое имя.

126 if (val)
127 for (size_t i = 0; i < bin_operations::divCeil8(N); ++i)
128 data_[i] = 0b11111111;
129 else
130 for (size_t i = 0; i < bin_operations::divCeil8(N); ++i)
131 data_[i] = 0b00000000;
132 }
можно эффективнее с помощью memset

80 fill(0);

false?

70 constexpr my_array<bool, N>::my_array(const std::initializer_list<bool>& lst)
noexcept?
хорошо бы проверить, что размер lst совпадает с N

41 template <std::size_t N>
42 constexpr my_array<bool, N>::my_bool_proxy::my_bool_proxy(uint8_t& data_fragment, size_t pos) noexcept
43 : data_fragment_ { data_fragment }
44 , pos_ { pos }
45
46 {
47 }

форматирование; assert(pos < 8)

comment:9 Changed 4 years ago by Sokolov Viacheslav

Resolution: задача сдана
Status: assignedclosed
Note: See TracTickets for help on using tickets.