GCC에서 '문자열 상수에서 'char*''로의 더 이상 사용되지 않는 변환 경고를 제거하는 방법은 무엇입니까?
문제
그래서 저는 매우 큰 코드베이스를 작업하고 있으며 최근에 gcc 4.3으로 업그레이드했는데 이제 다음 경고가 발생합니다.
경고:문자열 상수에서 'char*'로의 더 이상 사용되지 않는 변환
분명히 이 문제를 해결하는 올바른 방법은 다음과 같은 모든 선언을 찾는 것입니다.
char *s = "constant string";
또는 다음과 같은 함수 호출:
void foo(char *s);
foo("constant string");
그리고 그것들을 만들어 const char
포인터.그러나 이는 최소 564개의 파일을 만지는 것을 의미하며, 이는 현재 시점에서 수행하고 싶은 작업이 아닙니다.지금 문제는 내가 -werror
, 따라서 이러한 경고를 억제할 방법이 필요합니다.어떻게 해야 합니까?
해결책
나는 합격을 믿는다 -Wno-write-strings
gcc로 설정하면 이 경고가 표시되지 않습니다.
다른 팁
문자열 리터럴을 전달하는 모든 함수 "I am a string literal"
사용해야한다 char const *
대신 유형으로 char*
.
뭔가를 고칠 거라면 제대로 고치세요.
설명:
문자열 리터럴은 유형이기 때문에 수정될 문자열을 초기화하는 데 사용할 수 없습니다. const char*
.나중에 수정하기 위해 불변성을 버리는 것은 정의되지 않은 동작, 따라서 귀하는 const char*
문자열 char
~에 의해 char
동적으로 할당됨 char*
문자열을 수정하기 위해.
예:
#include <iostream>
void print(char* ch);
void print(const char* ch) {
std::cout<<ch;
}
int main() {
print("Hello");
return 0;
}
gcc를 확인해보세요 진단 프라그마 지원 및 목록 -W 경고 옵션 (변경됨: 경고 옵션에 대한 새 링크).
gcc의 경우 다음을 사용할 수 있습니다. #pragma warning
설명과 같은 지시어 여기.
비슷한 문제가 있었는데 다음과 같이 해결했습니다.
#include <string.h>
extern void foo(char* m);
int main() {
// warning: deprecated conversion from string constant to ‘char*’
//foo("Hello");
// no more warning
char msg[] = "Hello";
foo(msg);
}
이 문제를 해결하는 적절한 방법입니까?액세스할 수 없습니다. foo
받아들이도록 적응시키다 const char*
, 비록 그것이 더 나은 해결책이 될지라도 (왜냐하면 foo
변하지 않는다 m
).
활성 코드 베이스인 경우에도 코드 베이스를 업그레이드할 수 있습니다.물론 수동으로 변경을 수행하는 것은 불가능하지만 이 문제는 단 한 번의 조치로 완전히 해결될 수 있다고 믿습니다. sed
명령.하지만 나는 그것을 시도하지 않았으므로 소금 한알로 다음을 따르십시오.
find . -exec sed -E -i .backup -n \
-e 's/char\s*\*\s*(\w+)\s*= "/char const* \1 = "/g' {} \;
이렇게 하면 모든 위치를 찾을 수 없을 수도 있지만(함수 호출을 고려하지 않더라도) 문제를 완화하고 나머지 몇 가지 변경 사항을 수동으로 수행할 수 있습니다.
컴파일러 스위치를 사용할 수 없습니다.그래서 나는 이것을 다음과 같이 바꾸었습니다.
char *setf = tigetstr("setf");
이에:
char *setf = tigetstr((char *)"setf");
다음은 파일에서 인라인으로 수행하는 방법이므로 Makefile을 수정할 필요가 없습니다.
// gets rid of annoying "deprecated conversion from string constant blah blah" warning
#pragma GCC diagnostic ignored "-Wwrite-strings"
나중에 할 수 있습니다...
#pragma GCC diagnostic pop
바꾸다
char *str = "hello";
~와 함께
char *str = (char*)"hello";
또는 함수를 호출하는 경우:
foo("hello");
이것을로 바꾸십시오
foo((char*) "hello");
대신에:
void foo(char *s);
foo("constant string");
이것은 작동합니다:
void foo(const char s[]);
foo("constant string");
C++에서는 const_cast
아래와 같이
char* str = const_cast<char*>("Test string");
Test string
const 문자열입니다.따라서 다음과 같이 해결할 수 있습니다.
char str[] = "Test string";
또는:
const char* str = "Test string";
printf(str);
왜 타입 캐스팅을 사용하지 않는 걸까요?
(char*) "test"
상수 문자열에서 char 포인터로 타입 캐스팅을 수행합니다. 즉,
char *s = (char *) "constant string";
C++에서는 다음을 바꿉니다.
char *str = "hello";
와 함께:
std::string str ("hello");
그리고 비교하고 싶다면:
str.compare("HALLO");
귀하의 솔루션을 적용하는 방법을 이해할 수 없습니다 :( – kalmanIsAGameChanger
Arduino Sketch를 사용하면서 경고를 발생시키는 기능이 있었습니다.
원래 기능:char StrContains(char *str, char *sfind)
경고를 중지하려면 다음을 추가했습니다. const char *str 및 char *sfind 앞에.
수정됨:char StrContains(const char *str, const char *sfind).
모든 경고가 사라졌습니다.
이 상황을 참조하십시오 :
typedef struct tagPyTypeObject
{
PyObject_HEAD;
char *name;
PrintFun print;
AddFun add;
HashFun hash;
} PyTypeObject;
PyTypeObject PyDict_Type=
{
PyObject_HEAD_INIT(&PyType_Type),
"dict",
dict_print,
0,
0
};
이름 필드를 보세요. gcc에서는 경고 없이 컴파일되지만 g++에서는 그렇게 됩니다. 이유는 모르겠습니다.
다음을 호출하여 문자열 상수에서 쓰기 가능한 문자열을 만들 수도 있습니다. strdup()
.
예를 들어 다음 코드는 경고를 생성합니다.
putenv("DEBUG=1");
그러나 다음 코드는 그렇지 않습니다(문자열을 문자열에 전달하기 전에 힙에 복사본을 만듭니다). putenv
):
putenv(strdup("DEBUG=1"));
이 경우(그리고 아마도 대부분의 다른 경우에도) 경고를 끄는 것은 좋지 않은 생각입니다. 거기에는 이유가 있습니다.다른 대안(기본적으로 모든 문자열을 쓸 수 있게 만드는 것)은 잠재적으로 비효율적입니다.
컴파일러가 말하는 것을 들어보세요!
g++에는 -w 옵션을 사용하세요.
예:
g++ -w -o simple.o simple.cpp -lpthread
이는 지원 중단을 방지하는 것이 아니라 터미널에 경고 메시지가 표시되는 것을 방지한다는 점을 기억하세요.
이제 정말로 지원 중단을 피하고 싶다면 다음과 같이 const 키워드를 사용하세요.
const char* s="constant string";
왜 사용하지 않습니까? -Wno-deprecated
더 이상 사용되지 않는 경고 메시지를 무시하는 옵션이 있습니까?
지금 문제는 -Werror를 실행하고 있다는 것입니다.
이것이 당신의 진짜 문제입니다, IMO.(char *)에서 (const char *)로 이동하는 자동화된 방법을 시도해 볼 수 있지만 단순히 작동하는 것이 아니라 여기에 돈을 투자할 것입니다.적어도 일부 작업에는 사람이 참여해야 합니다.단기적으로는 경고를 무시하고(그러나 IMO는 경고를 켜두지 않으면 절대 수정되지 않음) -Werror를 제거합니다.
도움을 주셔서 감사합니다.여기저기서 선택하면 이 솔루션이 나옵니다.이것은 깨끗하게 컴파일됩니다.아직 코드를 테스트하지 않았습니다.내일...아마도...
const char * timeServer[] = { "pool.ntp.org" }; // 0 - Worldwide
#define WHICH_NTP 0 // Which NTP server name to use.
...
sendNTPpacket(const_cast<char*>(timeServer[WHICH_NTP])); // send an NTP packet to a server
...
void sendNTPpacket(char* address) { code }
알아요. timeServer 배열에는 항목이 1개뿐입니다.하지만 그 이상이 있을 수 있습니다.나머지는 지금은 메모리 절약을 위해 주석 처리되었습니다.
BlackShift의 답변은 매우 유용하며 다음과 같이 사용했습니다.
extern string execute(char* cmd) {
FILE* pipe = popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[256];
std::string result = " ";
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
return result;
}
int main(){
char cmd[]="grep -A1 'xml' out1.txt | grep read|awk -F'=' 'BEGIN{sum=0}{sum=sum+$NF}END{print sum}'";
string result=execute(cmd);
int numOfBytes= atoi(result.c_str());
cout<<"Number of bytes = "<<numOfBytes<<endl;
return 0;
}
PyTypeObject PyDict_Type=
{ ...
PyTypeObject PyDict_Type=
{
PyObject_HEAD_INIT(&PyType_Type),
"dict",
dict_print,
0,
0
};
이름 필드를 보세요. gcc에서는 경고 없이 컴파일되지만 g++에서는 그렇게 됩니다. 이유는 모르겠습니다.
~에 gcc (Compiling C)
, -Wno-write-strings는 기본적으로 활성화됩니다.
~에 g++ (Compiling C++)
-Wwrite-strings는 기본적으로 활성화되어 있습니다.
이것이 다른 행동이 나타나는 이유입니다.매크로를 사용하는 우리의 경우 Boost_python
그런 경고를 생성합니다.그래서 우리는 -Wno-write-strings
C++를 컴파일할 때 우리는 항상 다음을 사용하기 때문에 -Werror