lmi
[Top][All Lists]
Advanced

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

Re: [lmi] Fixing build with clang 7 and 64-bit Linux


From: Vadim Zeitlin
Subject: Re: [lmi] Fixing build with clang 7 and 64-bit Linux
Date: Tue, 13 Nov 2018 16:01:16 +0100

On Tue, 13 Nov 2018 09:57:48 +0000 Greg Chicares <address@hidden> wrote:

GC> We seem to be looking at this in completely different ways, apparently
GC> because we have different answers to a particular question pertaining
GC> to Dietmar Kuehl's original C98 code: given
GC>   static std::ctype_base::mask rc[table_size];
GC>   rc[C] &= ~std::ctype_base::space;
GC> what is the type of the expression
GC>            ~std::ctype_base::space
GC> on the RHS of the assignment?

 I think it's implementation-defined.

GC> I don't doubt your observation that its value is negative (and its type
GC> is therefore not unsigned) in a particular implementation whose "mask"
GC> type is unsigned; I just think the standard forbids that.

 I have my doubts about it, but even assuming that you're right, I wonder
if it really matters knowing that "mask" is unsigned in both libstdc++ and
libc++ (FWIW it is "signed short" in MSVC standard library implementation).

GC> I believe that expression's type must be 'ctype_base::mask':
GC> 
GC>  - 'ctype_base::mask' is a "bitmask" type (C++17 [locale.types]);

 And [bitmask.types] says

        Each bitmask type can be implemented as an enumerated type that
        overloads certain operators, as an integer type, or as a bitset
                                   ^^^^^^^^^^^^^^^^^^

(underlining mine). I'm reading this as saying that implementing
ctype_base::mask as an integer type is explicitly allowed. Am I wrong?

GC>  - the implementation
GC>       constexpr bitmask operator~(bitmask X){
GC>       return static_cast<bitmask>(~static_cast<int_type>(X));
GC>       }
GC>    [bitmask.types/2] is normative.

 Is it? This snippet starts with "// For exposition only." and, anyhow,
"can be written" doesn't imply "must be written" to me. Also, quoting
another part of your email occurring later:

GC> It would appear that, instead of the normative
GC> 
GC>       constexpr bitmask operator~(bitmask X){
GC>       return static_cast<bitmask>(~static_cast<int_type>(X));
GC>       }

 Certainly this can't be normative if bitmask is defined as an integer type
because an overloaded operator must take an argument of class or enum type,
i.e. writing this when bitmap is a typedef for "[unsigned] short" is a
compilation error.

GC> Moreover, the language "To clear a value Y in an object X is to
GC> evaluate the expression X &= ~Y" in [locale.types/2] is certainly
GC> normative, so issuing a warning on 'X &= ~Y' is extraordinary.

 I agree that it seems pretty strange, although it's probably a QoI issue
and not a conformance one. Just to be sure, note that it's gcc which does
this, while clang doesn't.

GC> I'd conclude that the line that clang objects to:
GC> 
GC> > GC> | -           constexpr std::ctype_base::mask z = 
{~std::ctype_base::space};
GC> 
GC> can't be wrong.

 For me it most definitely is...

GC> I could fabricate a rationale for what we've actually observed:
GC> 
GC>  - employing a typedef like
GC>      using ctype_base::mask = unsigned short int
GC>    is expedient (because it's probably more compact than 'int');

 I think it's mostly done like this for C compatibility.

GC>  - operator~()(unsigned short int) involves integral promotion;

 Yes.

GC>  - thus, Kuehl's original code
GC>      rc[C] &= ~std::ctype_base::space;
GC>    may legitimately trigger warnings, and introducing '{}' thus:
GC>      rc[C] &= {~std::ctype_base::space};
GC>    renders such code certainly incorrect.

 Yes.

GC> However, isn't that just to say that the signature
GC>    constexpr bitmask operator~(bitmask)
GC> prescribed by the standard can be ignored if one wishes?

 I don't think it's prescribed. I do think the standard text is confusing
here, but I'm almost sure the intention was to allow using integer types
as bitmask types.

 Regards,
VZ


reply via email to

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