C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Really nasty bug or feature?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Joerg Richter
Guest





PostPosted: Wed Sep 29, 2004 10:12 am    Post subject: Really nasty bug or feature? Reply with quote



Consider this code:

////////////////////////////////////////////////

template<typename T> class Foo {};
template<typename T> void func( Foo<T> const& );

template<class Val> class Bar
{
char a[sizeof(Val)];
};

struct undefined;
void func( Bar<undefined> const& );

struct Base
{};

int main()
{
func( Foo<Base>() );
}

////////////////////////////////////////////////

The call to func in main produces an error, that sizeof(undefinded) is
not possible. Two compilers agree. I have this vague feeling, that
this is ok with the standard. Can somebody confirm this please, that
"Bar<undefined>" must be instantiated, according to the standard?

From the real life code it was very hard to figure out what the
problem is.

The failing code looked like this (in)famous loop:
typedef std::vector<MyClass> MyVector;
MyVector vec;
....
for( MyVector::iterator it = vec.begin; it != vec.end(); ++it )
...

And the "it != vec.end()" part produced this error in a more than
unrelated file. I was curious how this can happen and reduced this
testcase above. (func was operator!=)

Lets assume this is ok with the standard. Then its perhaps an
overspecification. Can there be a definition of "Bar" that can change
the meaning of the call to "func()" in main?
I've found none.

So why must "Bar<undefined>" then be instantiated?


Joerg

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
David Abrahams
Guest





PostPosted: Thu Sep 30, 2004 10:35 am    Post subject: Re: Really nasty bug or feature? Reply with quote



[email]j_richter (AT) gmx (DOT) de[/email] (Joerg Richter) writes:

Quote:
So why must "Bar<undefined>" then be instantiated?

How does the compiler know there isn't a converting constructor from
Foo<Base> in Bar<undefined> otherwise? It can't really "look inside"
Bar<undefined> to find out without instantiating it.

HTH,
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Bob Hairgrove
Guest





PostPosted: Thu Sep 30, 2004 10:42 am    Post subject: Re: Really nasty bug or feature? Reply with quote



On 29 Sep 2004 06:12:26 -0400, [email]j_richter (AT) gmx (DOT) de[/email] (Joerg Richter) wrote:

Quote:
Consider this code:

////////////////////////////////////////////////

template<typename T> class Foo {};
template<typename T> void func( Foo<T> const& );

template<class Val> class Bar
{
char a[sizeof(Val)];
};

struct undefined;
void func( Bar<undefined> const& );

struct Base
{};

int main()
{
func( Foo<Base>() );
}

////////////////////////////////////////////////

The call to func in main produces an error, that sizeof(undefinded) is
not possible. Two compilers agree. I have this vague feeling, that
this is ok with the standard. Can somebody confirm this please, that
"Bar<undefined>" must be instantiated, according to the standard?

From the real life code it was very hard to figure out what the
problem is.

The failing code looked like this (in)famous loop:
typedef std::vector<MyClass> MyVector;
MyVector vec;
...
for( MyVector::iterator it = vec.begin; it != vec.end(); ++it )
...

And the "it != vec.end()" part produced this error in a more than
unrelated file. I was curious how this can happen and reduced this
testcase above. (func was operator!=)

Lets assume this is ok with the standard. Then its perhaps an
overspecification. Can there be a definition of "Bar" that can change
the meaning of the call to "func()" in main?
I've found none.

So why must "Bar<undefined>" then be instantiated?

An actual object doesn't have to be instantiated, but the class must
be defined in order for the compiler to calculate its size. The array
size must be a compile-time constant, and since "undefined" is
undefined, so is Bar<undefined>.

--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Alberto Barbati
Guest





PostPosted: Thu Sep 30, 2004 10:45 am    Post subject: Re: Really nasty bug or feature? Reply with quote

Joerg Richter wrote:
Quote:
Consider this code:

////////////////////////////////////////////////

template<typename T> class Foo {};
template<typename T> void func( Foo<T> const& );

template<class Val> class Bar
{
char a[sizeof(Val)];
};

struct undefined;
void func( Bar<undefined> const& );

struct Base
{};

int main()
{
func( Foo<Base>() );
}

