perl - (4 + sub)等于(sub + 4)吗?

标签 perl winapi operator-precedence

(编辑)TL; DR :我的问题是,尽管Win32 API定义的是真实的整数常量(如平台SDK header 中一样),而Win32 Perl包装器将它们定义为subs。从而引起一线解析的误解。

在单线测试对Win32::MsgBox的调用时,我感到以下困惑:给出MsgBox的可能参数是消息,用于选择按钮类型(值0..5)和消息框的标志的总和。图标“常量”(MB_ICONSTOP,...)和标题

调用perl -MWin32 -e"Win32::MsgBox world, 4+MB_ICONQUESTION, hello"可以得到预期的结果

而看起来相似的代码perl -MWin32 -e"Win32::MsgBox world, MB_ICONQUESTION+4, hello"是错误的

我首先尽管这是由于缺少括号,但是添加一些perl -MWin32 -e"Win32::MsgBox (world, MB_ICONQUESTION+4, hello)"会得出完全相同的错误结果。

我尝试与一位同事一起使用以下代码进行更深入的研究并显示传递给函数调用的参数(因为MB_xxx常数实际上是子变量)

>perl -Mstrict -w -e"sub T{print $/,'called T(#'.join(',',@_).'#)'; 42 }; print $/,'results:', join ' ,', T(1), T+1, 1+T"

输出
called T(#1#)
called T(##)
called T(#1,43#)
results:42 ,42

但是我不明白为什么在传递给join()的列表中将args T+1, 1+T解析为T(1, 43) ...

最佳答案

B::Deparse进行救援:

C:>perl -MO=Deparse -MWin32 -e"Win32::MsgBox world, MB_ICONQUETION+4, hello"
use Win32;
Win32::MsgBox('world', MB_ICONQUESTION(4, 'hello'));
-e syntax OK

C:>perl -MO=Deparse -MWin32 -e"Win32::MsgBox world, 4+MB_ICONQESTION, hello"
use Win32;
Win32::MsgBox('world', 4 + MB_ICONQUESTION(), 'hello');
-e syntax OK

第一种情况下的MB_ICONQUESTION调用被认为是带有参数+4, 'hello'的函数调用。在第二种情况下,它被视为不带参数的函数调用,并且添加了4个参数。它似乎不是一个常数,而是一个函数。

在源代码中,我们对此进行了验证:
sub MB_ICONQUESTION                     { 0x00000020 }

它是一个返回32(二进制的00100000,表示已设置的位)的函数。就像Sobrique指出的那样,这是一个标志变量,因此您不应使用加法运算,而应使用按位逻辑和/或运算符。

在您的情况下,它仅接受任何参数并忽略它们。如果您期望一个常数,这会有点令人困惑。

在您的实验案例中,该语句
print $/,'results:', join ' ,', T(1), T+1, 1+T

被解释
print $/,'results:', join ' ,', T(1), T(+1, (1+T))

因为执行从右到左
1+T = 43
T +1, 43 = 42
T(1) = 42

因为plus +precedence比逗号,高,而一元+甚至更高。

为了消除歧义,您需要使用括号来阐明优先级:
print $/,'results:', join ' ,', T(1), T()+1, 1+T
#                                      ^^-- parentheses

通常,应该始终在子程序调用中使用括号。在 perldoc perlsub 中,有4种调用符号:
NAME(LIST);    # & is optional with parentheses.
NAME LIST;     # Parentheses optional if predeclared/imported.
&NAME(LIST);   # Circumvent prototypes.
&NAME;         # Makes current @_ visible to called subroutine.

在我看来,只有第一个是透明的,而另一个则有点模糊。

关于perl - (4 + sub)等于(sub + 4)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30211089/

相关文章:

Perl Moose 方法修饰符 : Call 'around' before 'before' and 'after'

c++ - 我需要定时器每 25fps 显示图像缓冲区 (C++ win32)

c++ - Windows GDI 上下文 - LoadImage 和 GetLastError()

c++ - 是否违反了 C/C++ 运算符优先级和关联性规则?

c - 与输入/输出格式说明符相关联的每个转换都是 C 中的序列点吗?

perl - 在模式中使用带有空格的 Perl glob

perl - 我是否可以在不指定所需 Perl 版本的情况下使用新的 5.12 包版本语法?

perl - 如何使用 Perl 的 LWP::Simple 发送 cookie?

c++ - 免费的 C++ 库 (Win32) 来录制麦克风

java - 解决不同数学运算符的优先级