From: Kevin Wolf <kwolf@redhat.com>
To: Blue Swirl <blauwirbel@gmail.com>
Cc: qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [PATCH 1/5] Suppress some gcc warnings with -Wtype-limits
Date: Mon, 06 Sep 2010 15:04:36 +0200 [thread overview]
Message-ID: <4C84E6E4.6030909@redhat.com> (raw)
In-Reply-To: <AANLkTing_8g24OUb81duni05pMtO2KvEdCiQ0Xpd-QCr@mail.gmail.com>
Am 04.09.2010 23:07, schrieb Blue Swirl:
> On Sat, Sep 4, 2010 at 8:30 PM, andrzej zaborowski <balrogg@gmail.com> wrote:
>> Hi,
>>
>> On 4 September 2010 21:45, Blue Swirl <blauwirbel@gmail.com> wrote:
>>> On Sat, Sep 4, 2010 at 5:57 PM, andrzej zaborowski <balrogg@gmail.com> wrote:
>>>>> - if (event < 0 || event >= BLKDBG_EVENT_MAX) {
>>>>> + if ((int)event < 0 || event >= BLKDBG_EVENT_MAX) {
>>>> Is the behaviour incorrect for some values, or is it not correct C?
>>>> As far as I know it is correct in c99 because of type promotions
>>>> between enum, int and unsigned int.
>>>
>>> The problem is that the type of an enum may be signed or unsigned,
>>> which affects the comparison. For example, the following program
>>> produces different results when it's compiled with -DUNSIGNED and
>>> without:
>>> $ cat enum.c
>>> #include <stdio.h>
>>>
>>> int main(int argc, const char **argv)
>>> {
>>> enum {
>>> #ifdef UNSIGNED
>>> A = 0,
>>> #else
>>> A = -1,
>>> #endif
>>> } a;
>>>
>>> a = atoi(argv[1]);
>>> if (a < 0) {
>>> puts("1: smaller");
>>> } else {
>>> puts("1: not smaller");
>>> }
>>>
>>> if ((int)a < 0) {
>>> puts("2: smaller");
>>> } else {
>>> puts("2: not smaller");
>>> }
>>>
>>> return 0;
>>> }
>>> $ gcc -DUNSIGNED enum.c -o enum-unsigned
>>> $ gcc enum.c -o enum-signed
>>> $ ./enum-signed 0
>>> 1: not smaller
>>> 2: not smaller
>>> $ ./enum-signed -1
>>> 1: smaller
>>> 2: smaller
>>> $ ./enum-unsigned 0
>>> 1: not smaller
>>> 2: not smaller
>>> $ ./enum-unsigned -1
>>> 1: not smaller
>>> 2: smaller
>>
>> Ah, that's a good example, however..
>>
>>>
>>> This is only how GCC uses enums, other compilers have other rules. So
>>> it's better to avoid any assumptions about signedness of enums.
>>>
>>> In this specific case, because the enum does not have any negative
>>> items, it is unsigned if compiled with GCC. Unsigned items cannot be
>>> negative, thus the check is useless.
>>
>> I agree it's useless, but saying that it is wrong is a bit of a
>> stretch in my opinion. It actually depends on what the intent was --
>> if the intent was to be able to use the value as an array index, then
>> I think the check does the job independent of the signedness of the
>> operands.
>
> No.
>
> If BLKDBG_EVENT_MAX is < 0x80000000, it does not matter if there is
> the check or not. Because of unsigned arithmetic, only one comparison
> is enough. With a non-GCC compiler (or if there were negative enum
> items), the check may have the desired effect, just like with int
> cast.
> If BLKDBG_EVENT_MAX is >= 0x80000000, the first check is wrong,
> because you want to allow array access beyond 0x80000000, which will
> be blocked by the first check. A non-GCC compiler may actually reject
> an enum bigger than 0x80000000. Then the checks should be rewritten.
>
> The version with int cast is correct in more cases than the version
> which relies on enum signedness.
If the value isn't explicitly specified, it's defined to start at 0 and
increment by 1 for each enum constant. So it's very unlikely to hit an
interesting case - we would have to add some billions of events first.
And isn't it the int cast that would lead to (event < 0) == true if
BLKDBG_EVENT_MAX was >= 0x8000000 and falsely return an error? The old
version should do this right.
Anyway, even though this specific code shouldn't misbehave today, I'm
all for silencing warnings and enabling -Wtype-limits. We regularly have
real bugs of this type.
Kevin
next prev parent reply other threads:[~2010-09-06 13:04 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-04 14:17 [Qemu-devel] [PATCH 1/5] Suppress some gcc warnings with -Wtype-limits Blue Swirl
2010-09-04 15:40 ` andrzej zaborowski
2010-09-04 16:14 ` Blue Swirl
2010-09-04 16:44 ` andrzej zaborowski
2010-09-04 17:21 ` Blue Swirl
2010-09-04 17:57 ` andrzej zaborowski
2010-09-04 19:45 ` Blue Swirl
2010-09-04 20:30 ` andrzej zaborowski
2010-09-04 21:07 ` Blue Swirl
2010-09-06 13:04 ` Kevin Wolf [this message]
2010-09-06 19:21 ` Blue Swirl
2010-09-04 21:26 ` malc
2010-09-05 7:54 ` [Qemu-devel] " Michael S. Tsirkin
2010-09-05 9:06 ` Blue Swirl
2010-09-05 9:26 ` Michael S. Tsirkin
2010-09-05 9:44 ` Blue Swirl
2010-09-05 10:35 ` Michael S. Tsirkin
2010-09-05 15:26 ` andrzej zaborowski
2010-09-05 16:15 ` Blue Swirl
2010-09-05 17:02 ` andrzej zaborowski
2010-09-05 17:09 ` andrzej zaborowski
2010-09-05 19:16 ` Blue Swirl
2010-09-05 20:32 ` andrzej zaborowski
2010-09-05 21:44 ` Blue Swirl
2010-09-05 22:33 ` andrzej zaborowski
2010-09-06 19:08 ` Blue Swirl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C84E6E4.6030909@redhat.com \
--to=kwolf@redhat.com \
--cc=blauwirbel@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).