【问题标题】:Template access of symbol in unnamed namespace未命名命名空间中符号的模板访问
【发布时间】:2011-02-01 07:55:26
【问题描述】:

我们正在将我们的 XL C/C++ 编译器从 V8.0 升级到 V10.1,发现一些代码现在给我们一个错误,即使它是在 V8.0 下编译的。这是一个最小的例子:

test.h:

#include <iostream>
#include <string>

template <class T>
void f()
{
  std::cout << TEST << std::endl;
}

test.cpp:

#include <string>
#include "test.h"

namespace
{
  std::string TEST = "test";
}

int main()
{
  f<int>();
  return 0;
}

在V10.1下,出现如下错误:

"test.h", line 7.16: 1540-0274 (S) The name lookup for "TEST" did not find a declaration.
"test.cpp", line 6.15: 1540-1303 (I) "std::string TEST" is not visible.
"test.h", line 5.6: 1540-0700 (I) The previous message was produced while processing "f<int>()".
"test.cpp", line 11.3: 1540-0700 (I) The previous message was produced while processing "main()".

我们发现 g++ 3.3.2 和 4.3.2 之间存在类似的差异。我还在 g++ 中发现,如果我将 #include "test.h" 移动到未命名的命名空间声明之后,编译错误就会消失。

所以这是我的问题:标准对此有何评论?当模板被实例化时,该实例是否被认为是在模板本身被声明的地方被声明的,或者标准在这一点上不是很清楚?我看了一些 n2461.pdf 草案,但并没有真正想出任何确定的东西。

【问题讨论】:

    标签: c++ templates standards-compliance


    【解决方案1】:

    此测试未通过 Comeau online compiler,过去已证明它是最符合标准的编译器之一。那么,我倾向于认为代码是不正确的,尽管我无法指出标准中的一行来说明原因。请注意,在轻松模式下编译代码会成功。

    【讨论】:

      【解决方案2】:

      这不是有效的 C++ 代码。 TEST 不依赖于模板参数T,因此解析时必须在模板定义的上下文中找到。但是,在这种情况下,不存在 TEST 的声明,因此存在错误。

      该格式错误的模板的诊断消息可以延迟到编译器实例化,但如果编译器是好的,它会更早地诊断错误。即使在模板被实例化时也不为该代码提供任何诊断消息的编译器不符合要求。它与未命名的命名空间无关。

      此外,请注意,即使您将未命名的命名空间放在该模板之上,如果您在多个翻译单元中定义和调用该模板,它也不是有效的 C++ 程序。这是因为具有相同模板参数的同一模板的不同实例化将引用不同的事物(未命名命名空间中的字符串每次在另一个翻译单元中定义时都会产生不同的对象)。这种程序的行为将是未定义的。

      【讨论】:

      • 谢谢,约翰内斯。我希望你能加入。我觉得有趣的是旧的编译器通过了它。我可以阅读标准中的某个区域来更好地理解这一点吗?
      • @Fred 编译器似乎已经改进,现在可以进行两阶段名称查找。见模板常见问题:womble.decadentplace.org.uk/c++/template-faq.html
      • 关于您的编辑,我也想到了这一点。我认为我们解决这个问题的方法是从模板中消除此类引用。无论如何,这将是更正确的行为。
      • 感谢您的链接。我回家后会查一下。我们工作中的互联网过滤器不会让我去那里。 >8v(
      • 我想我在 C++03 草案标准 (n2461.pdf) 的 14.6.9 中找到了这个。
      猜你喜欢
      • 1970-01-01
      • 2010-12-29
      • 2012-03-26
      • 2018-05-14
      • 2018-02-03
      • 2014-11-14
      • 2017-12-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多