Programming

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

procodes 2020. 2. 21. 22:34
반응형

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


그래서 나는 매우 큰 코드베이스로 작업하고 있으며 최근에 gcc 4.3으로 업그레이드되어 이제이 경고를 트리거합니다.

경고 : 문자열 상수에서 'char *'로의 더 이상 사용되지 않는 변환

분명히 이것을 고치는 올바른 방법은 다음과 같은 모든 선언을 찾는 것입니다.

char *s = "constant string";

또는 함수 호출 :

void foo(char *s);
foo("constant string");

그리고 그것들을 const char포인터로 만드십시오 . 그러나 이것은 최소 564 파일을 만지는 것을 의미합니다.이 시점에서 수행하려는 작업이 아닙니다. 지금 문제는와 함께 실행 -werror중이므로 이러한 경고를 억제 할 방법이 필요하다는 것입니다. 어떻게해야합니까?


-Wno-write-stringsgcc에 전달 하면이 경고가 표시되지 않습니다.


문자열 리터럴을 전달하는 모든 함수 "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 stringconst 문자열입니다. 따라서 다음과 같이 해결할 수 있습니다.

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

참고 URL : https://stackoverflow.com/questions/59670/how-to-get-rid-of-deprecated-conversion-from-string-constant-to-char-warnin



반응형