mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-10 01:55:08 +00:00
Add a note to the C++ compatibility page about templates with no
valid instantiations. llvm-svn: 100836
This commit is contained in:
parent
c68e140657
commit
81a4a72e84
@ -25,6 +25,7 @@
|
||||
<li><a href="#init_static_const">Initialization of non-integral static const data members within a class definition</a></li>
|
||||
<li><a href="#dep_lookup">Unqualified lookup in templates</a></li>
|
||||
<li><a href="#dep_lookup_bases">Unqualified lookup into dependent bases of class templates</a></li>
|
||||
<li><a href="#bad_templates">Templates with no valid instantiations</a></li>
|
||||
<li><a href="#default_init_const">Default initialization of const variable of a class type requires user-defined default constructor</a></li>
|
||||
</ul>
|
||||
|
||||
@ -202,6 +203,53 @@ This works whether the methods are static or not, but be careful:
|
||||
if <tt>DoThis</tt> is virtual, calling it this way will bypass virtual
|
||||
dispatch!
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h2 id="bad_templates">Templates with no valid instantiations</h2>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
The following code contains a typo: the programmer
|
||||
meant <tt>init()</tt> but wrote <tt>innit()</tt> instead.
|
||||
|
||||
<pre>
|
||||
template <class T> class Processor {
|
||||
...
|
||||
void init();
|
||||
...
|
||||
};
|
||||
...
|
||||
template <class T> void process() {
|
||||
Processor<T> processor;
|
||||
processor.innit(); // <-- should be 'init()'
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
Unfortunately, we can't flag this mistake as soon as we see it: inside
|
||||
a template, we're not allowed to make assumptions about "dependent
|
||||
types" like <tt>Processor<T></tt>. Suppose that later on in
|
||||
this file the programmer adds an explicit specialization
|
||||
of <tt>Processor</tt>, like so:
|
||||
|
||||
<pre>
|
||||
template <> class Processor<char*> {
|
||||
void innit();
|
||||
};
|
||||
</pre>
|
||||
|
||||
Now the program will work — as long as the programmer only ever
|
||||
instantiates <tt>process()</tt> with <tt>T = char*</tt>! This is why
|
||||
it's hard, and sometimes impossible, to diagnose mistakes in a
|
||||
template definition before it's instantiated.
|
||||
|
||||
<p>The standard says that a template with no valid instantiations is
|
||||
ill-formed. Clang tries to do as much checking as possible at
|
||||
definition-time instead of instantiation-time: not only does this
|
||||
produce clearer diagnostics, but it also substantially improves
|
||||
compile times when using pre-compiled headers. The downside to this
|
||||
philosophy is that Clang sometimes fails to process files because they
|
||||
contain broken templates that are no longer used. The solution is
|
||||
simple: since the code is unused, just remove it.
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h2 id="default_init_const">Default initialization of const variable of a class type requires user-defined default constructor</h2>
|
||||
<!-- ======================================================================= -->
|
||||
|
Loading…
Reference in New Issue
Block a user