////////////////////////////////////////////////

The call to func in main produces an error, that sizeof(undefinded) is
not possible. Two compilers agree. I have this vague feeling, that
this is ok with the standard. Can somebody confirm this please, that
"Bar<undefined>" must be instantiated, according to the standard?

I guess 14.7.1/5 is relevant here: "it is unspecified whether that

instantiation actually takes place". That is: an implementation can
instantiate the class template but it's not required to do so. It seems
that both the compiler you tested instantiate the template. This
behaviour is conforming.

Quote:
From the real life code it was very hard to figure out what the
problem is.

The failing code looked like this (in)famous loop:
typedef std::vector<MyClass> MyVector;
MyVector vec;
...
for( MyVector::iterator it = vec.begin; it != vec.end(); ++it )
...

And the "it != vec.end()" part produced this error in a more than
unrelated file. I was curious how this can happen and reduced this
testcase above. (func was operator!=)

Frankly I don't see how this problem is related with the previous
question. If even you don't know how this example can be reduced to the
testcase above, how could we?

However, I hope MyClass is a complete type up there, because it's
undefined behaviour to instantiate any standard library template using
an incomplete type (17.4.3.6/2).

Quote:
Lets assume this is ok with the standard. Then its perhaps an
overspecification. Can there be a definition of "Bar" that can change
the meaning of the call to "func()" in main?
I've found none.

So why must "Bar<undefined>" then be instantiated?


As I said, it's not required, but the compiler is allowed to do so. I
think that's not a big deal, however. In your example, function
func(Bar<undefined> const&) could never be called anyway so the compiler
is IMHO issueing a useful diagnostic. You shouldn't have declared that
function in the first place. I don't understand what use do you have for
doing that and what harm could come from the compiler's behaviour.
Perhaps you do?

Regards,

Alberto

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Hyman Rosen
Guest





PostPosted: Fri Oct 01, 2004 11:55 am    Post subject: Re: Really nasty bug or feature? Reply with quote

Joerg Richter wrote:
Quote:
So why must "Bar<undefined>" then be instantiated?

Because overload resolution will look for a conversion
from Foo<Base> to Bar<undefined> const&.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Joerg Richter
Guest





PostPosted: Fri Oct 01, 2004 4:11 pm    Post subject: Re: Really nasty bug or feature? Reply with quote

David Abrahams <dave (AT) boost-consulting (DOT) com> wrote in message

Quote:
So why must "Bar<undefined>" then be instantiated?

How does the compiler know there isn't a converting constructor from
Foo<Base> in Bar<undefined> otherwise? It can't really "look inside"
Bar<undefined> to find out without instantiating it.

Cause its already clear that the other function matches better.
14.7.1/5 has a little example close to mine.


Joerg

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Joerg Richter
Guest





PostPosted: Fri Oct 01, 2004 4:12 pm    Post subject: Re: Really nasty bug or feature? Reply with quote

Alberto Barbati <AlbertoBarbati (AT) libero (DOT) it> wrote in message

Quote:
I guess 14.7.1/5 is relevant here: "it is unspecified whether that
instantiation actually takes place". That is: an implementation can
instantiate the class template but it's not required to do so. It seems
that both the compiler you tested instantiate the template. This
behaviour is conforming.

Thanks for this paragraph. This is exactly I was looking for. So this
is a QOI issue.

Quote:
The failing code looked like this (in)famous loop:
typedef std::vector<MyClass> MyVector;
MyVector vec;
...
for( MyVector::iterator it = vec.begin; it != vec.end(); ++it )
...

And the "it != vec.end()" part produced this error in a more than
unrelated file. I was curious how this can happen and reduced this
testcase above. (func was operator!=)

Frankly I don't see how this problem is related with the previous
question. If even you don't know how this example can be reduced to the
testcase above, how could we?

Ok, perhaps I reduced it a little bit too much to remain
understandable.
I hope this makes the problem clearer:

//// goodheader.h ////////////

struct MyClass
{};

//// badheader.h /////////////

struct undefined;

template<class Val> class Bar
{
char a[sizeof(Val)]; // something to make the instantiation fail
};

bool operator!=( Bar<undefined> const&, Bar<undefined> const& );

