0

I have something like this in a C++ extension:

char* kwlist[] = {"x", "W"};
if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO", kwlist, &x, &W)) return NULL;

The compiler complains that:

warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]

What is the best way to get rid of this warning?

I tried:

char const* kwlist[] = {"x", "W"};

But that fails with:

candidate function not viable: no known conversion from 'const char [2]' to 'char *'

Matyas
  • 644
  • 6
  • 15

1 Answers1

1

It looks like you're trying to be pedantically const-correct to an extent that Python's C API is not, even if indirectly by turning up the warnings on your compiler. You have a few options here. (Note that I wasn't able to reproduce you warnings in my compiler, so do double-check my recommendations actually resolve things.)

  • Cast away the warning on creation:

    char* kwlist[] = { const_cast<char*>("x"), const_cast<char*>("W") };
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO", kwlist, &x, &W)) return NULL;
    
  • Cast away the error on use:

    char const* kwlist[] = { "x", "W" };
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO", const_cast<char **>(kwlist), &x, &W)) return NULL;
    
  • Make things mutable as required:

    char kw_x[] = "x";
    char kw_W[] = "W";
    char* kwlist[] = { kw_x, kw_W };
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO", kwlist, &x, &W)) return NULL;
    
  • Silence the specific warnings, either globally or locally:

    The exact code for local warning suppression depends on the compiler. I've included two common cases below:

    GCC (thanks Matt Joiner!)

    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wdeprecated-writable-strings"
    takes_ppchar(kwlist);         /* no diagnostic for this one */
    #pragma GCC diagnostic pop
    

    Visual Studio

    #pragma warning(push)
    #pragma warning(disable : ####)
    code_causing_warning(####)
    #pragma warning(pop)
    

Casting away const is not universally safe, so if PyArg_ParseTupleAndKeywords actually uses the contents in a non-const manner, either of the first two approaches can legitimately result in run-time failures.

If you strongly suspect (or better yet verify) that PyArg_ParseTupleAndKeywords uses your parameter in a const-safe manner (requesting more permissions than it uses), most approaches are less verbose than the technically correct third approach.

Community
  • 1
  • 1
Michael Urman
  • 15,737
  • 2
  • 28
  • 44
  • I like option 3. The compiler is clang on MacOS (Apple seems to have some fallout with gcc and replaced it in 10.9). Thanks! – Matyas May 15 '14 at 05:03