0

I have this issue with one of my functions in this C++ program I'm porting over from HP-UX to LINUX. Basically, what seems to be the problem is that for the function

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

the gcc compiler appears to be complaining that I cannot pass objects of type const Dictionary through ...

The source code for the program is pretty old and looks to utilize a lot of C-style constructs. This particular function accepts a variable list of arguments as allowed through the stdarg.h header. In addition, the warning is only reported in gcc (version 2.95.2) for HP-UX and not in LINUX's gcc (version 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 `...'

The source code for the function is available below:

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
  }
}

I was wondering if there was a way to repair this issue. I don't understand what is causing this warning to appear. From what I found on other websites, it appears that this warning may cause the compiled program to behave unexpectedly. Some people are saying that this should really be an error rather than a warning. I haven't had much luck determining the cause of this problem.

Justin
  • 742
  • 5
  • 17
  • 34

1 Answers1

3

The warning is correct. You can only pass POD types as variable arguments -- attempting to pass a non-POD type gives undefined behavior [In case anybody cares (§5.2.2/7): "If the argument has a non-POD class type (clause 9), the behavior is undefined."]

Since you're treating all the other items being passed as char *, it's probably better to pass a vector<char *> or (perhaps even better) a vector<string>. If you can update to 4.7, you can switch to the latter fairly painlessly, so something like:

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

would turn into:

somedict.lookup(mykey, {"a", "b", "c"});
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Thanks a bunch. I shall give this solution a try. – Justin Jun 08 '12 at 20:36
  • In this circumstance though, is there a reason why this warning does not appear in LINUX's gcc during compilation? – Justin Jun 08 '12 at 20:37
  • @Justin: Not really sure. Could be a difference in settings, or something they don't bother to warn about any more, assuming code like that disappeared at least a decade ago. – Jerry Coffin Jun 08 '12 at 20:46
  • @Justin: been there, done that, glad I'm not doing it at the moment, wish I was sure I never would again... :-) – Jerry Coffin Jun 08 '12 at 21:05
  • The syntax above wouldn't work for versions of gcc below 4.7 am I correct? – Justin Jun 11 '12 at 13:09