2013-06-04 117 views
1

在添加detailed answer時,我注意到在Visual C++抱怨時,GCC不會警告以下代碼。爲什麼GCC接受std :: strrchr()返回的值從'const char *'轉換爲'char *'?

#include <cstring> 
int main() 
{ 
    const char CONSTSTR[] = "foo/bar/foobar.txt"; 

    char *nonconst = std::strrchr (CONSTSTR, '/'); 
    // cannot convert from 'const char *' to 'char *' 

    *nonconst++ = 'B'; 
    *nonconst++ = 'A'; 
    *nonconst++ = 'D'; 
} 

我已經測試了三個不同版本的GCC:在Red Hat(Linux)的

  • 4.5.3在Cygwin(Windows)中
  • 4.7.2上的MinGW(

    • 4.1.2 Windows)

    但是所有這三個GCC版本都沒有任何警告/錯誤編譯了這段代碼:

    > g++ -Wall -Wextra -pedantic -ansi test.cpp && echo "success" 
    success 
    

    儘管微軟編譯器V16抱怨:

    > cl -c test.cpp 
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86 
    Copyright (C) Microsoft Corporation. All rights reserved. 
    
    test.cpp 
    test.cpp(5) : error C2440: 'initializing' : cannot convert from 'const char *' to 'char *' 
         Conversion loses qualifiers 
    

    (從我的辦公室,我沒有獲得ideone /鍵盤/ ...使用其他版本進行測試)

    由於這代碼使用std::strrchr,我不明白爲什麼海灣合作委員會不抱怨。

    const char* strrchr(const char* str, int ch); //the code above uses this declaration 
         char* strrchr(  char* str, int ch); 
    

    我的問題:爲什麼G ++成功編譯此代碼沒有任何警告/錯誤?這是一個錯誤嗎?一個特徵?我身邊的小姐配置?

  • +2

    奇怪... gcc 4.7.2 http://ideone.com/7rcwVE錯誤'錯誤:無效轉換從'const char *'到'char *'[-fpermissive]'但是gcc 4.3.2 http:/ /ideone.com/fDdZ08沒有錯誤。舊的編譯器錯誤?你可以嘗試'g ++ -Wall -Wextra -pedantic -ansi file.cpp'(或這些選項的子集)嗎? –

    +1

    那麼問題是什麼?另外,我的GCC版本(4.6.3)確實會給出預期的錯誤。 –

    回答

    1

    其實你的G ++不接受「const char *」到「char *」的轉換,它只是在你的版本std::strrchr()返回(填錯,而不是const char*)一char*

    爲了驗證我的發言的第一部分,嘗試編譯你的版本的GCC下面,我預測,一切都會正常發出一個錯誤:

    int main() 
    { 
        const char* p = "foo"; 
        char* q = p; // error, invalid conversion from 'const char*' to 'char*' 
    } 
    

    現在的第二部分,我試圖編譯下面最少的代碼,其實際目的是爲了觸發錯誤列表聲明重載std::strrchr

    #include <cstring> 
    void (*p)() = &std::strrchr; // error here, with "candidates are: ..." 
    int main() {} 
    

    w^ELL,與gcc 4.7.2消息顯示預期 「的所有非const」 和 「所有的常量」 超載:

    prog.cpp:2:21: error: no matches converting function ‘strrchr’ to type ‘void (*)()’ 
    In file included from /usr/include/c++/4.7/cstring:44:0, 
           from prog.cpp:1: 
    /usr/include/string.h:249:1: error: candidates are: char* strrchr(char*, int) 
    /usr/include/string.h:255:1: error:     const char* strrchr(const char*, int) 
    

    即原型

     char* strrchr(  char* , int); 
    const char* strrchr(const char* , int); // Question's code will use this one (-> error) 
    

    但隨着gcc 4.3.2的信息是不同的:

    prog.cpp:2: error: no matches converting function 'strrchr' to type 'void (*)()' 
    /usr/include/string.h:171: error: candidates are: char* strrchr(const char*, int) 
    /usr/include/c++/4.3/cstring:118: error:     char* std::strrchr(char*, int) 
    

    ie重載是

     char* strrchr(const char* , int); // Question's code would use this one (-> no error...) 
         char* strrchr(  char* , int); 
    

    (第二個是C++非const超載;但第一個是舊C版,而應是C++常量過載)。

    這看起來似乎這個標題(<cstring>和/或<string.h>)在這個版本上是不正確的,我懷疑它在你的上是一樣的。


    編輯:我發現例如discussion,一個blog postbug report(爲strchr沒有strrchr,但它是相同的故事)。

    +0

    完美;-)非常好的答案。謝謝你的所有細節,現在每件事情都很清楚:-D乾杯 – olibre

    相關問題