2011-08-04 59 views
2

我在我的系統中安裝了frama-c。編譯器在創建目標代碼之前是否生成隱式轉換的代碼?

它做的事情,是我所有的代碼轉換爲使用C的所有隱式轉換更加擴大的形式..

(EG)
//我的實際代碼

if(opTab ==NULL || symTab ==NULL || intermediateFile==NULL || sourceCode ==NULL) 
{ 
    printf("\nError in opening file streams"); 
    exit(EXIT_FAILURE); 
} 

//郵資-C轉換代碼

if (opTab == (void *)0) { 
    printf((char const *)"\nError in opening file streams"); 
    exit(1); 
    } 
    else { 
    if (symTab == (void *)0) { 
     printf((char const *)"\nError in opening file streams"); 
     exit(1); 
    } 
    else { 
     if (intermediateFile == (void *)0) { 
     printf((char const *)"\nError in opening file streams"); 
     exit(1); 
     } 
     else { 
     if (sourceCode == (void *)0) { 
      printf((char const *)"\nError in opening file streams"); 
      exit(1); 
     } 
     } 
    } 
    } 

現在我的疑問是, 創建對象PROG之前RAM,是否C編譯器做所有隱式轉換?

OR

是否創建目標程序的過程中,這些隱式轉換是平行做了什麼?

OR

它是依賴於實現?如果是這樣,爲什麼?

回答

1

最有可能不是。我對frama-c不熟悉,但是您看到的轉換是源到源 - 即將C源作爲輸入,並將修改後的C源作爲輸出。顯然它的工作是讓代碼更加明確和冗長。

C編譯器通常不會執行那種源轉換。 (好吧,預處理器的確如此,但那是不同的。)

它會生成代碼來執行所需的任何轉換,但它會以機器語言或彙編語言或某種中間格式的形式執行。

舉一個簡單的例子,這樣的:

int n = 42; 
double x = n; 

從int執行隱式轉換上的x初始化翻番,但可能沒有在編譯過程將創建文本看起來像

double x = (double)n; 

C編譯器將C源代碼作爲輸入。他們通常不會將其作爲輸出生成。理論上他們可以,但他們沒有理由這麼做。

+0

我非常喜歡你的解釋。僅僅爲了澄清,Frama-C沒有'double double =(double)n;'在文本上不僅僅是編譯器。它有一個抽象語法樹,其中轉換是明確的(因爲大多數編譯器可能會這樣做,因爲標準說這就是'x = n;'的意思)。如果您要求將AST打印出來(例如,作爲調試的幫助),則轉換僅以文本形式顯示。 –

+0

@keith Thompson偉大的答案。謝謝 –

2

的第一個參數是printf類型const char*的,因此,如果包括作爲<stdio.h>你應該使用printf之前,轉換將被隱式地由編譯器執行。 (即,在這種情況下不需要演員)。

+0

ya,轉換是隱式的。我的疑問是編譯器在創建任何目標程序之前是否生成隱式轉換的代碼,或者是否逐行執行隱式轉換操作(在每行的目標代碼創建期間)。 –

+0

@EAGER_STUDENT :我不確定你的意思,但編譯器執行轉換的方式是它的選擇; C標準只保證產生的*行爲*。在任何情況下,const const限定符的添加很可能不會產生不同的目標代碼,因爲它是一個編譯時構造。 –

1

我是Frama-C開發人員之一。

你所看到的實際上是抽象語法樹的文本表示,它恰好是可編譯的C代碼。正如您注意到的,許多轉換都是明確的。就我們所知,並且有可能存在漏洞,添加這些轉換並不會改變程序的含義,因爲這些轉換是編譯器根據C99標準的6.3節(特別是6.3)所做的轉換。 1.8「通常的算術轉換」)。

如果打印好的代碼一旦編譯出來,就會給出與原始結果不同的結果,這是一個可以在the Frama-C bug tracker上報告的錯誤。