【发布时间】:2020-07-24 00:32:16
【问题描述】:
我非常渴望尝试 C++20 模块功能,但在运行时遇到了访问冲突。我能够将其简化为下面的最小示例。它适用于 clang,但使用 Microsoft 编译器运行上述 av。这可能是这个实验性功能的编译器错误,但也许我只是用错了?
下面的命令行不会产生任何调试符号。我查看了 Visual Studio 调试器出了什么问题:
在 main.exe 中的 0x00007FF7222E1027 处引发异常:0xC0000005:访问 违规读取位置0x000027AB00000021。
我在内存视图中检查了上述位置,它确实看起来像未映射的内存。
系统:Windows Server 2019,x64,版本 10.0.17763 Build 17763
CL 编译器:Visual Studio 2019、Microsoft (R) C/C++ 优化编译器版本 19.25.28612 for x64
Clang 编译器:clang 版本 10.0.0,目标:x86_64-pc-windows-msvc
fstmod.ixx:
export module fstmod;
export struct SampleFstMod {
SampleFstMod(const char* pData) {}
};
sndmod.ixx:
export module sndmod;
import fstmod;
export struct SampleSndMod {
SampleSndMod(SampleFstMod name = "SampleString") {}
};
main.cxx:
import sndmod;
int main(int, const char**) {
SampleSndMod variable;
return 0;
}
使用 clang 这个例子有效:
clang++ -fmodules-ts --precompile -x c++-module sndmod.ixx -o sndmod.pcm fstmod.pcm
clang++ -fmodules-ts --precompile -fprebuilt-module-path=. -x c++-module sndmod.ixx -o sndmod.pcm
clang++ -fmodules-ts --verbose -fprebuilt-module-path=. main.cxx -o main.exe
main.exe
使用 MSVC 进行翻译会在运行时产生访问冲突:
cl /EHsc /MDd /std:c++latest /experimental:module /c fstmod.ixx
cl /EHsc /MDd /std:c++latest /experimental:module /c sndmod.ixx
cl /EHsc /MDd /std:c++latest /experimental:module main.cxx fstmod.obj sndmod.obj
main.exe
编辑:
我在问:
- 为什么会出错?
- 可能是 UB,因为它在 clang 中工作?
- 非法指针取消引用导致 av 的哪个/哪里?
- 为什么编译时没有警告?一旦其他人得到回答,我可能会在这里找到一个启用警告的开关。
注意,我检查了反汇编,它发生在调用后取消引用 eax 的值时,它正在评估返回参数。
【问题讨论】:
-
您正在为 SampleFstMod 对象分配一个字符串字面量。这没有多大意义。我猜你想要做的是 SampleSndMod(SampleFstMod("SampleString"))
-
为什么两个构造函数一个带有 const char * 而另一个带有结构类型名称?
-
@goaran 是的,完全正确。我想要一个 SampleFstMod 作为可选参数。如果没有设置,我想要一个用那个特定的 const char* 构造的。此外,这似乎不是特定于模块的问题,对于误导性标题感到抱歉......
-
@Mannoj 这只是一个与我的预期相矛盾的最小示例,而不是真实世界的代码。
-
那么构造函数应该是 SampleSndMod(SampleFstMod sfm = SampleFstMod("SampleString")) {}