<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=text/html;charset=iso-8859-1 http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.7601.17785"></HEAD>
<BODY style="PADDING-LEFT: 10px; PADDING-RIGHT: 10px; PADDING-TOP: 15px"
id=MailContainerBody leftMargin=0 topMargin=0 CanvasTabStop="true"
name="Compose message area">
<DIV><FONT size=2 face=Consolas>On Friday, May 18, 2012 9:13 PM, Richard Smith
wrote:</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>> OK. The first thing you need to be aware of
is that 'folded<BR>> to a constant' is not the same as 'evaluated as a
constant<BR>> expression'. The former case just means "take an
expression,<BR>> and use any tricks we know to reduce it to a
compile-time<BR>> constant". The latter means following the relevant
language<BR>> standards, which is a nebulous affair [...]</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Firstly, thank you for such a detailed
reply. I have read it through now several times to be sure I understand
everything!</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>From what you say, just to be sure I do
understand, the range of expressions that can be "folded" is a super-set of
those "evaluated to a constant expression" in C++11 terms, which is
in turn a super-set of those which are "integer constant expressions"
of C++98 / C.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>So, what I am looking for is the first thing,
i.e. to use "any tricks we know" to reduce an expression to a compile-time
constant, which should mean, as an example, any calls to functions should be
eliminated. If they cannot be, then by extension the expression cannot be
folded, and the compiler should at this point stop with an error message to that
effect.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>As I mentioned in my post to Jonathan Sauer (<A
title="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-May/021554.html
STRG + Klicken, um Verknüpfung zu folgen"
href="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-May/021554.html">http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-May/021554.html</A>),
one such use case for this is to limit the possibility of using what may be
necessarily-inefficient compile-time algorithms accidentally in a run-time
environment.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>> Additionally, the set of things we can fold
is slightly<BR>> different in the different languages. Anyway, the point
is,<BR>> outside of C++11, we don't really have an implemented,<BR>>
checkable notion of 'constant expression' other than<BR>> 'integer constant
expression'.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Doesn't Expr::EvaluateAsRValue(...) fill
this criteria?</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>> For what it's worth, if you want something
which folds<BR>> expressions, I think you can already build that
[...]</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Unfortunately, I couldn't get your suggestion to
work in my tests. Here's some sample code:</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>struct assert_foldable_t { int arr[1];
};<BR>#define fold(X) (__builtin_constant_p(1)?(X):(X))<BR>#define ignore(X)
((int)!(X))<BR>#define assert_foldable(X) ((void)(struct
assert_foldable_t){.arr[ignore(fold(X))]=1})<BR>#define builtin_fold(X)
(assert_foldable(X),fold(X))</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>constexpr double X() {<BR>
return 5.0;<BR>}</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>int main() {<BR> double i =
builtin_fold(12.0 / X());<BR> printf("%f\n",
i);<BR> return 0;<BR>}</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>It does at least stop compilation if the
expression is not foldable, but it doesn't produce code as though I had written
"double i = 2.4" which is what my aim is (I checked the output using -S
-emit-llvm).</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>I also liked your solution using lambdas (I'd
actually considered a similar solution before), although as you say, it won't
work outside a C++11 environment. Also, you can't use it to assign to a
constexpr variable so it can't be used as a generic solution, although this
is in this case a minor thing.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>> If you want to add a new builtin for this,
you should<BR>> search through the codebase to find the places where<BR>>
builtins are currently handled, and add the relevant<BR>> support for your
builtin there. [...]</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Thank you for the pointers; I will have a nose
around and see what I can do! The way I have been approaching it so far is
to use Parser::ParseAssignmentExpression then Expr::EvaluateAsRValue which
returns an APValue which is the constant I'm looking for. If any of these
steps fail, I can generate some diagnostics and stop. Next, my
understanding and maybe you can confirm whether I'm right, is that I need
to then turn my APValue into an Expr object. There doesn't seem to be
a direct function available for doing this, but I could use IntegerLiteral
or FloatingLiteral for these types, and extract Expr directly from APValue if it
is an LValue type. Other APValue types may be more
difficult, but its a starting point. Is this the best route to take, do
you think?</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>> However, I think a better feature (and one
which I would<BR>> definitely support pushing into trunk clang) would be
an<BR>> attribute which can be applied to declarations (maybe<BR>>
[[clang::const_init]]) [...]</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>I agree that I can certainly see an advantage to
this feature. I'll have a look into this too.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Thanks again,</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Andy</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV> </DIV></BODY></HTML>