Here is my code:
// 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("") );
modified from https://salsa.debian.org/debian/openvpn-auth-radius/-/blob/master/radiusplugin.cpp#L446
block 1 and 2 seems to be equal but 1 works as expected while 2 does not work (seems not executing, for break point is not triggered).
What is the core difference between the two blocks of codes?
Also, only get_env ( "untrusted_ip", envp ) != (const char*)NULL
in conditional operator can pass compilation while if( get_env ( "untrusted_ip", envp ) !=NULL )
is possible. What is the reason and are the two problems connected?
P.S. I am using gcc/g 10.2.1
CodePudding user response:
It's an operator precedence issue.
The additions operator
have higher precedence than !=
so the expression is equivalent to (slightly rewritten to make it easier to see):
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("") );
This is one of the many cases where the conditional expression makes the code not only harder to read and understand, but also makes it wrong.
The if else
version is much easier to read and understand, and correct.