简体   繁体   English

模板编译:gcc vs VS2010

[英]Templates compilation: gcc vs VS2010

From the book - C++ Templates: The Complete Guide by David, Nicolai 摘自《 C ++模板:David,Nicolai的完整指南》

Thus, templates are compiled twice: 因此,模板被编译两次:

  1. Without instantiation, the template code itself is checked for correct syntax. 如果没有实例化,则将检查模板代码本身的语法是否正确。 Syntax errors are discovered, such as missing semicolons. 发现语法错误,例如缺少分号。
  2. At the time of instantiation, the template code is checked to ensure that all calls are valid. 在实例化时,将检查模板代码以确保所有调用均有效。 Invalid calls are discovered, such as unsupported function calls. 发现无效的调用,例如不支持的函数调用。

Keeping the first point, I wrote - 坚持第一点,我写道-

template<typename T>
void foo( T x)
{
   some illegal text
}

int main()
{
   return 0;
}

It build fine on Visual Studio 2010 with out any warnings with optimizations turned off. 它可以在Visual Studio 2010上很好地构建,不会在关闭优化的情况下发出任何警告。 How ever, it failed on gcc-4.3.4 . 但是, 它在gcc-4.3.4上失败了 Which one is complying to the C++ standard ? 哪一个符合C ++标准? Is it mandatory for template code to get compiled even with out template instantiation ? 即使没有模板实例化,模板代码也必须编译吗?

The program in question is ill-formed, but the C++ standard does not require a diagnostic in this case, so both Visual Studio and GCC are behaving in a compliant fashion. 该程序的格式不正确,但在这种情况下C ++标准不需要诊断,因此Visual Studio和GCC都以兼容的方式运行。 From §14.6/7 of the C++03 standard (emphasis mine): 根据C ++ 03标准的§14.6/ 7(强调我的):

Knowing which names are type names allows the syntax of every template definition to be checked. 知道哪些名称是类型名称,就可以检查每个模板定义的语法。 No diagnostic shall be issued for a template definition for which a valid specialization can be generated. 不得针对可为其生成有效专业化的模板定义发布诊断。 If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required. 如果无法为模板定义生成有效的专业化名称,并且未实例化该模板,则该模板定义格式错误,无需诊断。 If a type used in a non-dependent name is incomplete at the point at which a template is defined but is complete at the point at which an instantiation is done, and if the completeness of that type affects whether or not the program is well-formed or affects the semantics of the program, the program is ill-formed; 如果在非依赖名称中使用的类型在定义模板时是不完整的,但在完成实例化时是完整的,并且该类型的完整性影响程序是否正确,形成或影响程序语义的程序,格式不正确; no diagnostic is required. 无需诊断。 [ Note: if a template is instantiated, errors will be diagnosed according to the other rules in this Standard. [ 注意:如果实例化了模板,将根据本标准中的其他规则诊断错误。 Exactly when these errors are diagnosed is a quality of implementation issue. 准确地诊断出这些错误是实施质量的问题。 ] [ Example: ] [ 示例:

 int j; template<class T> class X { // ... void f(T t, int i, char* p) { t = i; // diagnosed if X::f is instantiated // and the assignment to t is an error p = i; // may be diagnosed even if X::f is // not instantiated p = j; // may be diagnosed even if X::f is // not instantiated } void g(T t) { +; //may be diagnosed even if X::g is // not instantiated } }; 

end example ] 结束示例 ]

The book you're looking at seems to reflect (mostly) that author's observations about how compilers really work, not the requirement(s) of the standard. 您正在看的书似乎(大部分)反映了作者对编译器实际工作方式的看法,而不是标准的要求。 The standard doesn't really say much to give extra leniency to a compiler about ill-formed code inside a template, just because it's not instantiated. 该标准并没有说太多的话可以使编译器对模板中格式错误的代码有所宽容,只是因为它没有实例化。

At the same time, the book is correct that there are some things a compiler really can't do much about checking until it's instantiated. 同时,这本书是正确的,即在实例化之前,编译器确实无法完成某些检查工作。 For example, you might use a dependent name as the name of a function (or invoke it like a function, anyway -- if it's functor instead that would be fine too). 例如,您可以使用从属名称作为函数的名称(或者无论如何都像函数一样调用它-如果它是函子,那也可以)。 If you instantiate that template over a class where it is a function, fine and well. 如果您在该模板函数的类上实例化该模板,那很好。 If you instantiate it over a class where it's really an int , attempting to call it will undoubtedly fail. 如果您在实际上是int的类上实例化它,则尝试调用它无疑会失败。 Until you've instantiated it, the compiler can't tell which is which though. 在实例化之前,编译器无法确定是哪一个。

This is a large part of what concepts were really intended to add to C++. 这是concepts真正要添加到C ++中的很大一部分。 You could directly specify (for example) that template X will invoke T::y like a function. 您可以直接指定(例如)模板X将像函数一样调用T::y Then the compiler could compare the content of the template with the declarations in the concept, and determine whether the body of the template fit with the declaration in the concept or not. 然后,编译器可以将模板的内容与概念中的声明进行比较,并确定模板的主体是否适合概念中的声明。 In the other direction, the compiler only needed to compare a class (or whatever) to the concept to determine whether instantiating that template would work. 在另一方面,编译器仅需要将类(或任何类)与概念进行比较,以确定实例化该模板是否可行。 If it wasn't going to work, it could report the error directly as a violation of the relevant concept (as it is now, it tries to instantiate the template, and you frequently get some strange error message that indicates the real problem poorly, if at all). 如果它无法正常工作,它可能会直接报告错误,认为它违反了相关概念(目前,它试图实例化模板,并且您经常会收到一些奇怪的错误消息,指出实际问题很糟糕,如果有的话)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM