gpt4 book ai didi

C# 不会编译在开头附近带有\0 的长 const 字符串

转载 作者:IT王子 更新时间:2023-10-29 03:56:34 26 4
gpt4 key购买 nike

我遇到了一个特殊情况,在创建某些类型的字符串时出现以下错误:

Unexpected error writing debug information -- 'Error HRESULT E_FAIL has been returned from a call to a COM component.'

这个错误对 Stack Overflow 来说并不新鲜(参见 this questionthis question),但是出现的问题与这个错误无关。

对我来说,当我创建一个一定长度的 const 字符串时会发生这种情况,该字符串在开头附近的某处包含一个空终止字符 (\0)。

要重现,首先生成一个适当长度的字符串,例如使用:

var s = new string('a', 3000);

在运行时获取结果字符串(例如,立即窗口或将鼠标悬停在变量上并复制其值)。然后,从中创建一个 const:

const string history = "aaaaaa...aaaaa";

最后,在某处放一个\0:

const string history = "aaaaaaaaaaaa\0aa...aaaaa";

我注意到的一些事情:

  • 如果将 \0 放在末尾附近,则不会发生错误。
  • 使用 .NET Framework 4.6.1 和 4.5 复制
  • 如果字符串很短则不会发生。
  • 编辑:下面的评论中提供了更多宝贵的信息。

知道为什么会这样吗?是某种错误吗?

编辑:Bug归档,包括来自评论的信息。谢谢大家。

最佳答案

我会稍微讨论一下这个问题。此问题在 VS2015 和更早版本中均会出现。所以与 C# 编译器本身没有直接关系,这在 ISymUnmanagedWriter2::DefineConstant2() 中出错了实现方法。 ISymUnmanagedWriter2 是一个 COM 接口(interface),是所有编译器使用的 .NET 基础结构的一部分。并由 Roslyn 和旧版 C# 编译器使用。

使用该方法的 Roslyn 源代码(实际上可以追溯到 CCI project )中的注释足以说明问题,之前发现该方法存在问题:

// EDMAURER If defining a string constant and it is too long (length limit is undocumented), this method throws
// an ArgumentException.
// (see EMITTER::EmitDebugLocalConst)

try
{
this.symWriter.DefineConstant2(name, value, constantSignatureToken);
}
catch (ArgumentException)
{
// writing the constant value into the PDB failed because the string value was most probably too long.
// We will report a warning for this issue and continue writing the PDB.
// The effect on the debug experience is that the symbol for the constant will not be shown in the local
// window of the debugger. Nor will the user be able to bind to it in expressions in the EE.

//The triage team has deemed this new warning undesirable. The effects are not significant. The warning
//is showing up in the DevDiv build more often than expected. We never warned on it before and nobody cared.
//The proposed warning is not actionable with no source location.
}
catch (Exception ex)
{
throw new PdbWritingException(ex);
}

吞下异常,啧啧啧。它死于您案例中的最后一个 catch 子句。他们确实进行了更深入的研究以对字符串长度问题进行逆向工程:

internal const int PdbLengthLimit = 2046; // Empirical, based on when ISymUnmanagedWriter2 methods start throwing.

这非常接近\0 开始抛出的位置,我得到 2034。当然,您或这里的任何其他人对此无能为力。您所能做的就是在 connect.microsoft.com 上报告错误。但希望你能看到墙上的文字,它得到修复的可能性很小。这是没有人再维护的代码,它现在具有“未记录”状态,并且从其他评论来看,这可以追溯到.NET 之前很久。也不是 Ed Maurer :)

解决方法应该很简单,在运行时将这个字符串粘在一起。

关于C# 不会编译在开头附近带有\0 的长 const 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34706411/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com