//// main.cc /////////////////

#include "goodheader.h"
#include <vector>
#ifdef FAILURE
#include "badheader.h"
#endif

int main()
{
std::vector<MyClass> vec;
for( std::vector<MyClass>::iterator it = vec.begin();
it != vec.end(); // <- failing line
++it )
;
}

///// END ////////////////////

If you define FAILURE, it doesn't compile anymore, at lease on GCC
3.4.2. Comeau Online (4.3.3 BETA August 4, 2003) accept it, but not
the first example.

Quote:
However, I hope MyClass is a complete type up there, because it's
undefined behaviour to instantiate any standard library template using
an incomplete type (17.4.3.6/2).

This was not the relevant part. As you can see, MyClass is defined and
totally unrelated to "Bar" or "undefined".

Quote:
So why must "Bar

As I said, it's not required, but the compiler is allowed to do so. I
think that's not a big deal, however. In your example, function
func(Bar<undefined> const&) could never be called anyway so the compiler
is IMHO issueing a useful diagnostic.

If the function is never called I would prefer no diagnostic that the
instantiation of the function parameter types failed.

Quote:
You shouldn't have declared that
function in the first place. I don't understand what use do you have for
doing that and what harm could come from the compiler's behaviour.
Perhaps you do?

In my case the relevant operator!= will only be called, when
"undefined" is actually defined.
Its right, that this failure could be prevented in my case, when I had
moved the declaration of the operator!= to the definition of
"undefined". But it is hard to see this from the error message on a
totally unrelated line.

But perhaps its not worth it changing 14.7.1/5 to prevent unneeded
instantiations.


Joerg

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Tokyo Tomy
Guest





PostPosted: Fri Oct 01, 2004 4:53 pm    Post subject: Re: Really nasty bug or feature? Reply with quote

[email]j_richter (AT) gmx (DOT) de[/email] (Joerg Richter) wrote in message news:<59aed.0409280348.2cdc4e0e (AT) posting (DOT) google.com>...
Quote:
Consider this code:

////////////////////////////////////////////////

template<typename T> class Foo {};
template<typename T> void func( Foo<T> const& );

template<class Val> class Bar
{
char a[sizeof(Val)];
};

struct undefined;
void func( Bar<undefined> const& );

struct Base
{};

int main()
{
func( Foo<Base>() );
}

////////////////////////////////////////////////

The call to func in main produces an error, that sizeof(undefinded) is
not possible. Two compilers agree. I have this vague feeling, that
this is ok with the standard. Can somebody confirm this please, that
"Bar<undefined>" must be instantiated, according to the standard?

...

I am happy to correct my misconceptions through reading various posts.
This time, I have to correct my three misconceptions. Then I would
like to answer to the inquiry of the original poster.

I am glad to hear your comments, if any. Thank you in advance.

Misconception 1: The sizeof is a special operator which operand shall
be evaluated at compile time.
Misconception 2: The bound (number of elements) of array shall be
determined at compile time.
Misconception 3: The template class shall be instantiated before or
when it is necessary.

CORRECTION:
////////////////////////////
Misconception 1: The sizeof is a special operator which operand shall
be evaluated at compile time.
I cannot find any description about the evaluation timing of the
sizeof operand in the Standard. Instead, I found the following
description (5.3.3/1).
" The sizeof operator shall NOT be applied to an expression that
has function or *incomplete type*, or to an enumeration type before
all its enumerators have been declared, or to the parenthesized name
of such types, or to an lvalue that designates a bit-field."

The original code has a possibility of syntax error, because of
sizeof(incomplete type). However, you cannot say it bring about a
complier error.

Quote:
From the limitations above, posed on the sizeof operand, I think I can
say "The sizeof is a special operator which operand shall be

evaluatable at compile time."


Misconception 2: The bound (number of elements) of array shall be
determined at compile time.
This is also suggested by Bob Hairgrove. The "const expression" in
array[const expression] is a static initialization (3.6.2/1), and my
misconception seems to be not a misconception, but as the title of
§3.6.2 is "initialization of non-local objects", I have to say "The
bound(number of elements) of array shall be determined at compile
time, when the array is a non-local object".

