2014-12-27 27 views
1

我讀的標準,但仍不能確定:我可以在此函數中使用限定符限定符嗎?

#include <stdio.h> 
#include <string.h> 

void repl(char *restrict ap){ 
    char *cp=strchr(ap,(int)'m'); 
    *cp='M'; 
} 

int main(){ 
    char arr[] = "example"; 
    repl(arr); 
    puts(arr); 
    return 0; 
} 

在功能repl,我以前strchr得到另一個指針修改的對象。我期望的結果是用M代替第一個m的字符串。

但這可能是未定義的行爲?

如果是,那麼使用ap[cp-ap]='M';而不是*cp='M';

+0

是的,但在這種情況下並沒有表明任何東西。 AFAICT,您需要在參數列表中使用兩個指針變量才能發揮作用。我看不出任何會破壞你所展示的代碼的限制。 –

+0

文字如'm''已經有'int'類型。所以不需要施放它們,無論如何,即使類型不同,無論如何,演員陣容並不是一個好主意。 –

回答

0

它不是未定義的行爲,因爲指針cp是從指針變量ap派生的。

編譯器如何知道cp是從p派生的?它不必知道。首先,編譯器是否知道該行爲是否已定義或未定義。規則不是「如果編譯器知道......」,規則是「如果cp是從ap派生的」。

只要編譯器無法證明cp不是來自ap,它必須提供完全相同的語義,就好像您沒有使用restrict關鍵字一樣。

+1

我能否對編譯器知道「cp」是從「ap」(而不是不相關的源代碼)派生出來有點好奇? :) – cshu

2

別名規則允許通過其自己的類型或字符類型(包括其有符號/無符號變體)來訪問任何變量。這意味着*cp='M';是指定的行爲,沒有任何特殊的預防措施,因爲*cp是字符類型。

在一個不同的主題,你不需要(int)'m''m''m'已經int類型的C.

+0

你是對的,我剛剛意識到文字是'int'類型。謝謝。其實我問這個問題是因爲我擔心編譯器可能不知道'cp'和'ap'之間的關係,只是簡單地相信''example''是永遠不會被修改的。 – cshu

+0

@ouah你是說char/unsigned char指針允許別名限制指針嗎? (如果是這樣,strcpy()的參數有什麼限制?) – nos

+3

@nos'restrict'在'strcpy'中用作提示(用於優化目的)來通知編譯器兩個指針不是別名。 C允許'char *'別名任何其他指針。 – ouah

0

我有你的restrict修正錯誤的目的的印象。這是函數調用者必須提供的保證,即該對象不能通過任何其他指針訪問,並且不會通過使用這樣的另一個指針來意外修改。所以使用restrict合格的指針不會導致UB。

另外在你的情況下,你正在傳遞這樣一個指針到一個函數。之後,編譯器不能再假設指針不會別名,例如對全局變量或函數返回的指針。 (它實際上是)

舉一個例子,它不是具有UB的功能memcpy。但是,如果兩個指針指向重疊的對象,那麼對memcpy的調用沒有定義行爲。

相關問題