Non-existing identifier used as default argument in non-instantiated function template
今天发现一段代码相当于如下:
1 2 3 4 5 6 7 8 9 10 11 12
|
enum X
{
x1 = 0,
x2 = 1
};
template<typename T> void bar(T obj, X x = x3) { } // ^^ // This identifier is bogus!
int main() { } |
VC10 和 VC12 都可以愉快地编译它。 clang 3.4 和 GCC 4.8.1 都拒绝它(这是我所期望的)。
这是一个错误,还是标准实际上允许 VC 的行为?如果有,哪些是相关段落?
- 哇,有趣的是汇编器 VS 为此生成了什么
-
请注意 – VC 18 (VS 2013) 拒绝此代码。
-
@CaptainObvlious:什么是 VC 18?
-
@AndyProwl VS 附带的编译器版本。
-
@CaptainObvlious:那是 VC12 AFAIK。我正在使用 VS2013,它确实可以编译它。我错过了什么吗?
-
@Andy:运行 cl.exe 时检查”Microsoft C/C Optimizing Compiler”的版本字符串,自从产品名称从”Microsoft C/C”更改为”Microsoft Visual C”之前它一直在增加。 IIRC,Microsoft C/C 达到 7.0 版本,随后是 Visual C 1.0
-
@Ben:啊,谢谢,这澄清了。那么VS2010和VS2013自带的Visual C编译器的正确引用方式是什么?我以为是”VC10″和”VC12″。
-
(不过,我使用的是 VS2013,它确实编译了这个片段)
-
@Andy:VS2012(VS 11.0)带有”Visual C 2012″,也是版本 11.0,并使用 Microsoft C/C 编译器 17.0。 DLL 被命名为 MSVCR110,与 Visual Studio 版本号匹配,而不是编译器版本号。我想 17.0 不应该与缩写 VS 或 VC 或 MSVC 配对,但如果你报告一个内部编译器错误,你肯定想要那个版本字符串,可能表示为 CL.EXE 17.00.61030 x86
-
@Ben:”VC12″是指 VS2013 附带的编译器(与 S. T. Lavavej 使用的编号一致,例如此处)。在提到 VC 编译器的某个版本时,我实际上从未见过提到数字 17 或 18(我一直读到”… VC10, VC11, VC12″)。可能是时候改变这一点了。
众所周知,VC 没有两阶段查找。这意味着它接受模板中的各种虚假,只要它至少看起来像语法上有效的 C 并且它实际上没有被实例化。
这只是其中一个例子。
正如您在他们的一致性路线图中所看到的,两阶段查找计划在 RTM CTP 之后的某个时间进行,我猜这意味着您将在为 Visual Studio 套件的下一次迭代付费后访问它.
至于标准参考,14.6/9-10 说:
When looking for the declaration of a name used in a template definition, the usual lookup rules (3.4.1, 3.4.2) are used for non-dependent names. […]
If a name does not depend on a template-parameter (as defined in 14.6.2), a declaration (or set of declarations) for that name shall be in scope at the point where the name appears in the template definition.
- @Xeo:编译器不再在 Windows SDK 中
-
@BenVoigt:哦,很高兴知道。不过,它仍然可以通过免费的 VS 版本免费获得。
-
@Xeo:是的,并且借助 Visual Studio”多目标支持”,也许可以将较新的编译器与较旧但更完整的付费版本一起使用。虽然没有保证。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/268925.html