-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should asserts in const expressions always be evaluated? #447
Comments
+100. The only real value I see in not evaluating an assertion is performance. Const asserts have zero performance cost, so there's no reason to not always evaluate them. |
Agree, it brings real value to evaluate assertions, and the main reason not to is to avoid production overhead. However, it means that: class C {
const C(int x) : assert(x != 0);
} behaves differently between compile-time and run-time. |
Agreed, same reasons as @munificent and @lrhn! ;-) I don't see a problem in |
Based on feedback from the language team (dart-lang/language#447). Removal of CompilerOptions.enableAsserts is pending cleanup in DDK. Change-Id: Id515e91da3e31647941ce893b2cffc58894a1b1d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108813 Commit-Queue: Vyacheslav Egorov <vegorov@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
Okay, are we happy with accepting this behavior? If so, we should update the spec appropriately. |
There are some situations where it "removes overhead". Some constructors cannot be declared as const, because they have an assert that calls a function: class Foo {
Foo(this.bar): assert(bar.trim().length > 0);
final String bar;
} When the I don't think it truly matters, but worth noting. |
@rrousselGit There should be no difference between the allowed programs before and after this change, but the assertions that are part of a constant evaluation (read: asserts in const constructor initializer lists of constructors invoked as const) will be checked at compile-time even when run-time assertions are disabled. |
Seems like the CFE/Fasta has implemented the "constant asserts are always evaluated", but we haven't added it to the Null Safety specification I'm not sure exactly how it's implemented by the CFE (no tests), and we haven't specified it formally yet, so just to say what I expect it to do:
(An assert of the form I think this is the right choice. It avoids the front-end/Fasta compilers needing to be told whether assertions are enabled when compiling constants. Otherwise we'd need to let pkg/fasta/compiler accept the |
Regarding the above example it would be nice to have 2 kinds of assert in compile-time constant evaluation to allow: class Foo {
const Foo(this.bar): assert(bar.trim().length > 0); // not possible today
final String bar;
} If the assert is evaluated as part of compile-time constant evaluation e1 would be evaluated only if e1 is a potentially constant expression. If e1 is not a potentially constant expression the assert would be evaluated at runtime when the const value is instantiated. There are a lot of immutable classes that should/could be const but they are not because of asserts in intializer list. |
Decided at language meeting Nov 11: We always evaluate const asserts. |
Changes to pkg/compiler, pkg/dev_compiler, pkg/front_end, pkg/vm were landed as dart-lang/sdk@e82ca2f. @scheglov, a couple of experiments seem to confirm that the analyzer always evaluates assertions that occur in the initializer list of a |
@eernstg Yes, the analyzer always evaluates the condition of |
Thx! |
A question was raised as to whether asserts in const expressions should always be evaluated, or only when asserts are otherwise enabled. Note that the notion of "asserts are otherwise enabled" is not necessarily well-defined at the point that consts are evaluated if we allow turning assertions on and off dynamically. In discussion, it seems useful to allow normal assertions to be:
Since consts are evaluated at compiled time, the only way we could turn const asserts on/off would be via the compile time control. That implies that we would only not evaluate const asserts if the compile time flag was off.
If we allow the compile time flag to turn off const assertions, then in table form the behavior looks like this:
If we always evaluate const asserts, then the behavior looks like this:
I don't see a lot of value in not evaluating const asserts. I also suspect that the analyzer always evaluates them: @stereotype441 is that correct?
So my inclination would be to go with the second behavior, where const asserts are always evaluated. The implementations are going with this behavior for now, since it is simpler to implement. If we decide to require the ability to turn on/off const asserts they can add this later as a non-breaking change.
cc @lrhn @munificent @eernstg @mraleph @a-siva
The text was updated successfully, but these errors were encountered: