2013-06-04 10 views
1

detailed answer을 추가하는 동안 Visual C++에서 불평하는 동안 GCC가 다음 코드를 경고하지 않는 것으로 나타났습니다. 레드햇 (리눅스)의 Cygwin에 GCC가 std :: strrchr() 반환 값에서 'const char *'에서 'char *'로의 변환을 허용하는 이유는 무엇입니까?

  • 4.5.3 (윈도우)는 MinGW에
  • 4.7.2 (에

    • 4.1.2 : 나는 세 가지 다른 GCC 버전을 테스트 한

      #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 버전 :

    ,536,913 63,210
    > 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/codepad/...에 액세스 할 수 없습니다) 코드는 std::strrchr을 사용합니다. 왜 GCC가 불평하지 않는지 이해할 수 없습니다.

    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의 ++는 'char *'에서 'const char *'에서 변환을 허용하지 않습니다, 그것은 char* (잘못, 대신 const char*의) 반환 std::strrchr() 버전에 그것은 단지입니다.

    내 문장의 첫 부분을 확인하려면, 당신의 GCC 버전에서 다음을 컴파일하려고, 나는 모든 올바르게 오류가 발행 할 것이라고 예측 : 두 번째 부분에 대해 지금

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

    을, 나는 컴파일하려고

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

    W : 실제의 목적은 다음의 최소 코드 목록 순서 트리거 오류로 선언의 과부하 std::strrchr 엘, gcc 4.7.2로 메시지를 보여줍니다 예상 "모든 const가 아닌가"와 "모든 CONST는"오버로드 :

    : 프로토 타입

     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: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) 
    

    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) 
    

    즉오버로드는

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

    이었다 (있지만 첫번째 이전 C 버전이며, 대신 C++ CONST 과부하되어야 번째는 C++ 비 CONST 과부하이다).

    이것은이 버전에서 헤더 (<cstring> 및/또는 <string.h>)가 잘못되어있는 것으로 보이며, 귀하의 것과 동일하다고 생각됩니다.


    편집 : 나는 (strchr하지 strrchr에 대한하지만 같은 이야기) 예 A discussion하는 blog postbug report에 대한 발견했다.

    +0

    완벽한 ;-) 아주 아주 좋은 대답. 모든 세부 사항을 주셔서 감사합니다. 모든 것이 명확합니다 .-D 건배 – olibre