zzy979 / ppp-code Goto Github PK
View Code? Open in Web Editor NEW《C++程序设计原理与实践》书中代码和习题解答
Home Page: https://zzy979.github.io/posts/ppp-note-index/
《C++程序设计原理与实践》书中代码和习题解答
Home Page: https://zzy979.github.io/posts/ppp-note-index/
MSVC编译ch21/word_query.cpp报错:
MSBuild version 17.4.1+9a89d02ff for .NET Framework
fltk.vcxproj -> D:\CLionProjects\PPP-code\cmake-build-debug-visual-studio-2022\_deps\fltk-build\lib\Debug\fltkd.lib
word_query.cpp
D:\CLionProjects\PPP-code\ch21\word_query.cpp(1,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失 [D:\CLionProjects\PPP-code\cmake-build-debug-visual-studio-2022\ch21\word_query.vcxproj]
D:\CLionProjects\PPP-code\ch21\word_query.cpp(103,88): error C3688: 文本后缀“��|�”无效;未找到文文本运算符或文本运算符模板“operator """"��|�” [D:\CLionProjects\PPP-code\cmake-build-debug-visual-studio-2022\ch21\word_query.vcxproj]
D:\CLionProjects\PPP-code\ch21\word_query.cpp(105,37): error C2065: “RE_SINGLE_QUOTES”: 未声明的标识符 [D:\CLionProjects\PPP-code\cmake-build-debug-visual-studio-2022\ch21\word_query.vcxproj]
相关代码如下:
static const std::regex RE_DOUBLE_QUOTES("“|”"), RE_SINGLE_QUOTES("‘|’");
但是gcc编译器正常,GitHub Actions的build-visual-studio也正常。
怀疑是字符编码的问题:源代码是UTF-8编码,而MSVC默认使用GBK编码,如果源代码中包含中文字符(全角引号)就会编译失败。将源文件编码改为GBK后错误就消除了。
提交 5dc031c 触发的Actions流水线报错:
https://github.com/ZZy979/PPP-code/actions/runs/6291461674/job/17079850502
In file included from C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/x86_64-w64-mingw32/include/windows.h:70,
from D:\a\PPP-code\PPP-code\cmake-build\_deps\fltk-src\fluid\ExternalCodeEditor_WIN32.h:27,
from D:\a\PPP-code\PPP-code\cmake-build\_deps\fltk-src\fluid\ExternalCodeEditor_WIN32.cxx:14:
D:\a\PPP-code\PPP-code\cmake-build\_deps\fltk-src\fluid\ExternalCodeEditor_WIN32.cxx: In member function 'int ExternalCodeEditor::reap_editor(DWORD*)':
D:\a\PPP-code\PPP-code\cmake-build\_deps\fltk-src\fluid\ExternalCodeEditor_WIN32.cxx:491:10: error: narrowing conversion of '4294967295' from 'DWORD' {aka 'long unsigned int'} to 'int' [-Wnarrowing]
491 | case WAIT_FAILED: { // failed
| ^~~~~~~~~~~
mingw32-make[2]: *** [_deps\fltk-build\fluid\CMakeFiles\fluid.dir\build.make:361: _deps/fltk-build/fluid/CMakeFiles/fluid.dir/ExternalCodeEditor_WIN32.cxx.obj] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:1451: _deps/fltk-build/fluid/CMakeFiles/fluid.dir/all] Error 2
从错误信息判断原因是FLTK源代码fluid\ExternalCodeEditor_WIN32.cxx中的缩小转换导致的。但是此前一直正常,本次提交运行的其他job也没报错,只有MinGW构建失败。
FLTK仓库已有相关issue:fltk/fltk#92、fltk/fltk#178、fltk/fltk#445,该bug已在1.4版本中修复,但目前尚未发布。
Job链接:https://github.com/ZZy979/PPP-code/actions/runs/4076716325/jobs/7024818373
错误信息:
/home/runner/work/PPP-code/PPP-code/ch12/shape_primitives.cpp: In function ‘int main()’:
/home/runner/work/PPP-code/PPP-code/ch12/shape_primitives.cpp:44:16: error: reference to ‘Font’ is ambiguous
44 | t.set_font(Font::times_bold);
| ^~~~
In file included from /home/runner/work/PPP-code/PPP-code/ch12/shape_primitives.cpp:1:
/home/runner/work/PPP-code/PPP-code/GUI/Graph.h:83:7: note: candidates are: ‘class Graph_lib::Font’
83 | class Font {
| ^~~~
In file included from /usr/include/X11/Xlib.h:44,
from /home/runner/work/PPP-code/PPP-code/cmake-build/_deps/fltk-src/FL/x.H:37,
from /home/runner/work/PPP-code/PPP-code/cmake-build/_deps/fltk-src/FL/fl_draw.H:27,
from /home/runner/work/PPP-code/PPP-code/GUI/Graph.h:10,
from /home/runner/work/PPP-code/PPP-code/ch12/shape_primitives.cpp:1:
/usr/include/X11/X.h:100:13: note: ‘typedef XID Font’
100 | typedef XID Font;
| ^~~~
gmake[2]: *** [ch12/CMakeFiles/shape_primitives.dir/build.make:76: ch12/CMakeFiles/shape_primitives.dir/shape_primitives.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:5052: ch12/CMakeFiles/shape_primitives.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2
解决方法:使用完全限定名称 Graph_lib::Font
提交 190f6c0 触发的Actions流水线运行单测在部分环境下失败:
https://github.com/ZZy979/PPP-code/actions/runs/6746001569
单测失败的程序为drill24-4.cpp,程序通过错误码errno
或者浮点数异常fetestexcept()
来判断标准数学函数sqrt()
是否计算成功。输入为drill24-4_input.txt,预期输出为drill24-4_output.txt,实际结果:
操作系统 | 编译器 | 结果 |
---|---|---|
Ubuntu | GNU GCC 11.4.0 | 成功 |
macOS | AppleClang 14.0.0 | 失败 |
Windows | MSVC 19.37.32825.0 | 失败 |
Windows | MinGW GCC 12.2.0 | 成功 |
问题1:在构建目标fltk_images
时报错:
[ 31%] Building CXX object _deps/fltk-build/src/CMakeFiles/fltk_images.dir/Fl_PNG_Image.cxx.obj
D:/a/PPP-code/PPP-code/cmake-build/_deps/fltk-src/src/Fl_PNG_Image.cxx:44:14: fatal error: libpng/png.h: No such file or directory
44 | # include <libpng/png.h>
| ^~~~~~~~~~~~~~
compilation terminated.
gmake.exe[2]: *** [_deps/fltk-build/src/CMakeFiles/fltk_images.dir/build.make:167: _deps/fltk-build/src/CMakeFiles/fltk_images.dir/Fl_PNG_Image.cxx.obj] Error 1
gmake.exe[1]: *** [CMakeFiles/Makefile2:1054: _deps/fltk-build/src/CMakeFiles/fltk_images.dir/all] Error 2
gmake.exe: *** [Makefile:146: all] Error 2
解决方法:增加CMake选项-D OPTION_USE_SYSTEM_LIBJPEG=OFF -D OPTION_USE_SYSTEM_LIBPNG=OFF -D OPTION_USE_SYSTEM_ZLIB=OFF
问题2:构建成功,但可执行程序和单元测试运行失败:
Start 322: AreaTest.Good
322/661 Test #322: AreaTest.Good ...........................................Exit code 0xc0000139
***Exception: 0.01 sec
Start 323: AreaTest.Bad
323/661 Test #323: AreaTest.Bad ............................................Exit code 0xc0000139
***Exception: 0.01 sec
Start 324: FramedAreaTest.Good
324/661 Test #324: FramedAreaTest.Good .....................................Exit code 0xc0000139
***Exception: 0.01 sec
Start 325: FramedAreaTest.Bad
325/661 Test #325: FramedAreaTest.Bad ......................................Exit code 0xc0000139
***Exception: 0.01 sec
...
322 - AreaTest.Good (Exit code 0xc0000139)
323 - AreaTest.Bad (Exit code 0xc0000139)
324 - FramedAreaTest.Good (Exit code 0xc0000139)
325 - FramedAreaTest.Bad (Exit code 0xc0000139)
原因:需要静态链接C和C++标准库
解决方法:增加链接选项-static -static-libgcc -static-libstdc++
PR #12 尝试将CI使用的构建模式改为Release,但是运行测试时发现build-unix-makefiles (ubuntu-latest)和build-mingw-makefiles两个job在卡在运行测试fibonacci_series_test,导致超时失败:
定位原因后发现fibonacci_series依赖整数溢出结束循环,而这是一个未定义行为,参考Arithmetic operators - Overflows:
When signed integer arithmetic operation overflows (the result does not fit in the result type), the behavior is undefined
不同编译器、不同优化模式可能会有不同的结果。
在Linux系统、GCC 8.2.0、C++14环境下,使用下面的代码进行测试:
#include <iostream>
using namespace std;
int main() {
int x = 1134903170, y = 1836311903, z = x + y;
cout << z << ' ' << (z > 0) << endl;
int a = 1, b = 1, i = 0;
while (a > 0 && ++i < 50) {
cout << a << ' ' << (a > 0) << endl;
int c = a + b;
a = b;
b = c;
}
return 0;
}
Debug模式的输出结果:
-1323752223 0
1 1
1 1
2 1
3 1
...
701408733 1
1134903170 1
1836311903 1
Release模式的输出结果:
-1323752223 0
1 1
1 1
2 1
3 1
...
701408733 1
1134903170 1
1836311903 1
-1323752223 1
512559680 1
-811192543 1
可以看到,在Release模式下,当a
发生溢出时,a > 0
仍然被判断为true
(甚至与循环之前z > 0
的结果不同),因此导致无限循环。
错误信息:
[ 94%] Linking CXX executable hello_fltk.app/Contents/MacOS/hello_fltk
Undefined symbols for architecture x86_64:
"_CFAbsoluteTimeGetCurrent", referenced from:
Fl::add_timeout(double, void (*)(void*), void*) in libfltk.a(Fl_cocoa.mm.o)
Fl::repeat_timeout(double, void (*)(void*), void*) in libfltk.a(Fl_cocoa.mm.o)
...
"_objc_retain", referenced from:
Fl_X::set_cursor(Fl_Cursor) in libfltk.a(Fl_cocoa.mm.o)
Fl_Paged_Device::print_window(Fl_Window*, int, int) in libfltk.a(Fl_cocoa.mm.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [ch12/hello_fltk.app/Contents/MacOS/hello_fltk] Error 1
make[1]: *** [ch12/CMakeFiles/hello_fltk.dir/all] Error 2
make: *** [all] Error 2
原因:缺少链接选项 -framework Cocoa
操作系统版本:macOS 12.5.1
$ c++ --version
Apple clang version 13.1.6 (clang-1316.0.21.2.5)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
$ ctest
...
98% tests passed, 13 tests failed out of 661
Total Test time (real) = 9.01 sec
The following tests FAILED:
155 - convert_length_unit_test_cm_compare (Failed)
158 - convert_length_unit_test_inch_compare (Failed)
161 - convert_length_unit_test_feet_compare (Failed)
164 - convert_length_unit_v2_test_cm_compare (Failed)
167 - convert_length_unit_v2_test_inch_compare (Failed)
170 - convert_length_unit_v2_test_feet_compare (Failed)
179 - convert_currency_test_pound_compare (Failed)
191 - convert_currency_v2_test_pound_compare (Failed)
200 - convert_currency_v2_test_baht_compare (Failed)
230 - length_statistics_test_compare (Failed)
411 - CalculatorV2LexerTest.Get (Failed)
548 - temp_stats_test_run (Failed)
549 - temp_stats_test_compare (Not Run)
Errors while running CTest
这些单测失败的原因:当数字后面紧跟一个非数字字符时,>>
运算符在不同编译器的行为可能不同。例如,对于cin >> length >> unit
,输入"2.5c",不同编译器可能得到不同的结果。经过测试发现结果与数字后面的具体字符有关:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
for (int i = 'a'; i <= 'z'; ++i) {
istringstream iss(string("2.5") + char(i));
double d = -1;
char c = ' ';
iss >> d >> c;
cout << bool(iss) << ' ' << d << ' ' << c << endl;
}
return 0;
}
测试机器上的clang编译器得到的结果为:
0 0
0 0
0 0
0 0
0 0
0 0
1 2.5 g
1 2.5 h
0 0
1 2.5 j
1 2.5 k
1 2.5 l
1 2.5 m
0 0
1 2.5 o
0 0
1 2.5 q
1 2.5 r
1 2.5 s
1 2.5 t
1 2.5 u
1 2.5 v
1 2.5 w
0 0
1 2.5 y
1 2.5 z
gcc编译器得到的结果为:
1 2.5 a
1 2.5 b
1 2.5 c
1 2.5 d
0 0
1 2.5 f
1 2.5 g
1 2.5 h
1 2.5 i
1 2.5 j
1 2.5 k
1 2.5 l
1 2.5 m
1 2.5 n
1 2.5 o
1 2.5 p
1 2.5 q
1 2.5 r
1 2.5 s
1 2.5 t
1 2.5 u
1 2.5 v
1 2.5 w
1 2.5 x
1 2.5 y
1 2.5 z
因此,为了确保一致的行为,需要在数字和字符之间加一个空格。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.