Re: Compile Time String processing
On Feb 27, 12:21 am, Walter Bright <wal...@digitalmars-nospamm.com>
wrote:
James Kanze wrote:
On Feb 26, 9:37 am, Walter Bright <wal...@digitalmars-nospamm.com>
Why should a template binary (or the floating point part of a mangled
name) be portable between platforms?
Why should anything be portable?
Binaries aren't portable between platforms, anyway. I don't know any
example of portable C++ binaries between Windows x86 and Linux x86 -
even a trivial one. The C++ standard doesn't specify anything beyond
source portability. So, such is not a valid reason for disallowing
floating point template arguments.
You're the one who mentionned binaries. The problem is
semantics. C++ normally gives a limited set of legal semantics
to a legal program.
Traditionally, C (and C++) have underspecified floating point
arithmetic, leaving it largely a quality of implementation
issue. With a few precautions, however, programmers could write
code which gave roughly the same results on different platforms,
in practice, anyway. (Note the "roughly", however.) In many
contexts, in order to do this, one avoided testing for equality.
By allowing floating point arguments to templates, you have an
implicit equality test, executed on the host (compiling)
machine, not on the target. The results are binary: either two
instantiations of a template are the same type, or they're not.
Note that whether the results of two floating point expressions
compares equal with g++, on an Intel, sometimes depends on the
level of optimization. In cases where this causes a problem in
non-template code, I write my tests differently, taking a delta
into account, using < instead of ==, etc. If this occurs in a
template argument, however, I don't have any choice.
I'm not saying that it can't be done. Just that there are some
non trivial problems which have to be addressed.
The problem here has nothing to do with mangled names or
whatever. The question is whether two different instantiations
of a template are the same type or not. The standard requires,
for example, that given "template<int i> struct foo{};",
"foo<1>" and "foo<2-1>" have the same type. Defining when two
such instantiations have the same type is much, much harder for
floating point.
Just specify they must match exactly to the full precision of the type,
Which varies depending on the implementation, and in some cases
(g++ on Intel, for example), the optimization or the context of
the expression.
like the == operator does for floats (and the standard has no problem
defining ==).
Except that I have no problems avoiding that operator in cases
where it causes problems. And the standard doesn't really
definite that well, either, since something like f() == g()
(where f() and g() return double) may give different results
depending on the optimization, or even in some cases,
surrounding context. (There was a case in this forum recently
where some one was having problems with std::set because he'd
defined the ordering function along the lines of f(a) < f(b),
and it was returning true when a and b were equal, even if the
order of the arguments was swapped.)
And of course, the standard does expect == to be evaluated in
the run-time environment. Which isn't necessarily available (at
present, at least) in the compiler.
Maybe it's acceptable to just say
"unspecified". Maybe not. Maybe we know the answer today. We
certainly didn't back in the 1990's, however, when the standard
was being formulated.
As the usage of floating template arguments in the D programming
language illustrates, it simply isn't a problem.
Or you haven't recognized it as a problem. Or nobody is
actually using it, so the problems haven't been seen.
The fact that it does exist in D is a good starting point
(provided that D's templates work something like those in C++,
or course). It doesn't prove anything per se, but it allows us
to at least start collecting some concrete data---a necessary
first step. (To tell the truth, I'm rather surprised that some
C++ compiler implementator hasn't offered it as an extension.
It's an obvious extension, and except in the case of cross
compilers, an experimental, first-draft implementation shouldn't
be that difficult.)
For starters, the two places where I see the most likelyhood of
difficulty is in cases of extended precision, and with
cross-compilers. Do you have any experience with
cross-compiling in D? And you certainly have experience with
extended precision, since I know you support Intel. What steps
do you take there: always ensure that the parameter is written
to memory (with the correct type) before comparing it, or
something else?
Array literals also work as template arguments, and we plan to
add in the future associative array and struct literals. C++
established a bridgehead on what could be done with templates,
and D is busy pouring the whole army through it <g>.
For a small example of what can be done, Don Clugston wrote a template
metaprogram to execute "99 bottles of beer" entirely at compile time:
http://www.99-bottles-of-beer.net/language-d-1212.html?PHPSESSID=5195...
On a more practical note, Don Clugston and Eric Anderton have
written string templates that will compile regular expressions
at compile time.
Finally, an example which interests me:-).
(It's done in C++ using expression templates rather than
string templates.)
Does this mean that we don't need string templates in C++ to do
it? (Sounds funny: how do you specify the regular expression,
if not with a string?)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
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! ]