Esteemed Monks,

I was dumb and accidentally anded some flags instead of orring them at some point when I wrote the part of the software that employs Win32::Sound — I would have found out way earlier, had SND_ASYNC not been 1, and so silently working as intended...

Today I found the bug, replaced things with bitwise ors, and wondered why this could ever have worked before, and it seems that in weird situations (such as the flags being used in the argument list of Win32::Sound::Play), the constants behave completely non-DWIMly.

So here's some examples:

C:\>perl -E "use Win32::Sound; say Win32::Sound::SND_ASYNC; say Win32: +:Sound::SND_LOOP; say Win32::Sound::SND_NODEFAULT;" 1 8 2

This should mean that SND_ASYNC and (as I erroneously wrote) SND_NODEFAULT is 0, right? 1 & 2 is zero, we all know that. Those two orred together is 3.

... Win32::Sound::Play($filename, Win32::Sound::SND_ASYNC & Win32::Sound:: +SND_NODEFAULT); ...

Lo and behold, that thing there has SND_ASYNC set. No, it's not a precedence issue, it would be the same if the bit construct were surrounded by an extra set of parentheses.

C:\>perl -E "use Win32::Sound; say Win32::Sound::SND_ASYNC & Win32::So +und::SND_NODEFAULT;" 1 C:\>perl -E "use Win32::Sound; $x = (Win32::Sound::SND_ASYNC & Win32:: +Sound::SND_NODEFAULT); say $x" 1 C:\>perl -E "use Win32::Sound; say (1 & 2);" 0 C:\>perl -E "use Win32::Sound; say ('1' & '2');" 0 C:\>perl -E "use Win32::Sound; my $as = Win32::Sound::SND_ASYNC; my $n +d = Win32::Sound::SND_NODEFAULT; say $as & $nd;" 0 C:\>perl -E "use Win32::Sound; my @as = Win32::Sound::SND_ASYNC; my @n +d = Win32::Sound::SND_NODEFAULT; say @as; say @nd; say (@as & @nd);" 1 2 1

There it is — & requires scalar values to bitwise and, so takes the length of the two list context return values, which is 1 for each because each is a one element array. Or, if anything, forcing list context on these guys seems to at least replicate the error — no clue why they'd be in list context there in the original usage!

This doesn't, however, explain why it works out of the box with |, where the list context hack doesn't:

C:\>perl -E "use Win32::Sound; my @as = Win32::Sound::SND_ASYNC; my @n +d = Win32::Sound::SND_NODEFAULT; say @as | @nd;" 1 C:\>perl -E "use Win32::Sound; $x = (Win32::Sound::SND_ASYNC | Win32:: +Sound::SND_NODEFAULT); say $x" 3

The only question I have is just: why?


In reply to Win32::Sound constants are weird by Ralesk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.