【发布时间】:2020-03-17 03:18:30
【问题描述】:
当我们从 AIX 迁移到 Linux Redhat 时,我遇到了一些遗留代码,发现 strcmp 的一些奇怪条件似乎在 AIX 上编译得很好,但在 Linux 上却出现了分段错误
void conv_virgin(char original_number[20], char normalised_number[20],char b_imsi[20]) {
if(strlen(original_number)<2||strcmp(original_number,""||strlen (b_imsi)<6)==0)
{
strcpy(normalised_number,original_number);
return;
}
}
对于 AIX,该行似乎编译得很好,因为我们的共享对象已经运行了 2 年多
strcmp(original_number,""||strlen (b_imsi)<6)==0
我错过了什么? 预期的代码是检查两个字段,现在已更正为
if(strlen(original_number)<2||strlen (b_imsi)<6)
【问题讨论】:
-
说实话,我什至不明白原来的说法
strcmp(original_number,""||strlen (b_imsi)<6)==0应该是什么意思。在||的上下文中,""的计算结果为真值(即 1),跳过strlen()调用并将 1 作为字符串传递给strcmp()。这是未定义的行为,因此程序崩溃是正确的。我不知道原作者想说什么。 -
除了导致分段错误之外,您还应该得到一些编译器警告。
strcmp需要 2 个字符串。您提供一个字符串和一个整数类型的逻辑 OR 的结果。 0 或 1 不是字符串的好地址。 -
我认为它是像
strcmp(original_number,"")==0||strlen (b_imsi)<6这样的代码,由于在编辑器中标记一些文本并意外用鼠标拖到另一个位置而损坏了。 -
strcmp(original_number,""||strlen (b_imsi)<6)==0可能是strcmp(original_number,"")==0||strlen (b_imsi)<6 -
地址零我们在 AIX 上可读(那里启动内核),但在 Linux 上不可读。 (正如人们所说,你的代码从来都没有问题。)