By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,269 Members | 1,506 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,269 IT Pros & Developers. It's quick & easy.

Compilation sequence - a feature or bug

P: n/a
Hi

There is an example of the code below (mostly written by P. Bindels).
In that example is strongly highlighted that very important is the
sequence
of compiled code. In C++ could be assume that such a sequence exists.
But the question is if it is a feature or it is a bug?
Especially in the scope of that example we could observe that
templates
can be somehow separated from its specializations.

Best regards.

#include <iostream>

template <class A>
class T {
A a;
};

class is_original_version_of_template
{
public:
static bool const value;
};

bool const is_original_version_of_template::value
(sizeof(T<void *>) == sizeof(T<void *>));

template <class A>
class T<A *{
A *a[10];
};

class is_not_original_version_of_template // specialized
{
public:
static bool const value;
};

bool const is_not_original_version_of_template::value
(sizeof(T<void *>) == is_original_version_of_template::value);

int main()
{
std::cout << "is_original_version_of_template "
<< is_original_version_of_template::value << '\n';

std::cout << "is_not_original_version_of_template "
<< is_not_original_version_of_template::value << '\n';
}

Jun 23 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Seweryn Habdank-Wojewódzki wrote:
Hi

There is an example of the code below (mostly written by P. Bindels).
In that example is strongly highlighted that very important is the
sequence
of compiled code. In C++ could be assume that such a sequence exists.
But the question is if it is a feature or it is a bug?
Especially in the scope of that example we could observe that
templates
can be somehow separated from its specializations.
There are definite rules for the template argument resolution. Well,
actually it's a little it complex stuff, but the common-sense rule
applies the most of the times. That is, in this situation, if you want
to use a specialisation, the definition of the specialisation has to be
visible in every place in which you instantiate the templates that
whould be specialised.
#include <iostream>

template <class A>
class T {
A a;
};

class is_original_version_of_template
{
public:
static bool const value;
};
I can't understand the meaning of this code...
bool const is_original_version_of_template::value
(sizeof(T<void *>) == sizeof(T<void *>));
This is always true...
template <class A>
class T<A *{
A *a[10];
};
Ah, that's bad. The standard (14.3.3#2) says:
Any partial specializations (14.5.4) associated with the primary class
template are considered when a specialization based on the template
template parameter is instantiated. If a specialization is not visible
at the point of instantiation, and it would have been selected had it
been visible, the program is ill-formed; no diagnostic is required.
This applies in your case.
class is_not_original_version_of_template // specialized
{
public:
static bool const value;
};

bool const is_not_original_version_of_template::value
(sizeof(T<void *>) == is_original_version_of_template::value);
Here you are comparing a size_type with a bool (that is always true).
It makes no sense.

Regards,

Zeppe
Jun 24 '07 #2

P: n/a
Hi!

Thanks for the reply.
Ah, that's bad. The standard (14.3.3#2) says:
Any partial specializations (14.5.4) associated with the primary class
template are considered when a specialization based on the template
template parameter is instantiated. If a specialization is not visible
at the point of instantiation, and it would have been selected had it
been visible, the program is ill-formed; no diagnostic is required.
This applies in your case.
Yes I understand. But I am looking if something is useful in that
case. I have another example of such a code. When I am blocking one
particular specialisation by using explicit instantiation before more
general specialisation. In the code calling "T<int*, double*>::value;"
will cause compilation error.

Regards.
#include <iostream>
#include <boost/static_assert.hpp>

template <class A, class B>
class T {};

template class T<int*, double*>;

template <class A, class B>
struct T<A *, B{
A a[10];
B * b[7];
enum { value = sizeof(A*[10]) + sizeof(B*[7]) };
};

template <typename A, typename B>
struct Func { enum { value = (sizeof(T<A,B>) == 1) }; };

int main()
{
using std::cout;
//T<int*, double*>::value;
int const b = T<int*,double>::value;
int const a = T<double*,int>::value;
int const c = Func<int*,double*>::value;
BOOST_STATIC_ASSERT (c == 1);
int const d = Func<int*,double>::value;
BOOST_STATIC_ASSERT (d != 1);
cout << b << ' ' << a << ' ' << c << ' ' << d << '\n';
return a;
}

Jun 25 '07 #3

P: n/a
Seweryn Habdank-Wojewódzki wrote:
Hi!

Thanks for the reply.
>Ah, that's bad. The standard (14.3.3#2) says:
Any partial specializations (14.5.4) associated with the primary class
template are considered when a specialization based on the template
template parameter is instantiated. If a specialization is not visible
at the point of instantiation, and it would have been selected had it
been visible, the program is ill-formed; no diagnostic is required.
This applies in your case.

Yes I understand. But I am looking if something is useful in that
case.
Sorry, I;ve quoted the wrong piece of standard. The correct one is in
14.5.4#1:
If a template is partially specialized then that partial specialization
shall be declared before the first use of that partial specialization
that would cause an implicit instantiation to take place, in every
translation unit in which such a use occurs; no diagnostic is required.

