Creo que el problema que tenes es que no estas entendiendo lo que se intenta realizar.
El & ( AND ) es un operadot bit-wise ( o bit a bit ). Primero entendamos que es cada cosa
IFG2 & UCA0TXIFG
IFG2 Es el registro Interrupt Flag Register 2, el cual es de 8 bits, pero solo 4 tienen un significado.
UCA0TXIFG es el flag de interrupcion ( uno de los bits de IFG2 ) de la UART. Esto en realidad es un numero y potencia de 2.
Lo que se suele hacer es que IFG2 devuelva los 8 bits, es decir todo el registro, mientras que UCA0TXIFG sea una "mascara". Me explico con un ejemplo.
Tengos los siguientes valores:
IFG2 = 0b0000 1011
UCA0TXIFG = 0b0000 0010
Al hacerle la AND queda asi:
0000 1011
0000 0010
-------------
0000 0010
Es decir mi "mascara" solo deja pasar el bit de mi interes.
Eso me da un numero que es 2. Pero C, el unico numero que considera "falso" es el 0, todo lo demas es considerado "Verdadero". Asi que si de IFG2 mi bit de interes era 0, el resultado de la AND es 0, sino es numero distinto de 0.
Hay una cosa mas que decirte, la mascara suele ser un numero constante, mientras que el IFG2 es el puntero al registro
Entonces... Suupongamos que el flag esta en 0, para entender el codigo. Si lo reemplazamos queda asi:
else{
while (!(0));
UCA0TXBUF = c[i];
}
Ahora el operador !, es un operador LOGICO, es decir solo se maneja con Verdadero o Falso. Por lo tanto primero va a pasar el numero 0 a un booleano, como anticipe antes es un "Falso", Y el operador lo va a cambiar a "Verdadero". Por lo tanto el queda asi:
else{
while (true);
UCA0TXBUF = c[i];
}
Y se mantendria en ese while. Esto se repite continuamente, hasta que el flag esta activo ( termino de transmitir ), dejando al resultado de la AND en un 2. Eso es un "Verdadero" y el !, lo convierte en "Falso".
En resumen. Se mantiene encerrado hasta que se activa el flag.
Ahora revisemos tu ejemplo en tu PC
a = 10 = 0000 1010
b = 12 = 0000 1100
a&b = 0000 1000
Por lo tanto es, luego de negarlo es "Falso" y sale del while ahi nomas. Para probar, podrias hacerlo cambiando los valores de
b, y dandole los valores 0x1, 0x2, 0x4 y 0x8
Vas a notar que si dejas a con un valor de 10, para cuando valga 0x2 y 0x8 nunca va a salir del while.
Lo otro es acerca de la directiva #pragma. Investigue acerca de ella y note que no es un estándar para todos los compiladores y C, son "etiquetas" que realizan "tareas" especificas para cada compilador.
¿Es asi o no?
la directiva de preprocesamiento PRAGMA pertenece al ANSI C
#pragma keyword options
Y puede ser usado para modificar el comportamiento del compilador. La diferencia es que no todos poseen los mismos keyword, estos si son dedicados a cada compilador. Muy pocas veces lo vi usado aparte de los FUSES, solo para eliminar algun warning que da el compilador (que lo omita).