GCC에서 '문자열 상수에서 'char*''로의 더 이상 사용되지 않는 변환 경고를 제거하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/59670

  •  09-06-2019
  •  | 
  •  

문제

그래서 저는 매우 큰 코드베이스를 작업하고 있으며 최근에 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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top