It's quite different, and it seems to allow your example. But 14.6.4.1#7
tells:
A specialization for any template may have points of instantiation in
multiple translation units. If two different points of instantiation
give a template specialization different meanings according to the one
definition rule (3.2), the program is ill-formed, no diagnostic required.

In my opinion, this means that as long as you make sure that the
particular specialisation is explicitly instantiated *before* the
definition of the general specialization in all the translation units in
which it is used, it should be fine.
I have another example of such a code. When I am blocking one
particular specialisation by using explicit instantiation before more
general specialisation. In the code calling "T<int*, double*>::value;"
will cause compilation error.
I think it's fine, according to the standard paragraphs that I cited.

Regards,

Zeppe

Jun 25 '07 #4

P: n/a
Hi

On 26 Cze, 01:29, Zeppe <z...@remove.all.this.long.comment.email.it>
wrote:
Sorry, I;ve quoted the wrong piece of standard. The correct one is in
14.5.4#1:
If a template is partially specialized then that partial specialization
shall be declared before the first use
The question is if e.g. instantiation is a use of template or not.

so the case when you will have:

template <typename T>
class A {};

template class A<void*>; // this is use or not.

template <typename T>
class A<T*{};
of that partial specialization
that would cause an implicit instantiation to take place, in every
translation unit in which such a use occurs; no diagnostic is required.
Regards.
Jun 26 '07 #5

P: n/a
Seweryn Habdank-Wojewódzki wrote:
Hi

On 26 Cze, 01:29, Zeppe <z...@remove.all.this.long.comment.email.it>
wrote:
>Sorry, I;ve quoted the wrong piece of standard. The correct one is in
14.5.4#1:
If a template is partially specialized then that partial specialization
shall be declared before the first use

The question is if e.g. instantiation is a use of template or not.
What do you mean as "use of template"?
>
so the case when you will have:

template <typename T>
class A {};

template class A<void*>; // this is use or not.
This one is an explicit template instantiation. It forces the template
class A to be inst\0ntiated with the paramater T = void*.

Regards,

Zeppe
Jun 26 '07 #6

P: n/a
Zeppe wrote:
Seweryn Habdank-Wojewódzki wrote:
>Hi

On 26 Cze, 01:29, Zeppe <z...@remove.all.this.long.comment.email.it>
wrote:
>>Sorry, I;ve quoted the wrong piece of standard. The correct one is
in 14.5.4#1:
If a template is partially specialized then that partial
specialization shall be declared before the first use

The question is if e.g. instantiation is a use of template or not.

What do you mean as "use of template"?
My guess is the OP means whatever the Standard means. The question
is, essentially, what the heck is the "use" in 14.5.4?
>so the case when you will have:

template <typename T>
class A {};

template class A<void*>; // this is use or not.

This one is an explicit template instantiation. It forces the template
class A to be instantiated with the paramater T = void*.
But is it a "use", in terms of the Standard?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 26 '07 #7

P: n/a
Victor Bazarov wrote:
Zeppe wrote:
>Seweryn Habdank-Wojewódzki wrote:
>>Hi

On 26 Cze, 01:29, Zeppe <z...@remove.all.this.long.comment.email.it>
wrote:
Sorry, I;ve quoted the wrong piece of standard. The correct one is
in 14.5.4#1:
If a template is partially specialized then that partial
specialization shall be declared before the first use
The question is if e.g. instantiation is a use of template or not.
What do you mean as "use of template"?

My guess is the OP means whatever the Standard means. The question
is, essentially, what the heck is the "use" in 14.5.4?
>>so the case when you will have:

template <typename T>
class A {};

template class A<void*>; // this is use or not.
This one is an explicit template instantiation. It forces the template
class A to be instantiated with the paramater T = void*.

But is it a "use", in terms of the Standard?
Well, I guess yes. I think that according to the standard, you can "use"
different versions (specializations) of the template. So, each time a
template must be matched, a version (the most of the time, the most
matching according to the template matching rules) will be "used".

Having said so, the standard tells in 14.5.4 that if a template is
partially specialised (that is, a partial specialisation exists in the
program) then this partial specialisation has to be declared before the
first "use" of the specialisation that would cause an implicit
instantiation to take place. Which mean that *if* there is an
instruction that "use" the specialisation (that means, that imply that
version of the template to be considered for that piece of code) *and*
this instruction _imply_ the implicit instantiation of the
specialisation (that is, a more specialised version of the general
template has not yet been explicitly, or even implicitly maybe (I have
to check), instantiated), *then* the specialisation has to come before
that instruction (obviously). And, additionally, this has to happen
consistently in the whole program.

This is IMHO.

Regards,

Zeppe
Jun 28 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.