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와 멀리 캐스팅 것은 정의되지 않은 동작 당신이 당신의 복사해야하므로, 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;
}
비슷한 문제가 있었는데 다음과 같이 해결했습니다.
#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
.
gcc의 진단 Pragma 지원 및 -W 경고 옵션 목록 (변경된 : 경고 옵션에 대한 새로운 링크 )을 확인하십시오.
gcc의 경우 here#pragma warning
설명과 같은 지시문 을 사용할 수 있습니다 .
활성 코드 기반 인 경우 여전히 코드 기반을 업그레이드 할 수 있습니다. 물론 수동으로 변경을 수행하는 것은 불가능하지만이 문제는 한 번의 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)
경고를 멈추기 위해 char * str과 char * sfind 앞에 const 를 추가했습니다 .
수정 : 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 -lp 스레드
이것은 사용 중단을 피하는 것이 아니라 터미널에 경고 메시지를 표시하지 않도록합니다.
사용 중단을 방지하려면 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 배열에 하나의 항목 만 있다는 것을 알고 있습니다. 그러나 더있을 수 있습니다. 나머지는 메모리를 절약하기 위해 현재 주석 처리되었습니다.
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;
}
문자열을 선언 const
하면 문제가 해결됩니다.
char const*s = "constant string";
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
'Programming' 카테고리의 다른 글
JavaScript를 사용하여 JSON 속성에 새 속성 (요소) 추가 (0) | 2020.02.21 |
---|---|
Heroku + node.js 오류 (웹 프로세스가 시작 후 60 초 내에 $ PORT에 바인딩하지 못했습니다) (0) | 2020.02.21 |
Laravel에는 Mcrypt PHP 확장이 필요합니다 (0) | 2020.02.21 |
MySQL에서 하나를 제외한 모든 중복 행을 삭제 하시겠습니까? (0) | 2020.02.21 |
문자열의 첫 글자를 대문자로 만듭니다 (성능 극대화). (0) | 2020.02.21 |