В GCC это выражение:
bool_expr ? func1 : func2
выдает это предупреждение:
warning: pointer type mismatch in conditional expression
, даже если вы не включаете специальные предупреждения.
Более того, GCC устраняет это несоответствие типов указателей, приводя оба выражения к void *
; поэтому, когда вы пытаетесь привести его обратно (либо явно, с (int (*)(void*, void*))
, либо неявно, передав его foo
), он выдает следующее предупреждение:
warning: ISO C forbids conversion of object pointer to function pointer type
если вы включите педантизм. (Причина, по которой ISO C запрещает это, заключается в том, что указатель на функцию не нужно реализовывать внутри как указатель на область памяти, поэтому он может не иметь такого же размера и тому подобного, что и обычный указатель «объекта».)
Тем не менее, это:
foo((bool_expr ? (int (*)(void*, void*))func1 : (int (*)(void*, void*))func2));
должен быть относительно безопасным при условии, что foo
передает действительные char
указатели на func1
или действительные int
указатели на func2
.
И я предполагаю, что в системе, где указатели функций действительно несовместимы с void *
, компилятор не разрешит несоответствие bool_expr ? func1 : func2
в пользу void *
(хотя я не обращался к спецификации по это).