bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: /*unsigned*/ int level3 in gen-uni-tables.c


From: Bruno Haible
Subject: Re: /*unsigned*/ int level3 in gen-uni-tables.c
Date: Wed, 12 Aug 2020 21:12:19 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-186-generic; KDE/5.18.0; x86_64; ; )

Florian Weimer wrote:
> gen-uni-tables.c produces types like this:
> 
> struct
>   {
>     int header[1];
>     int level1[2];
>     short level2[2 << 7];
>     /*unsigned*/ int level3[16 << 4];
>   }
> 
> Why is the unsigned commented out?

I think, at the time the code was written, some K&R C compilers were still in
use that did accept an initialization

  struct { int x; } table = { 0xFFFFFFFF };

but did not accept an initialization

  struct { unsigned int x; } table = { 0xFFFFFFFFU };

So, I made the element type an 'int'
  - in gen-uni-tables.c line 744,
  - e.g. in unictype/categ_Cc.h line 14,
  - in unictype/bitmap.h line 40.
But as you can see, the value is being cast back from 'int' to 'unsigned int'
immediately after being fetched from the table. So all is fine.

> Some of the constants are so large
> that they are treated as unsigned ints.

Indeed ISO C 99 and newer (ยง 6.4.4.1.(5)) specify that 0xFFFFFFFF is a priori
an unsigned integer. But when used as an initializer for an 'int' it poses
no problem. All machines nowadays use two's complement.

gcc 10.2.0 and clang 9.0.0 give no warning on the attached code (combined
code from unictype/categ_Cc.c, unictype/categ_Cc.h, unictype/bitmap.h),
even with "-Wall -std=gnu18".

> This kind of narrowing initialization is no longer valid C++.

Indeed, GCC 10.2.0 and clang give errors about this code when uses as C++ code:

$ gcc -Wall -O -S -x c++ foo.c
foo.c:156:1: error: narrowing conversion of '4294967295' from 'unsigned int' to 
'int' [-Wnarrowing]
  156 | };
      | ^
foo.c:156:1: error: narrowing conversion of '2147483648' from 'unsigned int' to 
'int' [-Wnarrowing]
foo.c:156:1: error: narrowing conversion of '4294967295' from 'unsigned int' to 
'int' [-Wnarrowing]

But why would this matter? This is C code, not C++ code.

Bruno

Attachment: foo.c
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]