Template access of symbol in unnamed namespace

谁都会走 提交于 2019-12-24 08:25:53

问题


We are upgrading our XL C/C++ compiler from V8.0 to V10.1 and found some code that is now giving us an error, even though it compiled under V8.0. Here's a minimal example:

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;
}

Under V10.1, we get the following error:

"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()".

We found a similar difference between g++ 3.3.2 and 4.3.2. I also found in g++, if I move the #include "test.h" to be after the unnamed namespace declaration, the compile error goes away.

So here's my question: what does the Standard say about this? When a template is instantiated, is that instance considered to be declared at the point where the template itself was declared, or is the standard not that clear on this point? I did some looking though the n2461.pdf draft, but didn't really come up with anything definitive.


回答1:


This is not valid C++ code. TEST is not dependent on the template parameter T, so it must be found in the context of the template definition when it's parsed. However, in that context no declaration of TEST exists, and so there is an error.

The diagnostic message for that ill-formed template can be delayed until instantiation by the compiler, but if the compiler is good, it will diagnose the error earlier. Compilers that don't give any diagnostic message for that code even when the template is instantiated are not conforming. It has nothing to do with unnamed namespaces.

In addition, notice that even if you put the unnamed namespace above that template, it will not be a valid C++ program either if you define and call that template in multiple translation units. This is because different instantiations of the same template with the same template arguments will refer to different things (the string in the unnamed namespace will produce a different object each time it's defined in another translation unit). Behavior for such a program would be undefined.




回答2:


This test fails the Comeau online compiler which in the past has shown to be one of the most standards-compliant compilers around. I would lean in favor, then, that the code is incorrect as written, though I could not point you to a line in the standard as to why. Note that compiling the code in relaxed mode succeeds, however.



来源:https://stackoverflow.com/questions/2525984/template-access-of-symbol-in-unnamed-namespace

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!