Возможно, это в цикле сообщений драйвер устройства и оригинальном кодер, возможно, 10 лет назад, не хотели прыжков в коде. Надеюсь, он подтвердил, что его компилятор не реализовал тройной оператор с прыжками!
Рассмотрение кода, мое первое замечание состоит в том, что последовательность тройных операторов - как и весь код - лучше читается при надлежащем форматировании.
Тем не менее, я не уверен, что правильно разбирал пример OP, который говорит против него. Даже традиционную вложенную конструкцию if-else трудно проверить. Это выражение нарушает фундаментальную парадигму программирования: Divide и Conquer.
req.security_violation
? dis_prot_viol_rsp && is_mstr
? uvc_pkg::MRSP_OKAY
: uvc_pkg::MRSP_PROTVIOL
: req.slv_req.size()
? is_mst_abort_rsp && dis_mst_abort_rsp
|| req.slv_req[0].get_rsp_status()==uvc_pkg::MRSP_PROTVIOL
&& dis_prot_viol_rsp
|| is_mst_abort_rsp && req.is_pci_config_req() && dis_pcicfg_mst_abort_rsp
? uvc_pkg::MRSP_OKAY
: req.slv_req[0].get_rsp_status()
: uvc_pkg::MRSP_OKAY;
Я хотел проверить, как выглядит код при реорганизации. Это, конечно, не короче, но мне нравится, как названия говорящих функций делают цель более ясной (конечно, я догадался здесь). Это, в некоторой степени, псевдокод, потому что имена переменных, вероятно, не являются глобальными, поэтому функции должны иметь параметры, что делает код менее понятным. Но, возможно, этот параметр может быть единственным указателем на структуру состояния или запроса или такой (из которых были извлечены значения, такие как dis_prot_viol_rsp
). Использовать тройник при объединении различных условий - это обсуждение. Я нахожу его часто элегантным.
bool ismStrProtoViol()
{
return dis_prot_viol_rsp && is_mstr;
}
bool isIgnorableAbort()
{
return is_mst_abort_rsp && dis_mst_abort_rsp;
}
bool isIgnorablePciAbort()
{
return is_mst_abort_rsp && req.is_pci_config_req() && dis_pcicfg_mst_abort_rsp;
}
bool isIgnorableProtoViol()
{
return req.slv_req[0].get_rsp_status()==uvc_pkg::MRSP_PROTVIOL && dis_prot_viol_rsp;
}
eStatus getRspStatus()
{
eStatus ret;
if(req.security_violation)
{
ret = ismStrProtoViol() ? uvc_pkg::MRSP_OKAY : uvc_pkg::MRSP_PROTVIOL;
}
else if( req.slv_req.size())
{
ret = isIgnorableAbort()
|| isIgnorableProtoViol()
|| isIgnorablePciAbort()
? uvc_pkg::MRSP_OKAY
: req.slv_req[0].get_rsp_status();
else
{
ret = uvc_pkg::MRSP_OKAY;
}
return ret;
}
Наконец, мы можем использовать тот факт, что uvc_pkg::MRSP_OKAY
является kindof по умолчанию и только перезаписаны при определенных обстоятельствах. Это устраняет ветвь. Посмотрите, как после некоторой резки аргументы кода хорошо видны: если это не нарушение безопасности, посмотрите ближе и проверьте статус фактического запроса, минус пустые запросы и игнорируемые прерывания.
eStatus getRspStatus()
{
eStatus ret = uvc_pkg::MRSP_OKAY;
if(req.security_violation)
{
ret = ismStrProtoViol() ? uvc_pkg::MRSP_OKAY : uvc_pkg::MRSP_PROTVIOL;
}
else if( req.slv_req.size()
&& !isIgnorableAbort()
&& !isIgnorablePorotoViol()
&& !isIgnorablePciAbort()
)
{
ret = req.slv_req[0].get_rsp_status();
}
return ret;
}
Является ли 'exp_rsp_status' по умолчанию конструктивным и назначаемым? – NathanOliver
Связанные: http://stackoverflow.com/questions/18237432/how-to-rewrite-complicated-lines-of-c-code-nested-ternary-operator или http://stackoverflow.com/questions/19020092/multiple -ternary-operator-in-c –
Ваш вопрос фокусируется на тройном операторе, когда реальная проблема заключается в том, что он просто слишком сложный, тройственный или нет. –