繁体   English   中英

什么会导致HP-UX和LINUX for C ++应用程序的返回值不同?

[英]What could cause return values to differ between HP-UX and LINUX for C++ application?

在将HP-UX C ++应用程序移植到LINUX的过程中,我注意到有一个int类型的函数,其中并非所有代码路径都似乎返回整数值。 当我在HP-UX下编译并运行应用程序时(使用acc编译器进行编译),它通过未明确声明返回值的代码路径返回0。 但是,当我在LINUX下编译并运行相同的应用程序时,我得到一个返回值-72,并且该应用程序因此出现错误(这是在返回值小于0时使用的)。 我注意到,经典C ++(ACC编译器支持的一个非常老旧且过时的标准)在处理变量作用域方面与标准C ++(不幸的是,ACC不支持)有所不同。 在经典的C ++中,似乎在forloop声明中声明了一个整数

for( int index = 0; index < array.length; index++ )

可以在forloop外部访问变量索引,尽管我不确定是否可以以相同的方式处理return语句,以便aCC识别所有代码路径都返回一个值。

我正在处理的功能如下:

int process_phase (const char *phase, const char *seg_type, const char *dist_target, const char *action_target, char *cmd) 
{
  char cmd2[MAX_STRING];

  printf( "I AM INSIDE THE PROCESS_PHASE\n" );

  if (TRACE_MODE) 
  {
    printf ("%s %s\n", MSG_LOOKUP("MSG_PHASE"), phase);
    printf ("%s %s\n", MSG_LOOKUP("MSG_SEG_TYPE"), seg_type);
    printf ("%s %s\n", MSG_LOOKUP("MSG_DIST_TARGET"), dist_target);
    printf ("%s %s\n", MSG_LOOKUP("MSG_ACTION_TARGET"), action_target);
    printf ("%s %s\n", MSG_LOOKUP("MSG_CMD"), cmd);
  }

  // Remove the pre- and post- prefixes
  const char *phase_ref = strchr(phase, '-');

  printf ("PHASE REF BEFORE PREFIX REMOVAL: %s\n", phase_ref );

  if (phase_ref) 
  {
    phase_ref++; 
  }
  else
  {
    phase_ref = phase;
  }

  printf ("PHASE REF AFTER PREFIX REMOVAL: %s\n", phase_ref );

  if (TRACE_MODE)
  {
    printf ("%s %s\n", MSG_LOOKUP("MSG_PHASE_REF"), phase_ref);
  }

  printf ( "==========TEST PHASE 1 BEGIN==========\n" );

  if (strcasecmp(phase_ref, "all_phases") != 0) 
  {
    if (DO_TRANSFER && strcasecmp(phase_ref, "transfer") != 0) 
    {
      printf ("IN ONE\n");
      return 0;
    }
    else if (DO_TAPE_GENERATION && strcasecmp(phase_ref, "tape_generation") != 0) 
    {
      printf ("IN TWO\n");
      return 0;
    }
    else if (DO_TAPE_EXTRACTION && strcasecmp(phase_ref, "tape_extraction") != 0) 
    {
      printf ("IN THREE\n");
      return 0;
    }
    else if (DO_PREPARATION && strcasecmp(phase_ref, "preparation") != 0)
    {
      printf ("IN FOUR\n");
      return 0;
    }
    else if (DO_DISTRIBUTION && strcasecmp(phase_ref, "distribution") != 0)
    {
      printf ("IN FIVE\n");
      return 0;
    }
    else if (DO_VERIFICATION && strcasecmp(phase_ref, "verification") != 0)
    { 
      printf ("IN SIX\n");
      return 0;
    }
    else if (DO_ACTIVATION && strcasecmp(phase_ref, "activation") != 0) 
    {
      printf ("IN SEVEN\n");
      return 0;
    }
    else if (DO_REMOVAL && strcasecmp(phase_ref, "removal") != 0)
    {
      printf ("IN EIGHT\n");
      return 0;
    }
  }

  printf ( "==========TEST PHASE 1 END==========\n" );

  // if (strstr(seg_type, envvar("SEGMENT_TYPE")) == 0 && strcasecmp(seg_type, "ALL") !=0) return 0;
  char tmp_seg_type[MAX_BUFFLEN];
  sprintf (tmp_seg_type, "_%s_", seg_type);

  printf( "tmp_seg_type: %s\n", tmp_seg_type );

  char tmp_envar_seg_type[MAX_BUFFLEN];
  sprintf (tmp_envar_seg_type, "_%s_", envvar("SEGMENT_TYPE"));

  printf( "tmp_seg_type: %s\n", tmp_seg_type );

  if ( strstr(tmp_seg_type, tmp_envar_seg_type) == 0 && strcasecmp(seg_type, "ALL") != 0 )
  {
    printf( "IN TEST PHASE TWO\n" );
    return 0;
  }

  char match_list[MAX_BUFFLEN];

  printf ( "==========TEST PHASE THREE BEGIN==========\n" );

  if ( DO_TRANSFER ) 
  {
    printf( "IN ONE\n" );
    sprintf( match_list, "DIST_NODES", dist_target );
  }
  else if (DO_TAPE_GENERATION) 
  {
    printf( "IN TWO\n" );
    sprintf( match_list, "HOST_NODES", dist_target );
  }
  else
  {
    printf( "IN THREE\n" );
    sprintf( match_list, "%s_NODES", dist_target );
    printf( "match_list: %s\n", match_list );
  }

  printf ( "==========TEST PHASE THREE END==========\n" );

  char matched_nodes[MAX_BUFFLEN];
  get_env(match_list, matched_nodes);

  printf( "matched_nodes: %s\n", matched_nodes );

  word_sort_unique(matched_nodes);

  printf( "sorted_matched_nodes: %s\n", matched_nodes );

  const char *element_separator = " ";
  const char *curr_node_type;
  char *curr_node = strtok(matched_nodes, element_separator);

  printf( "curr_node: %s\n", curr_node );

  int whileiteration = 0;

 while (curr_node) 
 {
    printf( "WHILE LOOP ITERATION: %d\n", whileiteration );

    int node_idx;
    bool matched = false;

    for (node_idx=0; node_idx<node_count; node_idx++) 
    {
      if (strcmp(curr_node, node_table[node_idx]) == 0) 
      {
        matched = true;
        break;
      }
    }

    if (matched) 
    {
      if (strcasecmp(action_target, "TARGET") == 0) 
      {
        if (indent[node_idx][0] == 0) 
        {
          fprintf (outfile[node_idx], "remsh %s \"\n", curr_node);
          indent[node_idx] = "  ";
          fprintf (outfile[node_idx], "%s. %s/site_profile\n", indent[node_idx], envvar ("TOOLS_DIR"));
          fprintf (outfile[node_idx], "%s. %s/install_profile\n", indent[node_idx], envvar ("TOOLS_DIR"));
          fprintf (outfile[node_idx], "%sexport LANG=%s\n", indent[node_idx], envvar ("LANG"));
        }
      } 
      else 
      {
        // Input redirection from /dev/echo enables that the ports reserved for remsh on both client and
        // server node get released immediately without any inactivity timeout period
        if (indent[node_idx][0] != 0) 
        {
          fprintf (outfile[node_idx], "\" < /dev/echo \n");
        }
        indent[node_idx] = "";
      }

      // Do parameter substitution
      strcpy(cmd2, cmd);
      expand_string (cmd2, "$BUILD_VERSION", BUILD_VERSION);
      expand_string (cmd2, "${BUILD_VERSION}", BUILD_VERSION);
      expand_string (cmd2, "$TARGET_NODE", curr_node);
      expand_string (cmd2, "${TARGET_NODE}", curr_node);
      curr_node_type = target_lookup (curr_node);      
      expand_string (cmd2, "$NODE_TYPE", curr_node_type);
      expand_string (cmd2, "${NODE_TYPE}", curr_node_type);

      fprintf(outfile[node_idx], "%s%s\n", indent[node_idx], cmd2);
      file_active[node_idx] = true;
    }
    curr_node = strtok(NULL, element_separator);

    whileiteration++;
  }
  printf ( "EXITING PROCESS PHASE\n" );
}

我使用代码工具在HP-UX和LINUX上打印出变量和其他输出,直到while循环为止,并且它们看起来是相同的。 在某些情况下,即使由于变量curr_node为空而退出了while循环并且退出了函数(在EXITING PROCESS PHASE打印到stdout的情况下)时,HP-UX和LINUX的输出也相同。 但是,HP-UX和LINUX之间的返回值完全不同。 我不知道是为什么。

您说函数的一个分支“未明确声明返回值”。 这是不需要编译器为您诊断的错误。 在那种情况下,行为是不确定的。 在一个平台上始终获得负面结果只是意味着您很幸运(或者很不幸,因为不同的值不会更早地暴露此错误)。

通常,有一个存储位置或寄存器指定要使用的返回值。 如果该函数不在那里存储任何内容,或者该函数使用该位置作为临时值,但从未在其中写入最终结果,则调用者将读取该位置并获取碰巧存在的任何值。 在您的情况下,Linux返回值的位置恰好保持-72,而HP-UX返回值的位置恰好保持零。 告知您的意图,并在所有代码路径中显式返回一个值。

返回值位置是否始终保持特定值通常会受到所讨论函数的动作以及它调用的函数的动作的影响。 小而简单的功能的行为并不一定能预测大功能的行为。

int值通常在寄存器中返回。 如果您实际上没有返回任何值,则该寄存器将包含先前计算中剩余的一些随机值。

如果到达此函数的末尾,则将从上一个printf返回一个返回值,该返回值可能会传递到下一个级别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM