变量已被优化,因而不可用。

在调试时关闭 Target 或者指定模块的代码优化,能够更好的分析问题。
ModuleRulesOptimizeCode 属性是用来控制当前模块是否要开启优化代码,在我们用 VS 调试时,有时候会看到“变量已被优化,因而不可用”,这就是因为被优化了。
可以使用它来关闭优化:

1
2
// build.cs
OptimizeCode = CodeOptimization.Never;

CodeOptimization支持几种值,默认是Default,开启优化:

  • Never
  • Default
  • InNonDebugBuilds
  • InShippingBuildsOnly

相关的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// UnrealBuildTool/Configutation/UEBuildModuleCPP.cs
public static bool ShouldEnableOptimization(ModuleRules.CodeOptimization Setting, UnrealTargetConfiguration Configuration, bool bIsEngineModule)
{
switch(Setting)
{
case ModuleRules.CodeOptimization.Never:
return false;
case ModuleRules.CodeOptimization.Default:
case ModuleRules.CodeOptimization.InNonDebugBuilds:
return (Configuration == UnrealTargetConfiguration.Debug)? false : (Configuration != UnrealTargetConfiguration.DebugGame || bIsEngineModule);
case ModuleRules.CodeOptimization.InShippingBuildsOnly:
return (Configuration == UnrealTargetConfiguration.Shipping);
default:
return true;
}
}

这个函数在 UEBuildModuleCPP.csCreateModuleCompileEnvironment中调用,将结果赋值给了 CppCompileEnvironment.bOptimizeCode,进而又在VCToolChain.cs 中被使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
UnrealBuildTool\Platform\Windows\VCToolChain.cs

void AppendCLArguments_Global(CppCompileEnvironment CompileEnvironment, List<string> Arguments)
{
// other code ...

//
// Debug
//
if (CompileEnvironment.Configuration == CppConfiguration.Debug)
{
// Disable compiler optimization.
Arguments.Add("/Od");

// Favor code size (especially useful for embedded platforms).
Arguments.Add("/Os");

// Allow inline method expansion unless E&C support is requested
if (!CompileEnvironment.bSupportEditAndContinue && CompileEnvironment.bUseInlining)
{
Arguments.Add("/Ob2");
}

if ((CompileEnvironment.Platform == CppPlatform.Win32) ||
(CompileEnvironment.Platform == CppPlatform.Win64))
{
Arguments.Add("/RTCs");
}
}
//
// Development and LTCG
//
else
{
if(!CompileEnvironment.bOptimizeCode)
{
// Disable compiler optimization.
Arguments.Add("/Od");
}
else
{
// Maximum optimizations.
Arguments.Add("/Ox");

// Favor code speed.
Arguments.Add("/Ot");

// Coalesce duplicate strings
Arguments.Add("/GF");

// Only omit frame pointers on the PC (which is implied by /Ox) if wanted.
if (CompileEnvironment.bOmitFramePointers == false
&& ((CompileEnvironment.Platform == CppPlatform.Win32) ||
(CompileEnvironment.Platform == CppPlatform.Win64)))
{
Arguments.Add("/Oy-");
}
}

// Allow inline method expansion
Arguments.Add("/Ob2");

//
// LTCG
//
if (CompileEnvironment.bAllowLTCG)
{
// Enable link-time code generation.
Arguments.Add("/GL");
}
}

// other code...
}

可以看到,在 Debug 的环境下,是默认关闭优化的。在非 Debug 时根据 CompileEnvironment.bOptimizeCode 的值来决定是否开启优化。
调试效果:
当使用默认时(OptimizeCode = CodeOptimization.Default;):

当关闭代码优化时(OptimizeCode = CodeOptimization.Never;):

建议使用OptimizeCode = CodeOptimization.InShippingBuildsOnly;

注意:这个选项和普通的 C++ 项目在 VS 中的 Properties-Configuration-C/C++-Optimization-Optimization 的设置时一样的。