HHehr0ow

HHehr0ow

V2EX member #107504, joined on 2015-03-26 18:55:51 +08:00
Per HHehr0ow's settings, the topics list is hidden
Deals info, including closed deals, is not hidden
HHehr0ow's recent replies
Sep 27, 2019
Replied to a topic by BruceAuyeung 程序员 c++动态调用链接库的问题
是可行的。
以 Windows 下 DLL 为例,使用 LoadLibrary 加载 module 之后获得 handle,再使用 GetProcAddress 获得目标函数指针 pFooTarget。
之后神奇的部分就发生了,假定 FooTarget 使用了 x86 cdecl calling convention,可以根据 xml 中描述的变量信息,在调用 pFooTarget 之前自行按照 cdecl 的规则进行参数压栈,最后一句汇编 CALL,即可完成函数的调用。
同样,调用完毕后,需要自行到寄存器或者栈上取回返回值,比如 eax。
Jun 12, 2019
Replied to a topic by codechaser C++ C++变量初始化问题
看编译器报错,缺啥补啥
Nov 22, 2018
Replied to a topic by hackpro C++ C++ 模板重载问题请教
main() 里面,
```
auto m2 = ::max(s1, s2, s3); //run-time ERROR
```
这句会进入第 3 个 function template
```
// maximum of three values of any type (call-by-reference)
template<typename T>
T const& max (T const& a, T const& b, T const& c)
{
return max (max(a,b), c); // error if max(a,b) uses call-by-value
}
```
这句又进入了第 2 个 function template
```
// maximum of two C-strings (call-by-value)
char const* max (char const* a, char const* b)
{
return std::strcmp(b,a) < 0 ? a : b;
}
```
此时,由于返回类型是 char const*,一个指针 variable,不论 a/b 哪个更大,都会返回一个 variable,类型是 char const*,值是 a/b 中 strcmp 较大的那个指向的地址。这个 variable 就是所谓的 temporary variable。

类似于
```
T a = foo();
```
foo() evaluate 完之后,所有 foo() 中的变量 life cycle 都结束了,那 assignment 要拿谁做等号右边的 variable ?这种情况就会产生一个 temporary variable 用来临时存放返回值,等 assignment 结束后,temporary variable 的 life cycle 也结束了。当然,实际代码中 temporary variable 可能被 RVO 优化掉,更或者被 C++17 的 copy elision 处理掉。这里不展开了。

第 2 个 function template return 后,回到第 3 个 function template,此时,等价于
```
return max(temporary_variable, c);
```
这里会再进一次第 2 个 function template,返回后等价于
```
return temporary_variable_2;
```
然而,第 3 个 function template 返回的类型是 T const&,也就是返回了 temporary variable 的引用,一直传递到了 main 里面,而这个 temporary variable 的 life cycle 也就到第 3 个 function template 结束而已。对 temporary variable 的使用超过的它的 life cycle,是一种 run time error。

此时会不会 crash 就是 UB 了,一般编译器不会做类似 variable life cycle 一结束就清除它的内存之类激进的事情,所以 temporary variable 的内存地址里“可能”暂时还会是它原本的内容( UB ),将这些字节解释回变量的内容也“可能”得到原来变量的值( UB again )。并且
```
auto m2 = ::max(s1, s2, s3);
```
这里,auto 会得到 decay 的类型,去掉了引用,因此只要这个 temporary variable “曾经”所在的内存能撑过这句,就能得到原本的变量值。


```
auto m1 = ::max(7, 42, 68); // OK
```
没问题的原因是它从头到尾就不会进第 2 个 function template,始终是引用飞来飞去,引用的就是 7/42/68 这三个 integer literal 产生的 temporary variable,life cycle 是到该语句结束,然后被 auto 得到 decay 的类型后 copy 一份。不属于 UB。

港真,好好写人能读懂的代码,不要乱飞这些乱七八糟的类型更重要。
Oct 15, 2018
Replied to a topic by css3 程序员 不懂 C/C++程序编译,该怎么学习编译?
1. 为什么实际工程中不用 g++ 命令?
其实也用,只不过是隐含在 makefile 里,执行 makefile 时候会自动调用。很多参考书给的用例,因为只有一个 cpp 文件,特意编写 makefile 来组织显得过于繁冗,因而直接一句 g++ 命令生成目标文件方便快捷。而实际工程中动辄几百个 cpp/header/so/a 文件,文件之间还存在依赖关系,这种情况下仍然手工一句一句 g++ 来编译实在过于复杂而且低效。

2. makefile 本质就是描述工程中的依赖关系和编译参数。执行时会自动根据依赖关系确定编译顺序,按序编译。makefile 是 unix-like 系统下的解决方案,Windows 下一般使用 MSVC 的 sln 工程文件。本质都是一样的东西。CMake 是一个跨平台的解决方案,执行时根据选择的目标平台不同将 CMakeList.txt “翻译”成 makefile 或者 vcxproj。

3. 自己搞个几十个 cpp 的小项目,跑一跑,在实践中摸索熟悉吧。相关的书籍有 《程序员的自我修养》、《 GNU Make 项目管理》。还有个文章《跟我一起写 Makefile 》。
Oct 14, 2018
Replied to a topic by zhangZMZ 2018 来到这世界很无奈
多晒太阳,在户外走走,眼前看得见比几米就到头的墙壁更宽阔的地方。
多运动,多健身,冲重量,流流汗。
多看书,感受先哲迷茫时的共情。
祝你好运。
About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5387 Online   Highest 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 10ms · UTC 07:52 · PVG 15:52 · LAX 00:52 · JFK 03:52
♥ Do have faith in what you're doing.