unnecessary implicit instantiation?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

unnecessary implicit instantiation?

Kristof Beyls via cfe-dev
Clang issues an error for the following code, whereas the GNU compiler does not.  Based on the standard, I think that an implicit instantiation should not occur because the compiler is not yet allocating an object, and that would mean that Clang is incorrectly issuing an error and GNU is correct to not issue any error.

Is my understanding correct?

> cat t.cpp
template <typename T> class A;

template <typename T>
struct B {
  static A<int> M;
};

template <typename T> A<int> B<T>::M;
> g++ -c t.cpp
> clang -c t.cpp
t.cpp:8:36: error: implicit instantiation of undefined template 'A<int>'
template <typename T> A<int> B<T>::M;
                                   ^
t.cpp:1:29: note: template is declared here
template <typename T> class A;
                            ^
1 warning and 1 error generated.


Thanks,
Troy

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: unnecessary implicit instantiation?

Kristof Beyls via cfe-dev
If there's a different email list for C++ language questions like this, please let me know, since I'm trying establish which compiler's behavior is correct before I try to change anything in Clang.  The standard is a little fuzzy on this matter because it says that the instantiation occurs as needed, and one could argue that one does not need to know the size of a static data member in order to use the class type as part of another definition.  Clang seems to want the whole definition of the class, including static data, to be fully defined before using it.

-Troy

From: cfe-dev <[hidden email]> on behalf of Troy Johnson via cfe-dev <[hidden email]>
Sent: Wednesday, September 18, 2019 4:26 PM
To: [hidden email] <[hidden email]>
Subject: [cfe-dev] unnecessary implicit instantiation?
 
Clang issues an error for the following code, whereas the GNU compiler does not.  Based on the standard, I think that an implicit instantiation should not occur because the compiler is not yet allocating an object, and that would mean that Clang is incorrectly issuing an error and GNU is correct to not issue any error.

Is my understanding correct?

> cat t.cpp
template <typename T> class A;

template <typename T>
struct B {
  static A<int> M;
};

template <typename T> A<int> B<T>::M;
> g++ -c t.cpp
> clang -c t.cpp
t.cpp:8:36: error: implicit instantiation of undefined template 'A<int>'
template <typename T> A<int> B<T>::M;
                                   ^
t.cpp:1:29: note: template is declared here
template <typename T> class A;
                            ^
1 warning and 1 error generated.


Thanks,
Troy

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: unnecessary implicit instantiation?

Kristof Beyls via cfe-dev
I believe the rules are that since 'M' is not dependent on any template parameters, it can be checked without deferring until the point of instantiation. (& that it isn't /required/ to be checked - it's up to the compiler, so both GCC and Clang are correct here)

On Mon, Sep 23, 2019 at 8:07 AM Troy Johnson via cfe-dev <[hidden email]> wrote:
If there's a different email list for C++ language questions like this, please let me know, since I'm trying establish which compiler's behavior is correct before I try to change anything in Clang.  The standard is a little fuzzy on this matter because it says that the instantiation occurs as needed, and one could argue that one does not need to know the size of a static data member in order to use the class type as part of another definition.  Clang seems to want the whole definition of the class, including static data, to be fully defined before using it.

-Troy

From: cfe-dev <[hidden email]> on behalf of Troy Johnson via cfe-dev <[hidden email]>
Sent: Wednesday, September 18, 2019 4:26 PM
To: [hidden email] <[hidden email]>
Subject: [cfe-dev] unnecessary implicit instantiation?
 
Clang issues an error for the following code, whereas the GNU compiler does not.  Based on the standard, I think that an implicit instantiation should not occur because the compiler is not yet allocating an object, and that would mean that Clang is incorrectly issuing an error and GNU is correct to not issue any error.

Is my understanding correct?

> cat t.cpp
template <typename T> class A;

template <typename T>
struct B {
  static A<int> M;
};

template <typename T> A<int> B<T>::M;
> g++ -c t.cpp
> clang -c t.cpp
t.cpp:8:36: error: implicit instantiation of undefined template 'A<int>'
template <typename T> A<int> B<T>::M;
                                   ^
t.cpp:1:29: note: template is declared here
template <typename T> class A;
                            ^
1 warning and 1 error generated.


Thanks,
Troy
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: unnecessary implicit instantiation?

Kristof Beyls via cfe-dev
Thank you.  That would appear to contradict C++11 14.7.1 paragraph 8 which said "The implicit instantiation of a class template does not cause any static data members of that class to be implicitly instantiated."  This paragraph seems to have expanded into C++17 17.8.1 paragraph 10, but still includes static data members.

Could you explain how this example does not violate that language?

-Troy

From: David Blaikie <[hidden email]>
Sent: Monday, September 23, 2019 11:23 AM
To: Troy Johnson <[hidden email]>
Cc: [hidden email] <[hidden email]>
Subject: Re: [cfe-dev] unnecessary implicit instantiation?
 
