1

在添加详细答案时,我注意到 GCC 在 Visual C++ 抱怨时不会警告以下代码。

#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 版本:

  • 4.1.2 在红帽 (Linux) 上
  • Cygwin (Windows) 上的 4.5.3
  • 4.7.2 在 MinGW (Windows) 上

但是所有这三个 GCC 版本都编译了这段代码,没有任何警告/错误:

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

虽然 Microsoft 编译器 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++ 成功编译此代码而没有任何警告/错误?它是一个错误吗?一个特征?我这边配置错误?

4

1 回答 1

1

实际上,您的 g++ 不接受从 ' const char *' 到 ' char *' 的转换,只是在您的版本上std::strrchr()返回 a char*(错误地,而不是 a const 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() {}

好吧,在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)

即重载是

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

(第二个是 C++ 非常量重载;但第一个是旧C 版本,应该是 C++ const 重载)。

看来这个版本的标题(<cstring>和/或<string.h>)不正确,我怀疑你的标题是一样的。


编辑:例如,我发现了一个讨论、一篇博客文章和一个错误报告(因为strchr不是strrchr,但它是同一个故事)。

于 2013-06-05T14:04:19.787 回答