Take a look at this example, which you can execute in any mIRC's editbox:
//var %a 5 | echo -ag $+(test,%a)
This will echo, as expected, even by you, "test5".
This is because it is expected that under normal circumstances, all the parameters of an identifier are evaluaed once before that function is executed, so $+() will evaluated the first parameter to "test" and will evaluate the second parameter %a to 5, and the concatenation of the two results in "test5".
$iif() is not different from $+() or any other $identifier() taking parameters, the parameter passed to $iif are evaluated before the function itself does something with the parameters.
So when you do $iif(%a == 1,%b = 2,%b = 3) %a %b and %c are all evaluated because they appear space separated in their parameter. And only after they have been evaluated, $iif will check if the condition is true.
You may think that if the condition is false, evaluating the true part (the second parameter) of $iif is useless since that value won't be used, and you would be right, but then that's about how $iif was implemented in the first place, and it's important that it works the way it's documented: as a normal identifier.
The documentation is not so clear about this but it's a main rule of the scripting language that identifiers evaluate their parameter once and in order.
Some identifier like $regsubex don't follow this rule and are exceptions, but they are not documented as being exceptions because it's a technicality that most scripters don't need to know/understand to use the identifier.
It may not seem like it but fixing this issue brought a lot of good to the language, it made parsing faster, it made the source code cleaner. As a matter of fact the $iif identifier is internally coded by calling the /if conditional construct instead of being a copy of it, that makes the $iif identifier super slow.
Your original code:
%a = 1 | %b = 2 | $iif(%a == 1,%b = 2,%b = 3)
is much much better written by keeping $iif as
%a = 1 | %b = $iif(%a == 1,2,3)
and without $iif as
%a = 1 | %b = 3 | if (%a == 1) %b = 2
or with an else to avoid the extra assignment
%a = 1 | if (%a == 1) %b = 2 | else %b = 3