3

Some weeks ago, I wrote a little JSON-RPC implemention on my Windows Notebook based on C++ and Qt. I used the Visual C++ 2013 compiler and it worked without any problems.

Now I copied my code to an Linux Mint machine with an GCC compiler and I always get the following error:

jsonrpc.h:18: Error: conversion from 'long int' to 'QJsonValue' is ambiguous
     static QJsonObject generateErrorObj(ErrorCode code, QString message, QJsonValue data = NULL);

This error also appears on line 19 (method generateErrorResponse) and line 20 (method generateRequest). So... now I'm not that familiar with C++ or Qt, so I don't get it, why this doesn't work, althought it worked on Windows...

Here is the full code of the jsonrpc.h:

#ifndef JSONRPC_H
#define JSONRPC_H

#include <QtCore>

class JSONRPC
{
public:
    enum ErrorCode
    {
        PARSE_ERROR = -32700,
        INVALID_REQUEST = -32600,
        METHOD_NOT_FOUND = -32601,
        INVALID_PARAMS = -32602,
        INTERNAL_ERROR = -32603
    };
    static QJsonObject generateObj(QString id, bool isNotification = false);
    static QJsonObject generateErrorObj(ErrorCode code, QString message, QJsonValue data = NULL);
    static QJsonObject generateErrorResponse(QString id, ErrorCode code, QString message, QJsonValue data = NULL);
    static QJsonObject generateRequest(QString id, QString method, QJsonValue parameters = NULL, bool isNotification = false);
    static QJsonObject generateResponse(QString id, QJsonValue result);
};

#endif // JSONRPC_H
Cheesi
  • 483
  • 4
  • 14
  • What is the type of QJsonValue? I'm guessing it is a typedef that represents another type. Find where QJsonValue is defined (in the QtCore include). Most likely, it is defined differently on Linux and Windows. – Kyle A Feb 29 '16 at 19:12
  • This most likely happens because QJsonValue can be constructed from two types that are different on Windows, but identical on Linux. For example, if you have an overload for time_t, that would be int64 on Windows, which is different from long int (which is 32 bits on Windows), while on Linux that same time_t might actually be a long int, thus giving you two overloads that cannot be distinguished from each other. – H. Guijt Feb 29 '16 at 19:13
  • I looked up QJsonValue. I was wrong, it is not a typedef. Since it is a class, go with ddriver's answer. That will probably work. – Kyle A Feb 29 '16 at 19:17

1 Answers1

5

NULL is likely implemented in a different way on both platforms. The "problematic" implementation creates an ambiguity as there is more than one likely candidate for implicit conversion.

Instead of JsonValue parameters = NULL try JsonValue parameters = JsonValue() - that constructor will create a json value of type null.

Furthermore, even if JsonValue parameters = NULL "works" it will likely be wrong, as it will be equal to something like JsonValue(int(0)) and not a "null" json value as in JsonValue() which has a default QJsonValue::Type::Null parameter. So you won't have a NULL json value, but a NUMBER json value with value of 0 - two completely different things.

dtech
  • 47,916
  • 17
  • 112
  • 190
  • It's more likely that QJsonValue was implemented differently. My experience with VS and GCC suggests that NULL is almost always defined as zero. – Kyle A Feb 29 '16 at 19:14
  • @KyleA `NULL` in GCC is defined as `__null`, which seems to be a pointer of imaginary unknown type. If you stringify `NULL`, you can see it: http://coliru.stacked-crooked.com/a/6562714b925829b9 – Weak to Enuma Elish Feb 29 '16 at 19:17
  • "JsonValue parameters = JsonValue()" The explicit default constructor is unnecessary. The declaration alone does the right thing: `JsonValue parameters;`. Generally speaking, Qt value classes default-construct a null value, so such explicit code is unnecessary and, as you've seen, leads to bugs. – Kuba hasn't forgotten Monica Feb 29 '16 at 20:47
  • @KubaOber - the point here is to have a default parameter value so you can call the function without specifying it. – dtech Feb 29 '16 at 20:49