【问题标题】:strcmp (AIX,Linux Redhat) different behaviorstrcmp (AIX,Linux Redhat) 不同的行为
【发布时间】: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)&lt;6)==0 应该是什么意思。在 || 的上下文中,"" 的计算结果为真值(即 1),跳过 strlen() 调用并将 1 作为字符串传递给 strcmp()。这是未定义的行为,因此程序崩溃是正确的。我不知道原作者想说什么。
  • 除了导致分段错误之外,您还应该得到一些编译器警告。 strcmp 需要 2 个字符串。您提供一个字符串和一个整数类型的逻辑 OR 的结果。 0 或 1 不是字符串的好地址。
  • 我认为它是像strcmp(original_number,"")==0||strlen (b_imsi)&lt;6 这样的代码,由于在编辑器中标记一些文本并意外用鼠标拖到另一个位置而损坏了。
  • strcmp(original_number,""||strlen (b_imsi)&lt;6)==0 可能是strcmp(original_number,"")==0||strlen (b_imsi)&lt;6
  • 地址零我们在 AIX 上可读(那里启动内核),但在 Linux 上不可读。 (正如人们所说,你的代码从来都没有问题。)

标签: c aix


【解决方案1】:

好像是 if 语句的错别字

if(strlen(original_number)<2||strcmp(original_number,""||strlen (b_imsi)<6)==0)

条件strlen (b_imsi)&lt;6 永远不会被计算,因为字符串文字"" 的地址永远不会等于NULL。所以只计算逻辑表达式的第一个操作数

""||strlen (b_imsi)<6

看来if语句应该写成这样

if(strlen(original_number)<2||strcmp(original_number,"" ) ||strlen (b_imsi)<6 )

或喜欢(不太可能)

if(strlen(original_number)<2|| strcmp(original_number,"" ) == 0 ||strlen (b_imsi)<6)

无论如何,这个功能很糟糕。至少它应该被声明为

void conv_virgin( const char original_number[20], char normalised_number[20], const char b_imsi[20]);

或者喜欢

void conv_virgin( const char original_number[static 20], char normalised_number[static 20], const char b_imsi[static 20]);

【讨论】:

  • ""||whatever 不会产生 strcmp 所需的字符指针,因此它不会在理智、兼容的编译器上干净地编译。
  • ||strlen (b_imsi)&lt;6 显然是要插入到==0 之后,但添加它的人却放错了位置。事实上,这甚至不应该编译。但整个情况是荒谬的。
猜你喜欢
  • 1970-01-01
  • 2019-09-05
  • 1970-01-01
  • 2011-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-25
相关资源
最近更新 更多