Ambiguity for `QByteArray:fromRawData` expecting `char` array
-
Hi,
If I try to compile the example code for QByteArray::fromRawData:
static const char mydata[] = { 0x00, 0x00, 0x03, 0x84, 0x78, 0x9c, 0x3b, 0x76, 0xec, 0x18, 0xc3, 0x31, 0x0a, 0xf1, 0xcc, 0x99, 0x6d, 0x5b }; QByteArray data = QByteArray::fromRawData(mydata, sizeof(mydata));
I get the a
Wnarrowing
warning:../main.cpp:XX:Y: error: narrowing conversion of ‘132’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
That is, because my system interprets
char
assigned char
by default.Maybe it is worth putting a "Note" there mentioning that?
As a feature request, can the constructor not also take
signed char
orunsigned char
arrays to circumvent this ambiguity? -
Hi,
If I try to compile the example code for QByteArray::fromRawData:
static const char mydata[] = { 0x00, 0x00, 0x03, 0x84, 0x78, 0x9c, 0x3b, 0x76, 0xec, 0x18, 0xc3, 0x31, 0x0a, 0xf1, 0xcc, 0x99, 0x6d, 0x5b }; QByteArray data = QByteArray::fromRawData(mydata, sizeof(mydata));
I get the a
Wnarrowing
warning:../main.cpp:XX:Y: error: narrowing conversion of ‘132’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
That is, because my system interprets
char
assigned char
by default.Maybe it is worth putting a "Note" there mentioning that?
As a feature request, can the constructor not also take
signed char
orunsigned char
arrays to circumvent this ambiguity?static const unsigned char mydata[] = { ... } QByteArray::fromRawData(reinterpret_cast<const char*>(mydata), sizeof(mydata))
Would that fix it?
Or, does your compiler have a
#pragma
to switch offWnarrowing
which you could surround the initialization with? -
static const unsigned char mydata[] = { ... } QByteArray::fromRawData(reinterpret_cast<const char*>(mydata), sizeof(mydata))
Would that fix it?
Or, does your compiler have a
#pragma
to switch offWnarrowing
which you could surround the initialization with?@JNBarchan that works like a charm, yes. I have no idea why my thoughts were way to complicated :) Thank you!
Still, as
char
can be eitherunsigned
orsigned
(depending on the platform), I still don't get why the constructor cannot takeuchar
arrays as an argument. Casting feels a bit unnatural within the Qt framework. -
@JNBarchan that works like a charm, yes. I have no idea why my thoughts were way to complicated :) Thank you!
Still, as
char
can be eitherunsigned
orsigned
(depending on the platform), I still don't get why the constructor cannot takeuchar
arrays as an argument. Casting feels a bit unnatural within the Qt framework.@lotuz-0
Yes, I was unsure whether you were asking for a solution or just commenting that you thoughtQByteArray::fromRawData()
should offer anconst unsigned char *
parameter overload.As for the reason for that lacking:
Firstly, note that the example in http://doc.qt.io/qt-5/qbytearray.html#fromRawData already has top-bit-set chars, and (presumably) the compiler they used did not have your "narrowing" warning/"my system interprets char as signed char by default". What compiler is it btw, as I've never seen this kind of warning on this kind of data, so maybe it's "unusual"?
Secondly, there are probably loads of functions which can accept either
char
orunsigned char
and they don't feel like writing alternate overloads for every single one (plus e.g. if they didfromRawData()
here, what about the return types ofdata()
andconstData()
and ....) Thischar
beingsigned
versusunsigned
is really an issue all over the place, not just for this particular function/constructor. Presumably the narrowing/warning would not occur if all arguments were declaredunsigned char
rather thanchar
as I think(?) that convertschar->unsigned char
without issue, but that's how it is in practice.... -
Hi,
If I try to compile the example code for QByteArray::fromRawData:
static const char mydata[] = { 0x00, 0x00, 0x03, 0x84, 0x78, 0x9c, 0x3b, 0x76, 0xec, 0x18, 0xc3, 0x31, 0x0a, 0xf1, 0xcc, 0x99, 0x6d, 0x5b }; QByteArray data = QByteArray::fromRawData(mydata, sizeof(mydata));
I get the a
Wnarrowing
warning:../main.cpp:XX:Y: error: narrowing conversion of ‘132’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
That is, because my system interprets
char
assigned char
by default.Maybe it is worth putting a "Note" there mentioning that?
As a feature request, can the constructor not also take
signed char
orunsigned char
arrays to circumvent this ambiguity?The error you get is for the way you initialize the
mydata
variable, not for the way you use it after that. By default integer literals are ofint
type, so you get (a benign) warning about possible truncations. You should use character literals to initialize the array:static const char mydata[] = { '\x00', '\x00', '\x03', // .. and so on };
-
@lotuz-0
Yes, I was unsure whether you were asking for a solution or just commenting that you thoughtQByteArray::fromRawData()
should offer anconst unsigned char *
parameter overload.As for the reason for that lacking:
Firstly, note that the example in http://doc.qt.io/qt-5/qbytearray.html#fromRawData already has top-bit-set chars, and (presumably) the compiler they used did not have your "narrowing" warning/"my system interprets char as signed char by default". What compiler is it btw, as I've never seen this kind of warning on this kind of data, so maybe it's "unusual"?
Secondly, there are probably loads of functions which can accept either
char
orunsigned char
and they don't feel like writing alternate overloads for every single one (plus e.g. if they didfromRawData()
here, what about the return types ofdata()
andconstData()
and ....) Thischar
beingsigned
versusunsigned
is really an issue all over the place, not just for this particular function/constructor. Presumably the narrowing/warning would not occur if all arguments were declaredunsigned char
rather thanchar
as I think(?) that convertschar->unsigned char
without issue, but that's how it is in practice....@JNBarchan I was asking for a solution to cast it nicely (I really was blind here) and was wondering about it.
I am on
4.13.11-1-ARCH
with agcc 7.2.0
and#include <limits> std::numeric_limits<char>::is_signed;
.. says it it signed. I just found out about the gcc having a flag to control the signess of a char (e.g. -funsigned-char). Btw the issue also only appears with arrays, e.g.
char f = 0xFF
does some implicit cast or something.Thanks for all the input! will mark it solved now :)
-
The error you get is for the way you initialize the
mydata
variable, not for the way you use it after that. By default integer literals are ofint
type, so you get (a benign) warning about possible truncations. You should use character literals to initialize the array:static const char mydata[] = { '\x00', '\x00', '\x03', // .. and so on };
@kshegunov that explains a lot! Thank you so much!
I would say the documentation needs a change and should use character literals for initialization too.
-
The error you get is for the way you initialize the
mydata
variable, not for the way you use it after that. By default integer literals are ofint
type, so you get (a benign) warning about possible truncations. You should use character literals to initialize the array:static const char mydata[] = { '\x00', '\x00', '\x03', // .. and so on };
@kshegunov
You will note that the example at http://doc.qt.io/qt-5/qbytearray.html#fromRawData does the initialization just the same way as the OP, and has top-bits-set, and presumably is not expecting compiler warnings.While your suggestion is correct, I suspect the OP does not want the ugliness/hassle of changing over all his initializer elements, which is why I didn't suggest it.
-
@kshegunov that explains a lot! Thank you so much!
I would say the documentation needs a change and should use character literals for initialization too.
@lotuz-0 said in Ambiguity for `QByteArray:fromRawData` expecting `char` array:
I would say the documentation needs a change and should use character literals for initialization too.
Yes, probably it does.
@JNBarchan said in Ambiguity for `QByteArray:fromRawData` expecting `char` array:
You will note that the example at http://doc.qt.io/qt-5/qbytearray.html#fromRawData does the initialization just the same way as the OP
Noted.
and presumably is not expecting compiler warnings.
This would depend on the warning reporting level.
While your suggestion is correct, I suspect the OP does not want the ugliness/hassle of changing over all his initializer elements, which is why I didn't suggest it.
Well, it's the "correct" way of avoiding the narrowing warning. Personally, I don't like it either, but it's how C++ works.
Note that:static const char mydata[] = { 0x100 };
is also correct and will emit the same warning, and incidentally in this case truncation is going to happen.
-
Hi,
There's an update to the documentation on its way.
-
@JNBarchan I was asking for a solution to cast it nicely (I really was blind here) and was wondering about it.
I am on
4.13.11-1-ARCH
with agcc 7.2.0
and#include <limits> std::numeric_limits<char>::is_signed;
.. says it it signed. I just found out about the gcc having a flag to control the signess of a char (e.g. -funsigned-char). Btw the issue also only appears with arrays, e.g.
char f = 0xFF
does some implicit cast or something.Thanks for all the input! will mark it solved now :)
@lotuz-0 said in Ambiguity for `QByteArray:fromRawData` expecting `char` array:
I just found out about the gcc having a flag to control the signess of a char (e.g. -funsigned-char).
Just to confirm: if I set the compiler flag
-funsigned-char
,char
gets interpreted asunsigned
by default and the example compiles nicely.