【问题标题】:Cannot pass objects of type `const DictionaryKey' through `...'无法通过“...”传递“const DictionaryKey”类型的对象
【发布时间】:2012-06-08 20:16:15
【问题描述】:

我从 HP-UX 移植到 LINUX 的这个 C++ 程序中的一个函数有这个问题。基本上,问题似乎在于函数

const char * Dictionary::lookup(const DictionaryKey &, ...)

gcc 编译器似乎在抱怨我无法通过 ... 传递 const Dictionary 类型的对象

该程序的源代码相当陈旧,看起来使用了很多 C 风格的结构。此特定函数接受通过 stdarg.h 标头允许的变量参数列表。此外,该警告仅在 HP-UX 的 gcc(版本 2.95.2)中报告,而不在 LINUX 的 gcc(版本 4.3.2)中报告。

$ gcc -lstdc++ foo1.cc foo2.cc
foo1.cc: In method `const char * Dictionary::lookup(const DictionaryKey &, ...)':
foo1.cc:178: warning: cannot pass objects of type `const DictionaryKey' through `...'

该函数的源代码如下:

const char *Dictionary::lookup (const DictionaryKey& key, ...)
{
  static char res[MAX_LINE];
  char *param[9];
  va_list ap;
  WordDictionary::iterator entry = dictionary.find (key);
  if (entry != dictionary.end())
  {
    int idx = 1;
    va_start (ap, key);
    while ((param[idx] = va_arg (ap, char *)) != NULL) idx++;
    va_end (ap);
    char *ts = (*entry).second.textdata;
    char *ts2 = res;
    while (*ts)
    {
      if (*ts == '$')
      {
        ts++;
        idx = *ts - '0';
        strcpy (ts2, param[idx]);
        ts2 += strlen(param[idx]);
        ts++;
      } else
      {
        *ts2++ = *ts++;
      }
    }  
    *ts2++ = 0;
    return res;
  }
  else
  {
    return key.keydata;     // Not found in dictionary
  }
}

我想知道是否有办法解决这个问题。我不明白是什么导致出现此警告。从我在其他网站上发现的情况来看,这个警告似乎可能导致编译后的程序出现意外行为。有人说这应该是一个错误而不是一个警告。我没有太多运气确定这个问题的原因。

【问题讨论】:

    标签: c++ linux gcc g++ hp-ux


    【解决方案1】:

    警告是正确的。您只能将 POD 类型作为变量参数传递——尝试传递非 POD 类型会给出未定义的行为 [如果有人关心(§5.2.2/7):“如果参数具有非 POD 类类型(第 9 条) ),行为未定义。"]

    由于您将传递的所有其他项目视为char *,因此传递vector<char *> 或(也许更好)vector<string> 可能会更好。如果您可以更新到 4.7,则可以相当轻松地切换到后者,例如:

    somedict.lookup(mykey, "a", "b", "c", NULL);
    

    会变成:

    somedict.lookup(mykey, {"a", "b", "c"});
    

    【讨论】:

    • 非常感谢。我会试试这个解决方案。
    • 在这种情况下,编译时LINUX的gcc中没有出现这个警告是有原因的吗?
    • @Justin:不太确定。可能是设置上的差异,或者他们不想再警告任何事情,假设这样的代码至少在十年前就消失了。
    • @Justin:去过那里,做到了,很高兴我现在没有这样做,希望我确定我再也不会这样做了...... :-)
    • 上面的语法不适用于 4.7 以下的 gcc 版本,对吗?
    猜你喜欢
    • 2013-11-24
    • 2012-07-07
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多