Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [paho-dev] Using C++ with the Paho C client library

Ugh. This is why people program in Python.

On 05/16/2013 07:18 PM, Ian Craggs wrote:
1) I can't pass a char** to a const char** or a const char * const * without a cast.   Adding casts requires changing programs, apart from the principle of adding what seem unnecessary casts.  See:

int f(const char * const * c)
{
    c = 0;
    c[1] = 0;
    c[0][0] = 1;
}


int main(int argc, char** argv)
{
    f(argv); /* cast needed - why? */
    return 0;
}

OK. I see this, as a warning, when using C with GCC 4.6 and clang 3.0 (but not with Visual C 2010, which is apparently incorrect).

This really surprised me.

C++ accepts this without warning. It will apply the const-ness all the way down. I found an explanation, but it wanders off into the world of "who would actually do that?"
http://c-faq.com/ansi/constmismatch.html
In C you can declare an array of topics like this (which gives the same warning as argv):
char* filts[] = { "topic1", "topic2", "topic3" };
In C++ this declaration used to be allowed (perhaps with a mild complaint from the compiler) but I believe is now prohibited in C++11. You must specify the const:
const char* filts[] = { "topic1", "topic2", "topic3" };
You can also do this in C, and then you don't get the warning when calling f()...


2) For char** topic, do you want const char** or const char* const *?  Presumably the latter, which I think is verging on the hard to understand.


Yes, unfortunately the second is more proper. The first would protect the contents of the strings themselves, whereas the second also protects the array of pointers to the strings. Perhaps using array [] notation would make it a little less cryptic?
void f(const char* const c[])
{
    c = 0;         // This is fine, normal pass-by value semantics
    c[1] = 0;            // compiler error!
    c[0][0] = 1;        // compiler error!
}

But, honestly, I'd settle for the first. C++ is moving to enforce the const-ness of string literals, but it seems to accept the "filts" array as-is, even if you leave out the second const.
void f(const char** c)
{
    c = 0;         // This is fine
    c[1] = 0;            // This is probably a bug, but allowed by the compiler
    c[0][0] = 1;        // compiler error!
}

f(filts);  // No complaints.
I'd still vote for the 1st, though. I'd rather get the compiler error than have to look for that bug.

Frank

Back to the top