I believe the rules are that since 'M' is not dependent on any template parameters, it can be checked without deferring until the point of instantiation. (& that it isn't /required/ to be checked - it's up to the compiler, so both GCC and Clang are correct here)

On Mon, Sep 23, 2019 at 8:07 AM Troy Johnson via cfe-dev <[hidden email]> wrote:
If there's a different email list for C++ language questions like this, please let me know, since I'm trying establish which compiler's behavior is correct before I try to change anything in Clang.  The standard is a little fuzzy on this matter because it says that the instantiation occurs as needed, and one could argue that one does not need to know the size of a static data member in order to use the class type as part of another definition.  Clang seems to want the whole definition of the class, including static data, to be fully defined before using it.

-Troy

From: cfe-dev <[hidden email]> on behalf of Troy Johnson via cfe-dev <[hidden email]>
Sent: Wednesday, September 18, 2019 4:26 PM
To: [hidden email] <[hidden email]>
Subject: [cfe-dev] unnecessary implicit instantiation?
 
Clang issues an error for the following code, whereas the GNU compiler does not.  Based on the standard, I think that an implicit instantiation should not occur because the compiler is not yet allocating an object, and that would mean that Clang is incorrectly issuing an error and GNU is correct to not issue any error.

Is my understanding correct?

> cat t.cpp
template <typename T> class A;

template <typename T>
struct B {
  static A<int> M;
};

template <typename T> A<int> B<T>::M;
> g++ -c t.cpp
> clang -c t.cpp
t.cpp:8:36: error: implicit instantiation of undefined template 'A<int>'
template <typename T> A<int> B<T>::M;
                                   ^
t.cpp:1:29: note: template is declared here
template <typename T> class A;
                            ^
1 warning and 1 error generated.


Thanks,
Troy
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: unnecessary implicit instantiation?

Kristof Beyls via cfe-dev
I don't think it's instantiating the static member - it's only type checking. (in the same way that "template<typename T> struct foo { my_int x; };" would be invalid if "my_int" wasn't previously defined)


Ah, here we go: from C++17, 17.6 [temp.res]p8:
"Knowing which names are type names allows the syntax of every template to be checked. The program is ill-formed, no diagnostic required, if:"
"(8.3) - a hypothetical instantiation of a template immediately following its definition would be ill-formed due to a construct that does not depend on a template parameter"

Sounds pretty convincing to me, at least.


On Mon, Sep 23, 2019 at 10:52 AM Troy Johnson <[hidden email]> wrote:
Thank you.  That would appear to contradict C++11 14.7.1 paragraph 8 which said "The implicit instantiation of a class template does not cause any static data members of that class to be implicitly instantiated."  This paragraph seems to have expanded into C++17 17.8.1 paragraph 10, but still includes static data members.

Could you explain how this example does not violate that language?

-Troy

From: David Blaikie <[hidden email]>
Sent: Monday, September 23, 2019 11:23 AM
To: Troy Johnson <[hidden email]>
Cc: [hidden email] <[hidden email]>
Subject: Re: [cfe-dev] unnecessary implicit instantiation?
 
I believe the rules are that since 'M' is not dependent on any template parameters, it can be checked without deferring until the point of instantiation. (& that it isn't /required/ to be checked - it's up to the compiler, so both GCC and Clang are correct here)

On Mon, Sep 23, 2019 at 8:07 AM Troy Johnson via cfe-dev <[hidden email]> wrote:
If there's a different email list for C++ language questions like this, please let me know, since I'm trying establish which compiler's behavior is correct before I try to change anything in Clang.  The standard is a little fuzzy on this matter because it says that the instantiation occurs as needed, and one could argue that one does not need to know the size of a static data member in order to use the class type as part of another definition.  Clang seems to want the whole definition of the class, including static data, to be fully defined before using it.

-Troy

From: cfe-dev <[hidden email]> on behalf of Troy Johnson via cfe-dev <[hidden email]>
Sent: Wednesday, September 18, 2019 4:26 PM
To: [hidden email] <[hidden email]>
Subject: [cfe-dev] unnecessary implicit instantiation?
 
Clang issues an error for the following code, whereas the GNU compiler does not.  Based on the standard, I think that an implicit instantiation should not occur because the compiler is not yet allocating an object, and that would mean that Clang is incorrectly issuing an error and GNU is correct to not issue any error.

Is my understanding correct?

> cat t.cpp
template <typename T> class A;

template <typename T>
struct B {
  static A<int> M;
};

template <typename T> A<int> B<T>::M;
> g++ -c t.cpp
> clang -c t.cpp
t.cpp:8:36: error: implicit instantiation of undefined template 'A<int>'
template <typename T> A<int> B<T>::M;
                                   ^
t.cpp:1:29: note: template is declared here
template <typename T> class A;
                            ^
1 warning and 1 error generated.


Thanks,
Troy
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev