[英]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.