Почему GCC принимает преобразование из ‘const char *’ в ‘char *’ в возвращаемом значении std :: strrchr ()?

При добавлении подробный ответ, Я заметил, что 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 в Red Hat (Linux)
  • 4.5.3 на Cygwin (Windows)
  • 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 / … для тестирования с использованием других версий)

Как этот код использует станд :: strrchr, Я не понимаю, почему GCC не жалуется.

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

Мой вопрос: Почему g ++ успешно компилирует этот код без предупреждения / ошибки? Это ошибка? особенность? неправильная конфигурация на моей стороне?

1

Решение

На самом деле ваш g ++ не принимает преобразование из ‘const char *кchar *«Просто на вашей версии std::strrchr() возвращает char* (неправильно, вместо 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 сообщение показывает ожидаемые перегрузки «все неконстантные» и «все константные»:

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 но это та же история).

1

Другие решения

Других решений пока нет …

А ты уже прошел курс программирования? Супер скидка!
Прокачать скилл $$$
×