 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Carlos Moreno Guest
|
Posted: Tue Aug 30, 2005 10:26 pm Post subject: Valarray bug in g++ 4.0.1 ? |
|
|
Hi,
I believe I understand why the following compiler error happens;
but wouldn't this be a bug in the valarray implementation? (more
specifically, in the expression templates part?)
The test program is:
#include <iostream>
#include <valarray>
using namespace std;
template <typename T>
int blah (const valarray<T> & x)
{
return x.size();
}
int main()
{
valarray<double> x (10,10);
cout << blah(abs(x)) << endl;
return 0;
}
The compiler reports that there is no matching function for
blah (std::_Expr< .... )
If I make blah a non-template function (with aan argument
const valarray
I'm not sure if the standard specifies this, though I find it
unlikely -- expression templates seem to me like an implementation
detail; all the overloaded ctors and assignment operators should
be there to respect the semantics of valarray.
abs(valarray) returns a valarray according to TC++PL3; so, any
"proxy" object returned should be transparently equivalent to a
valarray object in every possible situation, is it not?
The workaround is relatively trivial, but I wonder if I'm
misunderstanding the rules -- the way I see it, it seems like
a bug in the implementation.
Thanks for any comments,
Carlos
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Wed Aug 31, 2005 8:39 am Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
Carlos Moreno <moreno_at_mochima_dot_com (AT) xx (DOT) xxx> writes:
| Quote: | Hi,
I believe I understand why the following compiler error happens;
but wouldn't this be a bug in the valarray implementation? (more
specifically, in the expression templates part?)
|
The code as you posted does not demonstrate a bug in the
implementation, nor in the compiler in that respect. The valarray
component was specified to have a "loosened return type".
26.3.1/3
Any function returning a valarray<T> is permitted to return an
object of another type, provided all the const member functions of
valarray<T> are also applicable to this type. This return type
shall not add more than two levels of template nesting over the
most deeply nested argument type.
[...]
| Quote: | If I make blah a non-template function (with aan argument
const valarray<double> & ), then it compiles.
|
That is because template argument deduction makes room for little or
no implicit conversion, consequently the "ordinary implicit
conversion" does not apply. If your function is non-template, then
the ordinary implicit conversion will happen as you observed. Yes, it
is confusing.
| Quote: | I'm not sure if the standard specifies this, though I find it
unlikely -- expression templates seem to me like an implementation
detail;
|
that is what was thought before we gained more experience and insight
into templates. Sadly, expression templates are not implementation
detail in the current specification of templates.
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Marc Mutz Guest
|
Posted: Wed Aug 31, 2005 8:41 am Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
Carlos Moreno wrote:
<snip>
| Quote: | The compiler reports that there is no matching function
for blah (std::_Expr< .... )
If I make blah a non-template function (with aan
argument const valarray
snip |
Template arguments are not subject to implicit type
conversion. Thus, in the non-template blah, the compiler
considers the implicit conversion from the expression
template construct to the result valarray, while in the
template blah, it doesn't. Since you don't pass a
valarray<T>, overload resultion fails.
You can work around that by writing
template <typename T_container>
typename T_container::size_type
blah( const T_container & x ) {
return x.size();
}
Marc
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gene Bushuyev Guest
|
Posted: Wed Aug 31, 2005 8:42 am Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
"Carlos Moreno" <moreno_at_mochima_dot_com (AT) xx (DOT) xxx> wrote
....
| Quote: | The test program is:
#include <iostream
#include
using namespace std;
template
int blah (const valarray
{
return x.size();
}
int main()
{
valarray<double> x (10,10);
cout << blah(abs(x)) << endl;
return 0;
}
The compiler reports that there is no matching function for
blah (std::_Expr< .... )
|
Just a compiler bug. There is nothing that prevents compiler from deducing
template parameter. You can check out EDG front-end here:
http://www.dinkumware.com/exam/dinkumExam.aspx which is pretty standard
compliant.
By the way VC7.1 also compiles the test without problems, though the web test
produces a wacky warning message.
- gene
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ron House Guest
|
Posted: Wed Aug 31, 2005 8:45 am Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
Carlos Moreno wrote:
| Quote: | Hi,
I believe I understand why the following compiler error happens;
but wouldn't this be a bug in the valarray implementation? (more
specifically, in the expression templates part?)
The test program is:
#include <iostream
#include
using namespace std;
template
int blah (const valarray
{
return x.size();
}
int main()
{
valarray<double> x (10,10);
cout << blah(abs(x)) << endl;
|
This works:
cout << blah(static_cast(abs(x))) << endl;
| Quote: |
return 0;
}
The compiler reports that there is no matching function for
blah (std::_Expr< .... )
If I make blah a non-template function (with aan argument
const valarray
I'm not sure if the standard specifies this, though I find it
unlikely -- expression templates seem to me like an implementation
detail; all the overloaded ctors and assignment operators should
be there to respect the semantics of valarray.
abs(valarray) returns a valarray according to TC++PL3; so, any
"proxy" object returned should be transparently equivalent to a
valarray object in every possible situation, is it not?
The workaround is relatively trivial, but I wonder if I'm
misunderstanding the rules -- the way I see it, it seems like
a bug in the implementation.
|
--
Ron House [email]house (AT) usq (DOT) edu.au[/email]
http://www.sci.usq.edu.au/staff/house
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Daniel Krügler Guest
|
Posted: Wed Aug 31, 2005 9:37 am Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
Carlos Moreno wrote:
| Quote: | I believe I understand why the following compiler error happens;
but wouldn't this be a bug in the valarray implementation? (more
specifically, in the expression templates part?)
The test program is:
#include <iostream
#include
using namespace std;
template
int blah (const valarray
{
return x.size();
}
int main()
{
valarray<double> x (10,10);
cout << blah(abs(x)) << endl;
return 0;
}
The compiler reports that there is no matching function for
blah (std::_Expr< .... )
If I make blah a non-template function (with aan argument
const valarray
I'm not sure if the standard specifies this, though I find it
unlikely -- expression templates seem to me like an implementation
detail; all the overloaded ctors and assignment operators should
be there to respect the semantics of valarray.
abs(valarray) returns a valarray according to TC++PL3; so, any
"proxy" object returned should be transparently equivalent to a
valarray object in every possible situation, is it not?
The workaround is relatively trivial, but I wonder if I'm
misunderstanding the rules -- the way I see it, it seems like
a bug in the implementation.
|
I can add the following piece of information: My mingw compiler, with
gcc 3.4 has the same problem with your example program.
To my opinion it looks like an defect in the implementation, 26.3.1
presents the function signature as:
template<class T> valarray<T> abs (const valarray<T>&);
This is repeated in 26.3.3.3 valarray transcendentals.
Greetings from Bremen,
Daniel Krügler
[ 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
|
Posted: Wed Aug 31, 2005 9:41 am Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
Gene Bushuyev wrote:
| Quote: | "Carlos Moreno" <moreno_at_mochima_dot_com (AT) xx (DOT) xxx> wrote in message
news:q92Re.55114$A%2.692907 (AT) weber (DOT) videotron.net...
...
The test program is:
#include <iostream
#include
using namespace std;
template
int blah (const valarray
{
return x.size();
}
int main()
{
valarray<double> x (10,10);
cout << blah(abs(x)) << endl;
return 0;
}
The compiler reports that there is no matching function for
blah (std::_Expr< .... )
Just a compiler bug. There is nothing that prevents compiler
from deducing template parameter.
|
Provided the return type of abs(x) is really cv valarray
Gabriel Dos Reis has pointed out, the standard explicitly says
that this is not required.
| Quote: | You can check out EDG front-end here:
http://www.dinkumware.com/exam/dinkumExam.aspx which is pretty
standard compliant. By the way VC7.1 also compiles the test
without problems, though the web test produces a wacky warning
message.
|
Whether the code compiles or not (supposing a correct compiler)
depends on the implementation of valarray. The code will
compile with a naïve and straightforeward implementation of
valarray. As I understand it, however, the whole idea behind
valarray is for the implementation to use all sorts of
meta-programming tricks to improve speed. Given this, I rather
suspect that the fact that the code compiles is almost an
indication that the quality of implementation of valarray isn't
as good as it could be. (For various reasons: some
implementations doubtlessly avoid getting too tricky because
they have to be compiled with compilers which don't, or didn't
have sufficient template support for the trickiness.
Potentially, too, a compiler could optimize so well that the
trickiness wasn't necessary, although that's certainly not the
case for most current compilers.)
--
James Kanze GABI Software
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 |
|
 |
Gabriel Dos Reis Guest
|
Posted: Wed Aug 31, 2005 10:39 am Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
"Gene Bushuyev" <spam (AT) spamguard (DOT) com> writes:
[...]
| Quote: | The compiler reports that there is no matching function for
blah (std::_Expr< .... )
Just a compiler bug.
|
Wrong. See my other message.
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Wed Aug 31, 2005 10:42 am Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
Gabriel Dos Reis wrote:
| Quote: | Carlos Moreno <moreno_at_mochima_dot_com (AT) xx (DOT) xxx> writes:
| I'm not sure if the standard specifies this, though I find it
| unlikely -- expression templates seem to me like an implementation
| detail;
that is what was thought before we gained more experience and insight
into templates. Sadly, expression templates are not implementation
detail in the current specification of templates.
|
How about this solution to the OP's problem:
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
template <typename T>
typename boost::enable_if<boost::is_convertible, std::size_t>::type
blah(T const& x) { return x.size(); }
It compiles with gcc 3.4.4.
However, it is not clear to me if it is mandatory for an implementation
to provide a value_type member in the proxy class it returns instead
of std::valarray. The above code would break without it.
Falk
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Daniel Krügler Guest
|
Posted: Wed Aug 31, 2005 11:29 am Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
Daniel Krügler wrote:
| Quote: | To my opinion it looks like an defect in the implementation, 26.3.1
presents the function signature as:
template<class T> valarray<T> abs (const valarray<T>&);
This is repeated in 26.3.3.3 valarray transcendentals.
|
Obviously this conclusion was wrong - I should have read the complete
valarray introductory part.
It would have been nice, if the documented signature (in the standard)
would have some better annotation like:
template<class T> valarray_impl<T> abs (const valarray<T>&);
where valarray_impl is in italics and a short explanation what
valarray_impl stands for, i.e. either valarray itself or its replacement
type.
Greetings,
Daniel
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Wed Aug 31, 2005 11:30 am Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
Falk Tannhäuser <clcppm-poster (AT) this (DOT) is.invalid> writes:
| Quote: | Gabriel Dos Reis wrote:
Carlos Moreno <moreno_at_mochima_dot_com (AT) xx (DOT) xxx> writes:
| I'm not sure if the standard specifies this, though I find it
| unlikely -- expression templates seem to me like an implementation
| detail;
that is what was thought before we gained more experience and insight
into templates. Sadly, expression templates are not implementation
detail in the current specification of templates.
How about this solution to the OP's problem:
#include <boost/type_traits/is_convertible.hpp
#include
template
typename boost::enable_if, std::size_t>::type
blah(T const& x) { return x.size(); }
It compiles with gcc 3.4.4.
However, it is not clear to me if it is mandatory for an implementation
to provide a value_type member in the proxy class it returns instead
of std::valarray. The above code would break without it.
|
Indeed. When the GNU implementation of valarray was made, it was felt
that value_type was something to have in the proxy classes, though I
cannot find any wording in the C++ standard for that.
In general, I'm always reluctant to resort to or recommend "enable-if"
trickeries.
I tried some time ago to explain the gap between what was intended
(from practice in other languages that supports SIMD-like array
processing) and the actual specification.
http://groups.google.com/group/comp.std.c++/msg/afeb3dc8e0579d74?dmode=source&hl=en
I hope C++0x will shorten the gap.
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carlos Moreno Guest
|
Posted: Wed Aug 31, 2005 2:52 pm Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
Gabriel Dos Reis wrote:
| Quote: | The code as you posted does not demonstrate a bug in the
implementation, nor in the compiler in that respect. The valarray
component was specified to have a "loosened return type".
26.3.1/3
Any function returning a valarray<T> is permitted to return an
object of another type, provided all the const member functions of
valarray<T> are also applicable to this type. This return type
shall not add more than two levels of template nesting over the
most deeply nested argument type.
[...]
| If I make blah a non-template function (with aan argument
| const valarray<double> & ), then it compiles.
That is because template argument deduction makes room for little or
no implicit conversion, consequently the "ordinary implicit
conversion" does not apply. If your function is non-template, then
the ordinary implicit conversion will happen as you observed. Yes, it
is confusing.
|
Well, at least my understanding about why it was happening was ok.
Yes, it was confusing but this was exactly my conclusion -- now, given
the *what* exactly was happening, I was under the mistaken impression
that such "loophole" had to be a bug in the implementation; I now see
that it seems more like a loophole in the standard -- it simply feels
wrong that the test program I posted doesn't compile (though yes, I
understand and sympathize with James' comment that, ironically, the
fact that it compiles is a sign that the valarray implementation may
not be too good/efficient)
It just feels wrong that a proxy object being returned posing as a
valarray is not *transparently* equivalent to a valarray *in every
possible situation* allowed by the language.
Anyway, I guess one more to the list of rough/obscure corners of
the language :-)
BTW, where is min(valarray) defined? Before posting my initial
message, I was using min instead of my own blah function, just to
discover that the compiler *really* could not find min(valarray)
(as opposed to not finding min(std::_Expr< ... >) ). I tried
#including <numeric>, <algorithm>, without success (TC++PL3 does
not mention any special #include for those, so I assumed they would
be provided as part of the <valarray> #include ? )
Thanks,
Carlos
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
P.J. Plauger Guest
|
Posted: Wed Aug 31, 2005 2:56 pm Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
<kanze (AT) gabi-soft (DOT) fr> wrote
| Quote: | Whether the code compiles or not (supposing a correct compiler)
depends on the implementation of valarray. The code will
compile with a naïve and straightforeward implementation of
valarray. As I understand it, however, the whole idea behind
valarray is for the implementation to use all sorts of
meta-programming tricks to improve speed.
|
Actually, the *original* intention was for valarray to serve as
a hook for compiler writers who wanted to do back-end tricks,
like vectorizing loops. By the time the template metaprogrammers
rose up in force, the original sponsors of valarray had abandoned
it. But it got added to the C++ Standard anyway...
If valarray has become a playground for TMP, it's mostly because
few people care what happens to it.
| Quote: | Given this, I rather
suspect that the fact that the code compiles is almost an
indication that the quality of implementation of valarray isn't
as good as it could be. (For various reasons: some
implementations doubtlessly avoid getting too tricky because
they have to be compiled with compilers which don't, or didn't
have sufficient template support for the trickiness.
Potentially, too, a compiler could optimize so well that the
trickiness wasn't necessary, although that's certainly not the
case for most current compilers.)
|
We took the simple approach in the Dinkumware library, partly
because compilers were buggier when we wrote valarray (over a
decade ago). But we keep it that way because simplicity seems
to give the best combination of performance and reliability for
our customers.
P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Wed Aug 31, 2005 9:02 pm Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
Carlos Moreno <moreno_at_mochima_dot_com (AT) xx (DOT) xxx> writes:
| Quote: | BTW, where is min(valarray) defined?
|
I don't think there is min(valarray). There is, however, valarray<T>::min.
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carlos Moreno Guest
|
Posted: Thu Sep 01, 2005 9:14 am Post subject: Re: Valarray bug in g++ 4.0.1 ? |
|
|
Gabriel Dos Reis wrote:
| Quote: | Carlos Moreno <moreno_at_mochima_dot_com (AT) xx (DOT) xxx> writes:
| BTW, where is min(valarray) defined?
I don't think there is min(valarray). There is, however, valarray<T>::min.
|
Huh?
The C++ Programming Language, 3rd Edition, page 667, section 22.4.4
Nonmember operations
(...)
template <class T> T min (const valarray<T> &); // smallest value
template <class T> T max (const valarray<T> &); // largest value
(...)
However, he does not mention valarray<>::min or max in section 22.4.3
(Member operations).
Is that information incorrect? (has the standard changed on this,
or was it perhaps an oversight from B.Stroustrup in his book?)
Carlos
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
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
|
|