Therefore, I cannot say the original code causes a compiler error of
this reason.


Misconception 3: The template class shall be instantiated before or
when it is necessary.
Dave Abrahams insists that the Bar<undefined> is necessary and
shall be instantiated.
The original poster, Joerg, doubts about the necessity, saying
Quote:
Can somebody confirm this please, that
"Bar<undefined>" must be instantiated, according to the standard?
Alberto thinks that it may not be necessary, but compliers are

allowed to instantiate the template class, according to §14.7.1/5 "it
is unspecified whether that instantiation actually takes place".

I am on the side of Alberto. I have to say " The template class shall
be instantiated before or when it is necessary, and is allowed to be
instantiated even in the case that it is not necessary for overload
resolution process of a function."


ANSWER:
/////////////////
Here is my answer to the inquiry of the original poster.
Compliers are allowed to insatiate Bar<undefined>, and in the process
of the instantiation, the syntax error will be occurred at char
a[sizeof(Val)];.

OTHER ISSUES:
////////////////////////////
Quote:
char a[sizeof(Val)];
I don't understand this code at all. This code says that number of

elements in array a is sizeof(Val).

Quote:
And the "it != vec.end()" part produced this error in a more than
unrelated file. I was curious how this can happen and reduced this
testcase above. (func was operator!=)
I don't understand how this is related to the problem, but I guess

that the concept of "extreme programming" will be a help.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Fri Oct 01, 2004 5:12 pm    Post subject: Re: Really nasty bug or feature? Reply with quote

[email]j_richter (AT) gmx (DOT) de[/email] (Joerg Richter) wrote in message
news:<59aed.0409280348.2cdc4e0e (AT) posting (DOT) google.com>...
Quote:
Consider this code:

////////////////////////////////////////////////

template<typename T> class Foo {};
template<typename T> void func( Foo<T> const& );

template<class Val> class Bar
{
char a[sizeof(Val)];
};

struct undefined;
void func( Bar<undefined> const& );

struct Base
{};

int main()
{
func( Foo<Base>() );
}

////////////////////////////////////////////////

The call to func in main produces an error, that sizeof(undefinded) is
not possible. Two compilers agree. I have this vague feeling, that
this is ok with the standard. Can somebody confirm this please, that
"Bar<undefined>" must be instantiated, according to the standard?

[...]
Quote:
Lets assume this is ok with the standard. Then its perhaps an
overspecification. Can there be a definition of "Bar" that can change
the meaning of the call to "func()" in main? I've found none.

You didn't look very hard. If Bar<undefined> has a constructor which
takes a single Foo<Base> as parameter, the call is legal and well
defined.

Quote:
So why must "Bar<undefined>" then be instantiated?

How else can the compiler know whether it can convert Foo<Base> into a
Bar<undefined>?

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Tokyo Tomy
Guest





PostPosted: Sun Oct 03, 2004 2:57 am    Post subject: Re: Really nasty bug or feature? Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote in message news:<d6652001.0409292341.75d0b243 (AT) posting (DOT) google.com>...
Quote:
j_richter (AT) gmx (DOT) de (Joerg Richter) wrote in message
news:<59aed.0409280348.2cdc4e0e (AT) posting (DOT) google.com>...
Consider this code:

////////////////////////////////////////////////

template<typename T> class Foo {};
template<typename T> void func( Foo<T> const& );

template<class Val> class Bar
{
char a[sizeof(Val)];
};

struct undefined;
void func( Bar<undefined> const& );

struct Base
{};

int main()
{
func( Foo<Base>() );
}

////////////////////////////////////////////////

The call to func in main produces an error, that sizeof(undefinded) is
not possible. Two compilers agree. I have this vague feeling, that
this is ok with the standard. Can somebody confirm this please, that
"Bar<undefined>" must be instantiated, according to the standard?

[...]
Lets assume this is ok with the standard. Then its perhaps an
overspecification. Can there be a definition of "Bar" that can change
the meaning of the call to "func()" in main? I've found none.

You didn't look very hard. If Bar<undefined> has a constructor which
takes a single Foo<Base> as parameter, the call is legal and well
defined.

So why must "Bar<undefined>" then be instantiated?

