[llvm-bugs] [Bug 28815] Incorrect/inconsistent warning on use of static member of class template

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Sep 12 10:28:28 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=28815

Serge Pavlov <sepavloff at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |sepavloff at gmail.com
         Resolution|---                         |INVALID

--- Comment #1 from Serge Pavlov <sepavloff at gmail.com> ---
It is right to expect that the compiler warns on unavailable template
definitions for functions, similar as it warns on unavailable definition for
'member_var'. In fact it issues the warnings but they are turned off by
default. If the option '-Wundefined-func-template' is specified, compiler
issues appropriate warnings and notes for both static member and global
function:

28815.cpp:11:24: warning: instantiation of function Example<int>::member_fn'
required here, but no definition is available [-Wundefined-func-template]
  return Example<int>::member_fn();
                           ^
28815.cpp:3:14: note: forward declaration of template entity is here
    static T member_fn();
                 ^
28815.cpp:11:24: note: add an explicit instantiation declaration to suppress
this warning if 'Example<int>::member_fn' is explicitly instantiated in another
translation unit
  return Example<int>::member_fn();
                           ^
...
28815.cpp:19:10: warning: instantiation of function 'fn<int>' required here,
but no definition is available [-Wundefined-func-template]
      return fn<int>();
             ^
28815.cpp:7:24: note: forward declaration of template entity is here
template<typename T> T fn();
                           ^
28815.cpp:19:10: note: add an explicit instantiation declaration to suppress
this warning if 'fn<int>' is explicitly instantiated in another translation
unit
  return fn<int>();

This warning is turned off because function specializations without definitions
in the same file are used pretty often. Users would be annoyed if such warning
was enabled by default. As for the warning  '-Wundefined-var-template', it was
implemented and enabled by default to assist users in solving problems of
instantiation failures in tricky cases. The logic of variable instantiations is
less intuitive and can be especially obscure when modules are used. The problem
https://llvm.org/bugs/show_bug.cgi?id=24425 may be an example of such
complexity.

It is correct that using template instantiation without definitions is not an
error. Usual practice is to provide template definitions and let compiler to
instantiate necessary templates implicitly. This is simple and convenient way.
In large projects it may cause substantial slowdown of builds, as compiler
spends lots of time to instantiate the same things over and over. Using
explicit instantiation can drastically reduce compile time in such cases. There
may be other reasons to avoid implicit instantiation, such as better
encapsulation. 

Now let's consider why the warning is absent for 'var<0>' while similar
reference to 'Example<int>::member_var' causes it. Declaration of the static
member  'member_var' is not a definition as per [basic.def]p2:

    A declaration is a definition unless
    …
    (2.3) — it declares a non-inline static data member in a class definition
(9.2, 9.2.3),

Declaration of 'template<int n> int var' does not fall into any of cases
mentioned in this statement, so it is a definition. This is much similar to the
case of non-template declarations.

Clang behaves correctly in the provided cases, so close the problem report.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160912/41b7eeaf/attachment.html>


More information about the llvm-bugs mailing list