为什么在某些c++类型中条件/三元运算符的结果可能与if-else语句不同?

dba5bblo  于 2023-01-15  发布在  其他
关注(0)|答案(1)|浏览(194)

下面是我的代码:

// defs
string untrusted_ip;
const char * get_env (const char *name, const char *envp[]);
string User::getCommonname(void);
void User::setStatusFileKey(string);
void User::setKey(string);

// 1
                if( get_env ( "untrusted_ip", envp ) !=NULL ){
                    newuser->setStatusFileKey(newuser->getCommonname() +string ( "," ) + untrusted_ip + string ( ":" ) + get_env ( "untrusted_port", envp ) );
                    newuser->setKey(untrusted_ip + string ( ":" ) + get_env ( "untrusted_port", envp ) );
                }else{
                    newuser->setStatusFileKey(newuser->getCommonname() +string ( "," ) + untrusted_ip);
                    newuser->setKey(untrusted_ip);
                }
                
// 2
                newuser->setStatusFileKey(newuser->getCommonname() +string ( "," ) + untrusted_ip + get_env ( "untrusted_ip", envp ) != (const char*)NULL ? string ( ":" ) + get_env ( "untrusted_port", envp ) : string("") );
                newuser->setKey(untrusted_ip + get_env ( "untrusted_ip", envp ) != (const char*)NULL ? string ( ":" ) + get_env ( "untrusted_port", envp ) : string("") );

修改自www.example.comhttps://salsa.debian.org/debian/openvpn-auth-radius/-/blob/master/radiusplugin.cpp#L446
块1和2似乎相等,但1按预期工作,而2不工作(似乎未执行,因为断点未触发)。
这两个代码块的核心区别是什么?
另外,条件运算符中只有get_env ( "untrusted_ip", envp ) != (const char*)NULL可以通过编译,而if( get_env ( "untrusted_ip", envp ) !=NULL )是可以通过编译的,原因是什么?这两个问题有联系吗?
另外,我使用的是gcc/g ++10.2.1

b1zrtrql

b1zrtrql1#

这是一个operator precedence问题。
加法运算符+!=具有更高的优先级,因此表达式等效于(稍微重写以便于查看):

auto result = newuser->getCommonname() +string ( "," ) + untrusted_ip + get_env ( "untrusted_ip", envp );

newuser->setStatusFileKey(
    result != (const char*)NULL 
    ?
    string ( ":" ) + get_env ( "untrusted_port", envp )
    :
    string("") );

这是条件表达式不仅使代码难以阅读和理解,而且使代码出错的许多情况之一。
if else版本更容易阅读和理解,而且更正确。

相关问题