¿Cuál es la función de “(void) (& _min1 == & _min2)” en la macro mínima en kernel.h?

En kernel.h min se define como:

#define min(x, y) ({ \ typeof(x) _min1 = (x); \ typeof(y) _min2 = (y); \ (void) (&_min1 == &_min2); \ _min1 < _min2 ? _min1 : _min2; }) 

No entiendo cuál es la línea (void) (&_min1 == &_min2); hace. ¿Es algún tipo de comprobación de tipo o algo así?

La statement

 (void) (&_min1 == &_min2); 

es un “no-op” garantizado. Entonces la única razón por la que está ahí es por sus efectos secundarios.

¡Pero la statement no tiene efectos secundarios!

Sin embargo: obliga al comstackdor a emitir un diagnóstico cuando los tipos de x no son compatibles .
Tenga en cuenta que las pruebas con _min1 == _min2 convertirían implícitamente uno de los valores al otro tipo.

Entonces, supongo, eso es lo que hace. Valida, en tiempo de comstackción, que los tipos de y son compatibles .

El código en include / linux / kernel.h se refiere a esto como una comparación de puntero “innecesaria”. De hecho, se trata de una verificación de tipo estricta que garantiza que los tipos de y son los mismos.

Un desajuste de tipo aquí provocará un error o advertencia de comstackción.

Esto proporciona verificación de tipo, la igualdad entre punteros debe ser entre tipos compatibles y gcc proporcionará una advertencia para los casos donde esto no es así.

Podemos ver que la igualdad entre los punteros requiere que los punteros sean de tipos compatibles del borrador de la sección 6.5.9 estándar 6.5.9 operadores de igualdad que dice:

Uno de los siguientes debe contener:

e incluye:

ambos operandos son punteros a versiones calificadas o no calificadas de tipos compatibles;

y podemos encontrar el tipo compatible de la sección 6.2.7 Tipo compatible y tipo compuesto que dice:

Dos tipos tienen un tipo compatible si sus tipos son los mismos

Esta discusión sobre osnews también cubre esto y fue inspirada por los trucos de GCC en el artículo del kernel de Linux que tiene la misma muestra de código. La respuesta dice:

tiene que ver con la verificación de tipo.

Haciendo un progtwig simple:

 int x = 10; long y = 20; long r = min(x, y); 

Otorga la siguiente advertencia: advertencia: la comparación de distintos tipos de puntero carece de un molde

Ver http://www.osnews.com/comments/20566 que explica:

Tiene que ver con la verificación de tipo.

Haciendo un progtwig simple:

 int x = 10; long y = 20; long r = min(x, y); 

Otorga la siguiente advertencia: advertencia: la comparación de distintos tipos de puntero carece de un molde

La respuesta encontrada aquí

“Tiene que ver con la verificación de tipo. Hacer un progtwig simple:

 int x = 10; long y = 20; long r = min(x, y); 

Otorga la siguiente advertencia: advertencia: la comparación de distintos tipos de puntero carece de un molde ”

El kernel de Linux está lleno de cosas como esta (scripts gratuitos específicos de gcc por “seguridad tipo” y otras consideraciones similares), y yo consideraría que es una muy mala práctica y le insto a no seguirla a menos que alguien lo requiera.

pmg tiene razón acerca del propósito del hack, pero cualquier persona en su sano juicio definiría min como ((x)<(y)?(x):(y)) .

Tenga en cuenta que la definición del kernel impide muchos usos correctos, por ejemplo, cuando un argumento es int y otro es long . Sospecho que lo que realmente querían evitar es la falta de coincidencia de signo, donde por ejemplo min(-1,1U) es 1. Una mejor forma de afirmar esto sería usar una aserción en tiempo de comstackción para ((1?-1:(x))<0)==((1?-1:(y))<0) . Tenga en cuenta que esto no requiere ningún hack específico de gcc.