How else can the compiler know whether it can convert Foo<Base> into a
Bar<undefined>?

func( Foo<Base>() ) exactly matches with template<typename T> void
func( Foo<T> const& ). Then is it necessary to convert Foo<Base> into
Bar<undefined>?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Joerg Richter
Guest





PostPosted: Sun Oct 03, 2004 3:29 am    Post subject: Re: Really nasty bug or feature? Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote in message
Quote:
Lets assume this is ok with the standard. Then its perhaps an
overspecification. Can there be a definition of "Bar" that can change
the meaning of the call to "func()" in main? I've found none.

You didn't look very hard. If Bar<undefined> has a constructor which
takes a single Foo<Base> as parameter, the call is legal and well
defined.

This two declarations:
1. template<typename T> void func( Foo<T> const& );
2. void func( Bar<undefined> const& );

and this call:
func( Foo<Base>() );

Then converting constructors of Bar<> are not considered, because (1)
matches better than (2).

Joerg

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Frank Birbacher
Guest





PostPosted: Sun Oct 03, 2004 1:10 pm    Post subject: Re: Really nasty bug or feature? Reply with quote

Hi!

Joerg Richter wrote:
Quote:
This two declarations:
1. template<typename T> void func( Foo<T> const& );
2. void func( Bar<undefined> const& );

and this call:
func( Foo<Base>() );

Then converting constructors of Bar<> are not considered, because (1)
matches better than (2).

AFAIK, non-template functions are considered before any template
is instantiated. Thus if (2) can match, then don't consider any
of (1). But without instantiating Bar<undefined> the compiler
cannot know.

Frank


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Oct 04, 2004 7:25 pm    Post subject: Re: Really nasty bug or feature? Reply with quote

[email]j_richter (AT) gmx (DOT) de[/email] (Joerg Richter) wrote in message
news:<59aed.0410021006.65552dd7 (AT) posting (DOT) google.com>...
Quote:
kanze (AT) gabi-soft (DOT) fr wrote in message
Lets assume this is ok with the standard. Then its perhaps an
overspecification. Can there be a definition of "Bar" that can
change the meaning of the call to "func()" in main? I've found
none.

You didn't look very hard. If Bar<undefined> has a constructor
which takes a single Foo<Base> as parameter, the call is legal and
well defined.

This two declarations:
1. template<typename T> void func( Foo<T> const& );
2. void func( Bar<undefined> const& );

and this call:
func( Foo<Base>() );

Then converting constructors of Bar<> are not considered, because (1)
matches better than (2).

I missed the template function:-). However, in order to know that (1)
will be a better match, the compiler will typically have to try (2); the
first step in overload resolution is to create a set of viable
functions.

Another poster has already pointed out that there is a special exception
which does allow the compiler not to instantiate it if no possible
instantiation could be a best match (which would be the case here).
From what little I know of compilers, however, I suspect that this
optimization is not trivial.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Oct 04, 2004 7:27 pm    Post subject: Re: Really nasty bug or feature? Reply with quote

[email]hosoda (AT) jtec (DOT) or.jp[/email] (Tokyo Tomy) wrote in message
news:<49c1da0b.0410010023.6ea869e4 (AT) posting (DOT) google.com>...
Quote:
j_richter (AT) gmx (DOT) de (Joerg Richter) wrote in message
news:<59aed.0409280348.2cdc4e0e (AT) posting (DOT) google.com>...
Consider this code:

////////////////////////////////////////////////

template<typename T> class Foo {};
template<typename T> void func( Foo<T> const& );

template<class Val> class Bar
{
char a[sizeof(Val)];
};

struct undefined;
void func( Bar<undefined> const& );

struct Base
{};

int main()
{
func( Foo<Base>() );
}

////////////////////////////////////////////////

The call to func in main produces an error, that sizeof(undefinded)
is not possible. Two compilers agree. I have this vague feeling,
that this is ok with the standard. Can somebody confirm this please,
that "Bar<undefined>" must be instantiated, according to the
standard?

...

I am happy to correct my misconceptions through reading various posts.
This time, I have to correct my three misconceptions. Then I would
like to answer to the inquiry of the original poster.

