Question

Je sais que l'opérateur ternaire a des restrictions surprenantes, mais j'étais un peu déconcerté que cela ne peut pas compiler pour moi:

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

De toute évidence qui est le minimum nécessaire pour montrer le problème. L'erreur est:

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

Compiler est le moins que 100% -conforming Embarcadero C ++ Builder 2010, donc un bug du compilateur est loin d'être impossible ...

NOTE: parens modifié pour éviter toute confusion au sujet de mon intention

.

NOTE2: Je me suis un peu confus sur la façon dont je suis arrivée à cette construction, en premier lieu, donc voici mon excuse: je recevais des erreurs de compilation sur une ligne comme a = b? c : d, où b, c et d étaient toutes les expressions complexes. Pour le réduire, je l'ai remplacé c et d avec NULLs afin de vérifier si b était le coupable. À ce stade, tout est allé en enfer dans une charrette à bras.

Était-ce utile?

La solution

NULL est une macro qui se développe pour 0 (ou une expression constante intégrale avec une valeur de 0, par exemple, (1 - 1)). Ce n'est pas autrement « spécial ».

Toute expression constante intégrale avec une valeur de zéro peut être utilisée comme une constante de pointeur null qui est la raison pour laquelle int* ptr = 0; est autorisée. Cependant, ici, l'expression est b ? 0 : 0; ce ne sont pas une expression constante intégrale (b est pas constante); son type est int, ce qui est implicitement convertible en int*

La solution serait de préciser explicitement que vous voulez un type de pointeur:

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

L'exemple est un peu artificiel, si: généralement quand on utilise l'opérateur conditionnel, au moins l'un des arguments est en fait un type de pointeur (par exemple b ? ptr : 0); lorsque l'un des opérandes est un type de pointeur, le 0 est converti implicitement à ce même type de pointeur et donc le type de l'ensemble de l'expression conditionnelle est le type de pointeur, pas int.

Le seul cas où vous pouvez avoir ce « problème » est là une constante de pointeur NULL est utilisé à la fois comme deuxième et troisième opérandes de l'opérateur conditionnel, ce qui est plutôt bizarre.

Autres conseils

Votre problème est que sur votre système NULL est défini comme 0 qui est supposé être un entier dans le contexte de l'opérateur ternaire. Si vous static_cast un des opérandes à int* il devrait automatiquement promouvoir l'autre.

Mais pourquoi utiliser une telle construction en premier lieu?

NULL peut être définie comme ayant le type int ou même long, de sorte que l'opérateur ternaire a le même type. Il n'y a pas de conversion implicite du type de pointeur, donc compilateur génère une erreur. Le gotcha est ici qu'il y a une conversion implicite de l'expression constante entière évaluation à zéro (la constante de pointeur null infâme).

Solution possible est explicite ici:

int* ptr =  b ? (int*) NULL : NULL;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top