-
Notifications
You must be signed in to change notification settings - Fork 4
Description
tst-template_cpp20_warning.cpp.txt
Building current kanzi with simply make kanzi
on Fedora 42 Linux, i.e. using g++ 15.1.1 and the warning flags -Wall -Wextra
, succeeds but with a lot of warnings.
The warnings are of two kinds:
- -Wtemplate-id-cdtor that is easily fixed in the code and definitely should be
- -Walloc-size that requires a lot more lines to be changed, debatable whether gcc ought to complain about this and whether to adapt to it
-Wtemplate-id-cdtor warnings
Excerpt:
.../kanzi-cpp/src$ date;\time make kanzi;date
søn 20 jul 10:11:45 CEST 2025
g++ -c -std=c++14 -Wall -Wextra -O3 -fomit-frame-pointer -fPIC -DNDEBUG -pedantic -march=native -fno-rtti Global.cpp -o obj/Global.o
g++ -c -std=c++14 -Wall -Wextra -O3 -fomit-frame-pointer -fPIC -DNDEBUG -pedantic -march=native -fno-rtti Event.cpp -o obj/Event.o
g++ -c -std=c++14 -Wall -Wextra -O3 -fomit-frame-pointer -fPIC -DNDEBUG -pedantic -march=native -fno-rtti entropy/EntropyUtils.cpp -o obj/entropy/EntropyUtils.o
g++ -c -std=c++14 -Wall -Wextra -O3 -fomit-frame-pointer -fPIC -DNDEBUG -pedantic -march=native -fno-rtti entropy/HuffmanCommon.cpp -o obj/entropy/HuffmanCommon.o
g++ -c -std=c++14 -Wall -Wextra -O3 -fomit-frame-pointer -fPIC -DNDEBUG -pedantic -march=native -fno-rtti entropy/CMPredictor.cpp -o obj/entropy/CMPredictor.o
g++ -c -std=c++14 -Wall -Wextra -O3 -fomit-frame-pointer -fPIC -DNDEBUG -pedantic -march=native -fno-rtti entropy/TPAQPredictor.cpp -o obj/entropy/TPAQPredictor.o
I fil inkluderet fra entropy/TPAQPredictor.hpp:24,
fra entropy/TPAQPredictor.cpp:16:
entropy/AdaptiveProbMap.hpp:35:35: advarsel: template-id not allowed for constructor in C++20 [-Wtemplate-id-cdtor]
35 | LinearAdaptiveProbMap<RATE>(int n);
| ^
entropy/AdaptiveProbMap.hpp:35:35: bemærk: remove the »< >«
entropy/AdaptiveProbMap.hpp:37:8: advarsel: template-id not allowed for destructor in C++20 [-Wtemplate-id-cdtor]
37 | ~LinearAdaptiveProbMap<RATE>() { delete[] _data; }
| ^
entropy/AdaptiveProbMap.hpp:37:8: bemærk: remove the »< >«
entropy/AdaptiveProbMap.hpp:90:43: advarsel: template-id not allowed for constructor in C++20 [-Wtemplate-id-cdtor]
90 | LogisticAdaptiveProbMap<FAST, RATE>(int n);
| ^
entropy/AdaptiveProbMap.hpp:90:43: bemærk: remove the »< >«
entropy/AdaptiveProbMap.hpp:92:8: advarsel: template-id not allowed for destructor in C++20 [-Wtemplate-id-cdtor]
92 | ~LogisticAdaptiveProbMap<FAST, RATE>() { delete[] _data; }
| ^
[...]
Other projects have also seen the new warnings, occuring since some gcc 14.x with -Wall, and changed their code due to that, see e.g. this OpenJDK comment
Your code is already aware of the potential issue and prepared for the fix, requiring changing as little as this line
#if __cplusplus >= 202002L // simple-template-id in ctors and dtors rejected in C++20
and the identical line 85 further down in the file.
Maybe even delete the #if's with their old-style #else-clauses completely?
Or do you know of any compiler that requires the <...> parts in the constructors and destrucors?
The attached tst-template_cpp20_warning.cpp compiles and runs correctly without warnings with
all from -std=c++20 down to -std=c++98 with g++ 15.1.1, and also with clang++ -stdc=c++14.
You can reproduce the warnings with -DOLD_STYLE. Sample test:
$ grep -A7 '^#if' tst-template_cpp20_warning.cpp
#ifndef OLD_STYLE
TestClass(int n);
~TestClass() { cout << "Goodbye " << _pval << " world!" << endl; }
#else
TestClass<FOO, BAR>(int n);
~TestClass<FOO, BAR>() { cout << "Goodbye " << _pval << " world!" << endl; }
#endif
int get(void);
$ g++ -std=c++98 -Wall -Wextra -O3 -fomit-frame-pointer -fPIC -DNDEBUG -pedantic -march=native -fno-rtti tst-template_cpp20_warning.cpp
$ ./a.out
Hello 6 world!
Hello 5 world!
tc1.get() = 16
tc2.get() = 25
Goodbye 5 world!
Goodbye 6 world!
-Walloc-size warnings
Excerpt:
transform/BWT.cpp: In constructor »kanzi::BWT::BWT(int)«:
transform/BWT.cpp:39:25: advarsel: allocation of insufficient size »0« for type »kanzi::uint« {aka »unsigned int«} with size »4« [-Walloc-size]
39 | _buffer = new uint[0];
| ^
transform/BWT.cpp:40:20: advarsel: allocation of insufficient size »0« for type »int« with size »4« [-Walloc-size]
40 | _sa = new int[0];
| ^
[... a lot of these, e.g. also: ...]
io/CompressedOutputStream.cpp: In constructor »kanzi::CompressedOutputStream::CompressedOutputStream(kanzi::OutputStream&, int, const std::string&, const std::string&, int, int, kanzi::uint64, ThreadPool*, bool)«:
io/CompressedOutputStream.cpp:129:54: advarsel: allocation of insufficient size »0« for type »kanzi::byte« {aka »unsigned char«} with size »1« [-Walloc-size]
129 | _buffers[_jobs] = new SliceArray<byte>(new byte[0], 0, 0);
| ^
io/CompressedOutputStream.cpp:132:53: advarsel: allocation of insufficient size »0« for type »kanzi::byte« {aka »unsigned char«} with size »1« [-Walloc-size]
132 | _buffers[i] = new SliceArray<byte>(new byte[0], 0, 0);
| ^
[...]
This is also quite legal C++14 but considered suspicious by GCC anyway.
-Walloc-size can catch real problems too, not only pseudo/non-problems like this, so it would be best not to silence it with -Wno-alloc-size (that's only supported by some compiler versions, far from all) and instead replace the 38 near-empty allocations with null pointers and guard an appropriate number of delete[]
statements with if ... != nullptr
as is currently only done for two TextCodec variables:
.../kanzi-cpp$ git grep -P 'new \w+\[0]'|wc
38 218 2552
.../kanzi-cpp$ git grep -P 'new \w+\[0]'|head -5
src/entropy/ANSRangeDecoder.cpp: _buffer = new byte[0];
src/entropy/ANSRangeDecoder.cpp: _f2s = new uint8[0];
src/entropy/ANSRangeEncoder.cpp: _buffer = new byte[0];
src/entropy/BinaryEntropyDecoder.cpp: , _sba(new byte[0], 0)
src/entropy/BinaryEntropyEncoder.cpp: , _sba(new byte[0], 0)
.../kanzi-cpp$ git grep -P 'if.*nullptr.*delete\s?\[]'|cat
src/transform/TextCodec.hpp: if (_dictList != nullptr) delete[] _dictList;
src/transform/TextCodec.hpp: if (_dictMap != nullptr) delete[] _dictMap;
src/transform/TextCodec.hpp: if (_dictList != nullptr) delete[] _dictList;
src/transform/TextCodec.hpp: if (_dictMap != nullptr) delete[] _dictMap;