I am glad to hear your comments, if any. Thank you in advance.

Misconception 1: The sizeof is a special operator which operand shall
be evaluated at compile time.
Misconception 2: The bound (number of elements) of array shall be
determined at compile time.
Misconception 3: The template class shall be instantiated before or
when it is necessary.

CORRECTION:
////////////////////////////
Misconception 1: The sizeof is a special operator which operand shall
be evaluated at compile time.
I cannot find any description about the evaluation timing of the
sizeof operand in the Standard. Instead, I found the following
description (5.3.3/1).
" The sizeof operator shall NOT be applied to an expression that
has function or *incomplete type*, or to an enumeration type before
all its enumerators have been declared, or to the parenthesized name
of such types, or to an lvalue that designates a bit-field."

§5.19 says that sizeof can be used in an integral constant expression,
which pretty much means that it must be evaluated at compile time.

Quote:
The original code has a possibility of syntax error, because of
sizeof(incomplete type). However, you cannot say it bring about a
complier error.

Syntax errors require a compiler diagnostic. Once the diagnostic is
emmitted, of course, the compiler can do whatever it wants: refuse to
generate any object code, generate arbitrary object code, or thrash your
hard disk. Most compilers today choose the first alternative.

Quote:
From the limitations above, posed on the sizeof operand, I think I
can say "The sizeof is a special operator which operand shall be
evaluatable at compile time."

Misconception 2: The bound (number of elements) of array shall be
determined at compile time.
This is also suggested by Bob Hairgrove. The "const expression" in
array[const expression] is a static initialization (3.6.2/1), and my
misconception seems to be not a misconception, but as the title of
§3.6.2 is "initialization of non-local objects", I have to say "The
bound(number of elements) of array shall be determined at compile
time, when the array is a non-local object".

The size of an array has nothing to do with initialization. The const
expression in the [] must be an integral constant expression, as defined
in §5.19.

Quote:
Therefore, I cannot say the original code causes a compiler error of
this reason.

The standard says it does. (At least if the compiler tries to
instantiate Bar<undefined>.)

Quote:
Misconception 3: The template class shall be instantiated before or
when it is necessary.
Dave Abrahams insists that the Bar<undefined> is necessary and
shall be instantiated.
The original poster, Joerg, doubts about the necessity, saying
Can somebody confirm this please, that
"Bar<undefined>" must be instantiated, according to the standard?
Alberto thinks that it may not be necessary, but compliers are
allowed to instantiate the template class, according to §14.7.1/5 "it
is unspecified whether that instantiation actually takes place".

I am on the side of Alberto. I have to say " The template class shall
be instantiated before or when it is necessary, and is allowed to be
instantiated even in the case that it is not necessary for overload
resolution process of a function."

In theory, the standard allows compilers to skip the instantiation,
since it theory, it is possible to determine that the function in
question could not possible be called. In practice, given the way
overload resolution is defined, I expect that most compilers will
instantiate it.

Quote:
ANSWER:
/////////////////
Here is my answer to the inquiry of the original poster.
Compliers are allowed to insatiate Bar<undefined>, and in the process
of the instantiation, the syntax error will be occurred at char
a[sizeof(Val)];.

OTHER ISSUES:
////////////////////////////
char a[sizeof(Val)];
I don't understand this code at all. This code says that number of
elements in array a is sizeof(Val).

That's exactly what it says. So what don't you understand about it?

The technique is the usual one for getting raw memory of the correct
size. Except that in general, the array is declared within a union with
some other types (double, for example) in order to (hopefully) ensure
correct alignment.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Oct 04, 2004 7:29 pm    Post subject: Re: Really nasty bug or feature? Reply with quote

Frank Birbacher <bloodymir.crap (AT) gmx (DOT) net> wrote


Quote:
Joerg Richter wrote:
This two declarations:
1. template<typename T> void func( Foo<T> const& );
2. void func( Bar<undefined> const& );

and this call:
func( Foo<Base>() );

Then converting constructors of Bar<> are not considered, because
(1) matches better than (2).

AFAIK, non-template functions are considered before any template is
instantiated.

That used to be the case, at least with some compilers, but I don't
think that that is what the standard finally required.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.