HHehr0ow

HHehr0ow

V2EX 第 107504 号会员,加入于 2015-03-26 18:55:51 +08:00
根据 HHehr0ow 的设置,主题列表被隐藏
二手交易 相关的信息,包括已关闭的交易,不会被隐藏
HHehr0ow 最近回复了
2019-09-27 20:41:51 +08:00
回复了 BruceAuyeung 创建的主题 程序员 c++动态调用链接库的问题
是可行的。
以 Windows 下 DLL 为例,使用 LoadLibrary 加载 module 之后获得 handle,再使用 GetProcAddress 获得目标函数指针 pFooTarget。
之后神奇的部分就发生了,假定 FooTarget 使用了 x86 cdecl calling convention,可以根据 xml 中描述的变量信息,在调用 pFooTarget 之前自行按照 cdecl 的规则进行参数压栈,最后一句汇编 CALL,即可完成函数的调用。
同样,调用完毕后,需要自行到寄存器或者栈上取回返回值,比如 eax。
2019-06-12 23:23:52 +08:00
回复了 codechaser 创建的主题 C++ C++变量初始化问题
看编译器报错,缺啥补啥
2018-11-22 23:39:52 +08:00
回复了 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。

港真,好好写人能读懂的代码,不要乱飞这些乱七八糟的类型更重要。
2018-10-15 22:55:04 +08:00
回复了 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 》。
2018-10-14 22:08:20 +08:00
回复了 zhangZMZ 创建的主题 2018 来到这世界很无奈
多晒太阳,在户外走走,眼前看得见比几米就到头的墙壁更宽阔的地方。
多运动,多健身,冲重量,流流汗。
多看书,感受先哲迷茫时的共情。
祝你好运。
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3075 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 12ms · UTC 13:16 · PVG 21:16 · LAX 05:16 · JFK 08:16
Developed with CodeLauncher
♥ Do have faith in what you're doing.