缺少的布尔运算符如何仍然可以编译?
How does a missing boolean operator still compile?
我有这样的代码:
val pop: Bool = (
(fsm === Fsm.None && canPop) ||
(fsm === Fsm.Some && canPop && fooBar)
(fsm === Fsm.Other && canPop && dragonFruit) ||
(fsm === Fsm.Mom && canPop))
fsm
是一个基于 ChiselEnum 的状态机,其他信号只是布尔值。第二个语句行(fooBar 之后)缺少 ||
。这会编译并运行,但会导致行为错误。我的问题是......为什么要编译?这似乎不是有效的语法。是吗?
请帮助我理解这一点。我只是花了很多天调试一个大电路才发现这个问题。
正确答案
问题是这是一个有点摘录。 Chisel 允许您执行 foo(bar)
从 foo
中提取索引 bar
处的位。上面的代码,正如所写的那样,有点摘录,即使用户希望它是一个错误。
不幸的是,这是一个已知的陷阱,在没有误报的情况下犯错误是不合理的,同时仍然允许用户使用 ()
语法进行位提取。
原答案不正确
这是符合 Scala 规则的有效语法。这里发生的事情是代码实际上是两条语句,但缩进令人困惑。相当于:
val foo = a + b // Create an immutable value equal to "a + b".
c + d // A bare statement that adds "c + d", but doesn't use the result.
或臭名昭著的 C 错误,例如:
if (cond)
foo();
bar(); // bar() is always executed, but the indentation is confusing.
通常这是由于代码格式化程序或通过 linting 而引起的事情类型。但是,几乎所有语言都有这个问题。
为您的项目设置 Scalafmt 可能会有所帮助。
我有这样的代码:
val pop: Bool = (
(fsm === Fsm.None && canPop) ||
(fsm === Fsm.Some && canPop && fooBar)
(fsm === Fsm.Other && canPop && dragonFruit) ||
(fsm === Fsm.Mom && canPop))
fsm
是一个基于 ChiselEnum 的状态机,其他信号只是布尔值。第二个语句行(fooBar 之后)缺少 ||
。这会编译并运行,但会导致行为错误。我的问题是......为什么要编译?这似乎不是有效的语法。是吗?
请帮助我理解这一点。我只是花了很多天调试一个大电路才发现这个问题。
正确答案
问题是这是一个有点摘录。 Chisel 允许您执行 foo(bar)
从 foo
中提取索引 bar
处的位。上面的代码,正如所写的那样,有点摘录,即使用户希望它是一个错误。
不幸的是,这是一个已知的陷阱,在没有误报的情况下犯错误是不合理的,同时仍然允许用户使用 ()
语法进行位提取。
原答案不正确
这是符合 Scala 规则的有效语法。这里发生的事情是代码实际上是两条语句,但缩进令人困惑。相当于:
val foo = a + b // Create an immutable value equal to "a + b".
c + d // A bare statement that adds "c + d", but doesn't use the result.
或臭名昭著的 C 错误,例如:
if (cond)
foo();
bar(); // bar() is always executed, but the indentation is confusing.
通常这是由于代码格式化程序或通过 linting 而引起的事情类型。但是,几乎所有语言都有这个问题。
为您的项目设置 Scalafmt 可能会有所帮助。