The reason the select operator is necessary/useful is for working with OpenCL vector types, like int2, float4 etc. Unlike in C++, where you could overload various operators to give them custom semantics - in C (and OpenCL C) there's only the default behavior. For the ternary operator, that means that for
x ? expression_for_true : expression_for_false
a single check will be performed, and the single appropriate value will be used - even if all three operands are of an OpenCL vector type.
Instead, with select():
- All elements must have the same dimensions as vector types, e.g.
int4, float4 and float4.
- a different check is performed for every position within the vector type.
- a different choice between elements of the true and false expressions is made for every position within the vector type
Also, to confuse us a bit, the order of parameters to select() is different than with the ternary operator: x ? y : z corresponds to select(z, y, x).
Thus if
x = (int4) ( 1, 0 );
y = (float4) ( 1.2, 3.4 );
z = (float4) ( 5.6, 7.8 );
then
select(z, y, x) == (float4) ( 1.2, 7.8 );
See also the Khronos OpenCL documentation, here and here.