Pregunta

Sé que el operador ternario tiene algunas restricciones sorprendentes, pero estaba un poco desconcertado de que esto no me compile:

void foo(bool b)
{
    int* ptr =  ((b) ? NULL : NULL);
}

Obviamente, ese es el mínimo necesario para mostrar el problema. El error es:

[BCC32 Error] Unit11.cpp(20): E2034 Cannot convert 'int' to 'int *'

El compilador es el Builder C ++ Builder 2010 de Embarcadero C ++ 2010, por lo que un error del compilador está lejos de ser imposible ...

Nota: Parens modificados para evitar confusiones sobre mi intención.

Nota2: Me había confundido un poco sobre cómo había llegado a esta construcción en primer lugar, así que aquí está mi excusa: estaba recibiendo algunos errores de compilación en una línea como a = b? c : d, donde B, C y D eran todas expresiones complejas. Para reducirlo, reemplacé c y d con NULLs para verificar si b fue el culpable. En este punto, todo salió al infierno en un carro de mano.

¿Fue útil?

Solución

NULL es una macro que se expande a 0 (o alguna expresión constante integral con un valor de 0, por ejemplo, (1 - 1)). De otra manera no es "especial".

Cualquier expresión constante integral con un valor de cero se puede usar como una constante de puntero nulo, que es la razón por la que int* ptr = 0; esta permitido. Sin embargo, aquí, la expresión es b ? 0 : 0; esta no es una expresión constante integral (b no es constante); Su tipo es int, que no es implícitamente convertible para int*

La solución sería especificar explícitamente que desea un tipo de puntero:

int* const null_int_ptr = 0;
int* ptr = b ? null_int_ptr : null_int_ptr;

Sin embargo, el ejemplo es un poco artificial: generalmente cuando uno usa el operador condicional, al menos uno de los argumentos es en realidad un tipo de puntero (por ejemplo, b ? ptr : 0); Cuando uno de los operandos es un tipo de puntero, el 0 se convierte implícitamente en ese mismo tipo de puntero y, por lo tanto, el tipo de la expresión condicional completa es el tipo de puntero, no int.

El único caso en el que puede tener este "problema" es donde se usa una constante de puntero nulo como el segundo y tercero operandos del operador condicional, lo cual es bastante extraño.

Otros consejos

Su problema es que en su sistema NULL se define como 0 que se supone que es un int en el contexto del operador ternario. Si usted static_cast uno de los operandos a int* Debería promocionar automáticamente el otro.

Pero, ¿por qué están utilizando tal construcción en primer lugar?

NULL podría definirse como tener tipo int o incluso long, entonces el operador ternario tiene el mismo tipo. No hay una conversión implícita al tipo de puntero, por lo que el compilador genera un error. El Gotcha aquí es que hay una conversión implícita de la expresión entera constante que se evalúa a cero (la infame constante de puntero nulo).

La posible solución aquí hay un elenco explícito:

int* ptr =  b ? (int*) NULL : NULL;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top