在浏览我们组织的代码库时,我发现了这个小宝石:
RawParameterStorage[!ParameterWorkingIdx][ParameterDataOffset] = ...
这段代码是否有效?(它可以编译)这里的感叹号是什么作用?
使用反转 ~
运算符可能是有意义的,因为在布尔表达式中常常与非 !
运算符混淆。然而,在数组索引上强制使用非 !
运算符似乎没有逻辑意义。有什么想法?
在浏览我们组织的代码库时,我发现了这个小宝石:
RawParameterStorage[!ParameterWorkingIdx][ParameterDataOffset] = ...
这段代码是否有效?(它可以编译)这里的感叹号是什么作用?
使用反转 ~
运算符可能是有意义的,因为在布尔表达式中常常与非 !
运算符混淆。然而,在数组索引上强制使用非 !
运算符似乎没有逻辑意义。有什么想法?
!ParameterWorkingIdx
意味着 ParameterWorkingIdx
值为 0
,如果是,则!ParameterWorkingIdx
求值为 true
,可能会隐式转换为索引类型(例如,在数组中为整数索引器的1
),否则,求值为 false
。
如果 ParameterWorkingIdx == 0
,则 [!ParameterWorkingIdx] == [1]
。
如果 ParameterWorkingIdx != 0
,则 [!ParameterWorkingIdx] == [0]
。
还取决于其他因素,如:
ParameterWorkingIdx
的类型。
按照 ParameterWorkingIdx
的类型重载 ! 运算符
。
按照 RawParameterStorage
的类型重载索引器。
等等...
猜测这是一个双缓冲模式。 ParameterWorkingIdx
会在0和1之间来回切换(可能使用代码 ParameterWorkingIdx = !ParameterWorkingIdx;
)。
然后,RawParameterStorage[ParameterWorkingIdx]
将是当前的缓存,而RawParameterStorage[!ParameterWorkingIdx]
将是先前的缓存。
对数组索引使用非
!
操作符似乎没有逻辑意义
这样做可能有意义: 它只会将零转换为一,将其他数字转换为零。
我们可以从这段代码中推断出,RawParameterStorage
可能在顶层有两个元素。
附注:在此,我假设 RawParameterStorage
是一个数组(正如你所说)。此外,我假设 ParameterWorkingIdx
是一个整数(因为它的名字暗示了这一点)。例如,如果其中一个是带有重载操作符的类,则语义可能完全不同。
ParameterWorkingIdx
不是一个具有重载 !
操作符的类的实例。建议 OP 进行检查。 - Bathsheba这是有效的代码吗?
是的。假设ParameterWorkingIdx
是一个int
,对于!ParameterWorkingIdx
,当与operators !
一起使用时,它将在上下文中转换为bool,
值为零(对于整数、浮点数和未作用域枚举)、空指针和空指针成员值变为
false
。所有其他值都变为true
。
然后进行整数提升以用作数组索引。
类型bool可以转换为值为
false
的int,true
变为1。
因此,!ParameterWorkingIdx
等同于ParameterWorkingIdx == 0 ? 1 : 0
,这更加清晰易懂。
ParameterWorkingIdx == 0 ? 1 : 0
),clang使用cmove
指令而不是分支(x86_64)。gcc则会分支。 - tamas.kenez
"true"
/"false"
。所以要么使用"You "+["are not", "are"][+loggedIn()]+ " logged in"
,要么使用"You "+{false:"are not", true:"are"}[loggedIn()]+ " logged in"
。 - Bergi