代码之家  ›  专栏  ›  技术社区  ›  Josh Matthews

如何消除GCC中“从字符串常量到字符*”的不推荐转换警告?

  •  394
  • Josh Matthews  · 技术社区  · 16 年前

    因此,我正在开发一个非常大的代码库,最近升级到gcc 4.3,它现在触发了以下警告:

    警告:不推荐将字符串常量转换为字符*

    char *s = "constant string";
    

    或函数调用,如:

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

    const char 指针。然而,这意味着至少要处理564个文件,这不是我现在希望执行的任务。现在的问题是我在和 -werror ,所以我需要一些方法来压制这些警告。我该怎么做?

    23 回复  |  直到 8 年前
        1
  •  576
  •   johnthagen Matthew Scharley    6 年前

    向其中传递字符串文字的任何函数 "I am a string literal" char const * 作为类型而不是 char* .

    您不能使用字符串文字来初始化将被修改的字符串,因为它们属于 const char* . 丢弃常量以稍后修改它们是非常重要的 undefined behaviour 常量字符* char 通过 烧焦 煤焦* 字符串,以便修改它们。

    例子:

    #include <iostream>
    
    void print(char* ch);
    
    void print(const char* ch) {
        std::cout<<ch;
    }
    
    int main() {
        print("Hello");
        return 0;
    }
    
        2
  •  237
  •   Tim Cooper    13 年前

    我相信传球 -Wno-write-strings

        3
  •  72
  •   LogicStuff    9 年前

    我有一个类似的问题,我是这样解决的:

    #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* m

        4
  •  68
  •   Community Nick Dandoulakis    7 年前

    查看gcc的 Diagnostic Pragma -W warning options (更改为: new link to warning options ).

    对于gcc,您可以使用 #pragma warning here .

        5
  •  33
  •   Konrad Rudolph    16 年前

    如果它是活动的代码库,您可能仍然希望升级代码库。当然,手动执行更改是不可行的,但我相信这个问题可以通过一个单一的方法一次性解决 sed

    find . -exec sed -E -i .backup -n \
        -e 's/char\s*\*\s*(\w+)\s*= "/char const* \1 = "/g' {} \;
    

        6
  •  27
  •   EdH    13 年前

    下面是如何在文件中内联执行此操作,这样您就不必修改Makefile。

    // gets rid of annoying "deprecated conversion from string constant blah blah" warning
    #pragma GCC diagnostic ignored "-Wwrite-strings"
    

    #pragma GCC diagnostic pop
    
        7
  •  26
  •   LogicStuff    9 年前

    代替

    char *str = "hello";
    

    具有

    char *str = (char*)"hello";
    

    foo("hello");
    

    替换为

    foo((char*) "hello");
    
        8
  •  25
  •   vy32    15 年前

    我不能使用编译器开关。所以我把这个翻过来:

    char *setf = tigetstr("setf");
    

    为此:

    char *setf = tigetstr((char *)"setf");
    
        9
  •  15
  •   gipinani    10 年前

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

    这项工作:

    void foo(const char s[]);
    foo("constant string");
    
        10
  •  14
  •   LogicStuff    9 年前

    在C++中,使用 const_cast 如下

    char* str = const_cast<char*>("Test string");
    
        11
  •  7
  •   Sicco    12 年前

    Test string 是常量字符串。所以你可以这样解决:

    char str[] = "Test string";
    

    或:

    const char* str = "Test string";
    printf(str);
    
        12
  •  4
  •   LogicStuff    9 年前

    (char*) "test"
    
        13
  •  2
  •   LogicStuff    9 年前

    从常量字符串到字符指针进行类型转换,即。

    char *s = (char *) "constant string";
    
        14
  •  1
  •   Sohrab    7 年前

    在C++中,替换:

    char *str = "hello";
    

    与:

    std::string str ("hello");
    

    如果你想比较一下:

    str.compare("HALLO");
    
        15
  •  1
  •   MyGEARStationcom    6 年前

    使用Arduino Sketch时,我有一个函数导致我的警告。

    原始函数:char StrContains(char*str,char*sfind)

    为了停止警告,我添加了 在char*str和char*sfind前面。

    修改:字符StrContains(const char*str,const char*sfind)。

    所有的警告都消失了。

        16
  •  0
  •   svick Raja Nadar    13 年前

    看到这种情况:

    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++中它会编译,我不知道为什么。

        17
  •  0
  •   Jason Plank Steve Leung    13 年前

    您还可以通过调用 strdup()

    例如,此代码生成一个警告:

    putenv("DEBUG=1");
    

    但是,下面的代码没有(它在将字符串传递给 putenv ):

    putenv(strdup("DEBUG=1"));
    

    在这种情况下(也许在大多数其他情况下),关闭警告是一个坏主意——这是有原因的。另一种选择(默认情况下使所有字符串都可写)可能效率低下。

    听编译器告诉你的!

        18
  •  0
  •   Md. Arafat Al Mahmud    12 年前

    只需对g使用-w选项++

    g++-w-o simple.o simple.cpp-lpthread

    现在,如果您真的想避免弃用,请使用以下const关键字:

    const char* s="constant string";  
    
        19
  •  0
  •   Drew Noakes    11 年前

    你为什么不使用 -Wno-deprecated 忽略不推荐的警告消息的选项?

        20
  •  0
  •   Micheal Morrow    8 年前

    谢谢大家的帮助。从这里选择,那里就有了这个解决方案。这编译得很干净。尚未测试代码。明天大概

    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阵列中只有一项。但可能还有更多。其余部分暂时被注释掉以节省内存。

        21
  •  0
  •   AAEM Niklas B.    4 年前

    路过时 string constants 要将其编写为:

    void setpart(const char name[]);
    
    setpart("Hello");
    

    而不是 const char name[] ,你也可以写 const char \*name

    [Warning] deprecated conversion from string constant to 'char*' [-Wwrite-strings]
    
        22
  •  -1
  •   Rathakrishnan Ramasamy micky    12 年前
    PyTypeObject PyDict_Type=
    { ...
    
    PyTypeObject PyDict_Type=
    {
      PyObject_HEAD_INIT(&PyType_Type),
                         "dict",
                         dict_print,
                         0,
                         0
    }; 
    

    注意名称字段,在gcc中它会毫无警告地编译,但在g++中它会编译,我不知道为什么。

    gcc (Compiling C) ,-Wno写入字符串在默认情况下处于活动状态。

    在里面 g++ (Compiling C++) -默认情况下,Wwrite字符串处于活动状态

    这就是为什么会有不同的行为。 对于我们来说,使用 Boost_python 生成此类警告。 -Wno-write-strings 编译C++以来,我们一直使用 -Werror

        23
  •  -1
  •   James Antill    9 年前

    这是你真正的问题,依我看。你可以尝试一些从(char*)到(const char*)的自动化方法,但我会把钱花在它们上,而不仅仅是工作上。你必须有一个人参与至少部分工作。