2014-05-14 126 views
0

我有一個C這樣的事情++擴展:Python的C++擴展編譯器警告

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

編譯器抱怨:

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

什麼是擺脫此警告的最佳方式是什麼?

我想:

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

但是失敗:

候選函數並不可行:從沒有任何已知的轉換 '爲const char [2]' 到 '字符*'

+0

'字符常量* kwlist [] = ....' – WhozCraig

+0

錯誤:沒有匹配的函數調用 'PyArg_ParseTupleAndKeywords' ...候選函數不可行:沒有從已知的轉換 '爲const char * [6]'到'char **' – Matyas

回答

1

看起來你試圖在Python的C API不適用的範圍內學習常量,即使間接地通過在你的編譯器上發出警告。你在這裏有幾個選擇。 (請注意,我是無法重現你在我的編譯器警告,這樣做仔細檢查我的建議其實解決的事情。)

  • 鑄造外出創作警告:

    char* kwlist[] = { const_cast<char*>("x"), const_cast<char*>("W") }; 
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO", kwlist, &x, &W)) return NULL; 
    
  • 拋棄錯誤的使用方法:

    char const* kwlist[] = { "x", "W" }; 
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO", const_cast<char **>(kwlist), &x, &W)) return NULL; 
    
  • 讓事情可變要求:

    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; 
    
  • 沉默的具體警告,無論是全局或局部:

    本地警告抑制確切的代碼依賴於編譯器。我已經包括下面的兩種情況:(!感謝Matt Joiner

    GCC

    #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) 
    

虛擲常量不是普遍安全的,所以如果PyArg_ParseTupleAndKeywords實際使用內容以非常量方式,前兩種方法中的任何一種都可以合法地導致運行時失敗。

如果您強烈懷疑(或更好的驗證)PyArg_ParseTupleAndKeywords以常量安全的方式使用您的參數(請求比使用的權限更大的權限),大多數方法比技術上正確的第三種方法少冗長。

+0

我喜歡選項3.編譯器在MacOS上鏗鏘作響(蘋果似乎在gcc上有一些影響,並在10.9中將其替換)。謝謝! – Matyas