overload operator manipulate bitwise c++ language-lawyer bitwise-operators

manipulate - overload operator c++



¿Cuál es el resultado de a & b? (4)

C ++ Standard define el almacenamiento como una cierta cantidad de bits. La implementación puede decidir qué significado atribuir a un bit en particular; Dicho esto, se supone que el AND binario funciona en los ceros conceptuales 0s formando la representación de un tipo particular.

3.9.1.7. (...) Las representaciones de tipos integrales definirán valores mediante el uso de un sistema de numeración binario puro. 49 (...)

3.9.1, nota al pie 49) Una representación posicional para enteros que usa los dígitos binarios 0 y 1, en los que los valores representados por bits sucesivos son aditivos, comienzan con 1 y se multiplican por la potencia integral sucesiva de 2, excepto tal vez para el poco con la posición más alta

Eso significa que para cualquier representación física utilizada, Binary AND actúa de acuerdo con la tabla de verdad para la función AND (para cada número de bit i, toma los bits A i y B i de los operandos apropiados y produce un valor de 1 solo si ambos son 1, de lo contrario, producirá un 0 para el bit R i ). El valor resultante se deja interpretar por la implementación, pero independientemente de lo que se elija, debe estar en línea con otras expectativas con respecto a otras operaciones binarias como OR y XOR.

Esto es incómodo, pero el operador AND bit a bit se define en el estándar C ++ de la siguiente manera (énfasis mío).

Se realizan las conversiones aritméticas habituales; el resultado es la función AND a nivel de bit de sus operandos . El operador aplica solo a operandos de enumeración integral o no codificado.

Esto parece algo sin sentido para mí. La "función AND a nivel de bit" no está definida en ninguna parte del estándar, hasta donde puedo ver.

Entiendo que la función Y es bien conocida y, por lo tanto, puede no requerir explicación. El significado de la palabra "bitwise" también debería ser bastante claro: la función se aplica a los bits correspondientes de sus operandos. Sin embargo, lo que constituye los bits de los operandos no está claro.

¿Lo que da?


Esto no está especificado. La cuestión de lo que significa el estándar cuando se refiere a operaciones de bits es el tema de algunos informes de defectos.

Por ejemplo, informe de defectos 1857: preguntas adicionales sobre bits :

La especificación de las operaciones bit a bit en 5.11 [expr.bit.and], 5.12 [expr.xor], y 5.13 [expr.or] usa el término indefinido "bitwise" al describir las operaciones, sin especificar si es el valor o representación de objetos que está a la vista.

Parte de la resolución de esto podría ser definir "bit" (que de otra manera no está definido actualmente en C ++) como un valor de una potencia dada de 2.

y la respuesta fue:

CWG decidió reformular la descripción de las operaciones mismas para evitar referencias a bits, dividiendo las preguntas más amplias de definir "bit" y similares para emitir 1943 para una mayor consideración.

y el informe de defectos de 1943 dice:

CWG decidió en la reunión 2014-06 (Rapperswil) abordar solo un subconjunto limitado de las cuestiones planteadas por los números 1857 y 1861. Este problema es un marcador de posición para las preguntas restantes, como la definición de un "bit" en términos de un valor de 2 n , especificando si un campo de bit tiene un bit de signo, etc.

Podemos ver en este informe de defectos 1796: ¿Es todo un bits cero para los caracteres nulos un requisito significativo? , que esta cuestión de lo que significa el estándar cuando se refiere a bits afectados / también afecta a otras secciones:

De acuerdo con 2.3 [lex.charset], párrafo 3,

El conjunto de caracteres de ejecución básica y el conjunto de caracteres amplios de ejecución básica contendrán todos los miembros del conjunto de caracteres fuente básico, más los caracteres de control que representan alerta, retroceso y retorno de carro, más un carácter nulo (respectivamente, carácter ancho nulo), cuya representación tiene todos los bits cero.

No está claro que un programa portátil pueda examinar los bits de la representación; en cambio, parece estar limitado a examinar los bits de los números correspondientes a la representación del valor (3.9.1 [basic.fundamental] paragraph 1). Puede ser más apropiado exigir que el valor del carácter nulo se compare con 0 o ''/ 0'' en lugar de especificar el patrón de bits de la representación.

Existe un problema similar para la definición de desplazamiento, a nivel de bit y de bit a bit u operadores: ¿son esas restricciones de especificaciones en el patrón de bits de la representación o en los valores resultantes de la interpretación de esos patrones como números?

En este caso, la resolución era cambiar:

la representación tiene todos los bits cero

a:

el valor es 0.

Tenga en cuenta que, como se menciona en la respuesta de ecatmur, el borrador de la norma de C ++ 5.2.4.2.1 sección estándar C 5.2.4.2.1 en la sección 3.9.1 [fundamento básico] en el párrafo 3 , no se refiere a la sección 6.5/4 del estándar C que al menos dinos que los resultados están definidos por la implementación. En mi comentario a continuación, explico que el estándar C ++ solo puede incorporar texto de referencias normativas explícitamente.


Legalmente, podríamos considerar que todas las operaciones bit a bit tienen un comportamiento indefinido, ya que en realidad no están definidas.

Más razonablemente, se espera que apliquemos el sentido común y nos remitamos a los significados comunes de estas operaciones, aplicándolas a los bits de los operandos (de ahí el término "bitwise").

Pero nada en realidad dice eso. Es una pena que mi respuesta no pueda considerarse una redacción normativa.


[basic.fundamental] / 3 difiere a C 5.2.4.2.1. Parece razonable que los operadores de bit a bit en C ++ que no están especificados de forma adecuada deferieran C, en este caso 6.5.10 / 4:

El resultado del operador binario & es el AND a nivel de bit de los operandos (es decir, cada bit en el resultado se establece si y solo si se establece cada uno de los bits correspondientes en los operandos convertidos).

Tenga en cuenta que C 6.5 / 4 tiene:

Algunos operadores (el operador unario ~ y los operadores binarios << , >> , & , ^ y | , colectivamente descritos como operadores bit a bit ) deben tener operandos que tengan un tipo entero. Estos operadores generan valores que dependen de las representaciones internas de los enteros y tienen aspectos definidos e definidos por la implementación para los tipos firmados.

Las representaciones internas de los enteros se describen, por supuesto, en 6.2.6.2/1, / 2.