Announcement

Collapse
No announcement yet.

Linux 5.15's New "-Werror" Behavior Is Causing A Lot Of Pain

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Originally posted by indepe View Post
    But that's what I mean. You are saying that because of the missing sentence, "someone else" got confused about the rule, someone who didn't really understand the language enough to realize it was a mistake. And that someone thought that typedef meant something else than what it really meant and changed the compiler. And also the people who wrote C11 got confused about it. They all didn't know anymore what typedef really meant. It wasn't as obvious to them as it is to me. So I figured out that can't be right, but the first C11 standards people didn't. Because they were confused. That's what you are saying, right?
    The people who made the C11 stuffed up drafts was not confused about it what they thought typedef meant. The C11 authors assumed C90 was the same as C89 of course since C89 had the typedef rule they then put in the new coding rules they assumed the rule existed. This is "Assume= Makes a Ass out of U and Me." Please remember you were making the same very dangerous assume. Yes as you also found that very dangerous assume that C89=C90 is written all over the place. From a document point of view C89>C90 as C89 is more complete.

    The people did not notice the lines missing out of C90 is again "Assume= Makes a Ass out of U and Me." people assumed the missing lines where there and did not go through C90 with a fine tooth comb looking for errors in the reformat. Remember every line that is in C90 by itself read right for the C standard its the complete document is missing pieces completely. Remember the first correction in 1994 with C90 puts back into C90 8 complete miss pages of stuff that in C89 there was not a small amount missing here lot of it is stuff that is in K&R. The level of screw up in C90 is happens to be insane that at times leaves you scratching head how in heck did that get past but we have to live with the fact it did get past. Is even more insane how does the belief that C90=C89 remain. Does no one want to admit the C90 standard is screwed up. The first release of C90 was almost missing 5% of C89 that is a lot of document not there.

    Yes a new developer adding code to a compiler may not be as versed in the language as you hope they are. Those people will depend on the standard/language define documents to be complete and correct. Bad things happen when those people pick up a defective standard/language define documents have a defect. This happened in the C90 time frame and this happened at the start of the C11 process. Yes as this is all made more likely by the incorrect assume that C89=C90.

    PS the rank rules with C11 are screwed because of the same word Assume. They assume how a person is going to read the rank rules is the same as the implementation in front of them. Not that someone is going to read the rank rules and attempt to stuff it up. Or read the rank rules and get it wrong because they don't know the C language well.

    Assume is one of the biggest causes of headaches.
    Last edited by oiaohm; 16 September 2021, 08:09 PM.

    Comment


    • Originally posted by oiaohm View Post
      The people who made the C11 stuffed up drafts was not confused about it what they thought typedef meant. The C11 authors assumed C90 was the same as C89 of course since C89 had the typedef rule they then put in the new coding rules they assumed the rule existed. This is "Assume= Makes a Ass out of U and Me." Please remember you were making the same very dangerous assume. Yes as you also found that very dangerous assume that C89=C90 is written all over the place. From a document point of view C89>C90 as C89 is more complete.
      So you are saying in both cases (C90 and early drafts C11) the standards people just didn't notice missing sentences, while it was the people modifying the compiler who eventually got confused about the meaning of typedef (although for me difficult to understand why someone would be, even if the sentences were missing).

      Originally posted by oiaohm View Post
      Remember every line that is in C90 by itself read right for the C standard its the complete document is missing pieces completely. Remember the first correction in 1994 with C90 puts back into C90 8 complete miss pages of stuff that in C89 there was not a small amount missing here lot of it is stuff that is in K&R. The level of screw up in C90 is happens to be insane that at times leaves you scratching head how in heck did that get past but we have to live with the fact it did get past. Is even more insane how does the belief that C90=C89 remain. Does no one want to admit the C90 standard is screwed up. The first release of C90 was almost missing 5% of C89 that is a lot of document not there.
      Why do you say "remember"? I don't have any knowledge of that, and you didn't provide quotes or any linked content. And it is not like I would take that as a given just because you claim it repeatedly. It is not something that I "remember" at all.

      Originally posted by oiaohm View Post
      ... This happened in the C90 time frame and this happened at the start of the C11 process. Yes as this is all made more likely by the incorrect assume that C89=C90.
      Actually for C90, even a missing sentence about typedef does not have that effect, since it does not have the same rank rules as C11.

      Your point was the C11 rule "No two signed integer types shall have the same rank, even if they have the same representation.".
      In C11, you claim, a misunderstanding of typedef would possibly cause a misinterpretation of this rule, which would possibly mess up the rank system.

      But if you look at C89: (specifically 3.2.1 including 3.2.1.5 "Usual arithmetic conversion") http://port70.net/~nsz/c/c89/c89-draft.html
      C89 does not have that rule, and therefore the misunderstanding of typedef does not cause a misinterpretation of the type ranks ("ranks" do not even exist by that name).

      So there can't be a problem because of that in C90 itself.

      That leaves only the early drafts of C11. And in the year 2021, any serious compiler that implements a C11 mode, and is used in C11 mode (and any serious distribution delivering it) should have been long ago updated to the final version of C11. Otherwise don't blame the standard and what it "defines", blame those using long outdated compilers or buggy compilers.

      So in each mode, c89, c90, ansi, C99, C11, there is no good reason for a problem that comes from any of the discussed C standard definitions. Specifically there is no reason for a problem in the c89 mode which is apparently used by the kernel. Since there never was, and there never was in c90 either, typedef or not.
      Last edited by indepe; 16 September 2021, 11:28 PM.

      Comment


      • Originally posted by indepe View Post
        But if you look at C89: (specifically 3.2.1 including 3.2.1.5 "Usual arithmetic conversion") http://port70.net/~nsz/c/c89/c89-draft.html
        C89 does not have that rule, and therefore the misunderstanding of typedef does not cause a misinterpretation of the type ranks ("ranks" do not even exist by that name).t.
        Then you open up first version C90 you look for section 3.2.1 guess what. Its completely not there. Yes there is no "Usual arithmetic conversion" in C90 the first one that is left up the compiler developer to-do what every they like. Yes this also explains why the 6.3.1.8 section C11 equal to C89 seams like complete rewrite with no relation to C89 because that is what it is.

        Originally posted by indepe View Post
        So there can't be a problem because of that in C90 itself.
        This is you still making the Assume that you find something in C89 that is in C90. This assume you need to stop making. C90 standard document is insanely broken. There are a lot of sections in the original C89 that are in the missing pages of the first C90.

        Thing to remember C90 first version without the corrections in 1994 and 1996 is missing a hell load. Think C11 starts with a C90 document, This is partly what leads to the new written rank system because sections you are point to fo C89 are not in fact in first C90 standard document. There is nothing on that original C90 document that tells you you need to find the 1994 or 1996 to find the missing bits.

        Originally posted by indepe View Post
        Specifically there is no reason for a problem in the c89 mode which is apparently used by the kernel.
        Remember the is the repeating case of people with the C90 documents using it instead of the C89 document when working in GCC and LLVM compliers then applying changes to C89 part of compiler because C90 is assumed to be C89 document when it not.

        indepe remember in total 10 complete pages of the C89 standard were missing out the first of the C90 standard document yes the one released in 1990.

        Compiler based on the original C90 document can be a true problem child because lots of what is in C89 is not there. Horrible since the C90 document says it is C89 the person making those compiler horrible put C90 broken behaviour that is acceptable to the wording of the C90 standard under C89 mode.

        Yes the reason for the C90 problems to appear in C89 mode on a compiler is how the intro to the C90 document is written where it claims something that its totally bogus. Then how people like you indepe keep on presuming that they can read C89 to know what is in C90 this is wrong of course.

        People fail to presume some people will see the ANSI C89 on the intro pages of C90 then mistakenly use the broken C90 document instead of proper C89 document to write C89 parts.

        Basically we have three ways people screw up with this indepe.
        1) is like you saying stuff is not a problem who don't in fact have a C90 documents to see problem.
        2) then people who have C90 documents who incorrectly use them for C89 because the intro to the document says it same as ANSI C89 that is really easy to prove is 100 percent false when you directly compare C90 to C89 due to the volume of missing bits.
        3) C11 case where people start writing new standards using C90 as a base....

        From my point of view you find a C90 documents it either goes into archives not be accessed or in the bin.

        Problem is the damage from the existence of the C90 documents with their flaws is still present because we still have people finding a C90 document seeing the intro saying the same as C89 and believing it. Yes this is leading to repeated cases of incorrect patches to gcc and llvm turn up.

        Do also think what you read of gcc because gcc documentation also says C90 is the same as C89 it does not take much looking to notice the 8+ pages added back in to C90 1994 and the other page and half in 1996 and the fact parts are still missing when you compare C90 standard to C89 to go they are absolutely not the same thing.

        C90 is truly the problem. The other part is people using the C90 standard instead of C89. Then places like gcc including falsehood that C90 is the same as C89.

        Remember people trying to run on a budget at times will google for a C11 document and at times google will nicely give you old out of date C11 document. Yes this is a case of going to the Wikipedia is safer

        Comment


        • Originally posted by oiaohm View Post
          Then you open up first version C90 you look for section 3.2.1 guess what. Its completely not there. Yes there is no "Usual arithmetic conversion" in C90 the first one that is left up the compiler developer to-do what every they like.
          ...because nobody would notice if that went missing as well. I can see the compiler writers scratching their head and asking themselves "why the heck did I put that careful code there, when I could have just done whatever I would have liked to do..."

          Originally posted by oiaohm View Post
          Yes this also explains why the 6.3.1.8 section C11 equal to C89 seams like complete rewrite with no relation to C89 because that is what it is.
          ...because none of them could find the C89 docs and go back to them like I did....

          Originally posted by oiaohm View Post
          Remember the is the repeating case of people with the C90 documents using it instead of the C89 document when working in GCC and LLVM compliers then applying changes to C89 part of compiler because C90 is assumed to be C89 document when it not.
          ...because none of GCC and LLVM people would figure out what happened and talk to each other, but instead get confused about basic matters of the language and make all kinds of "horrible" compiler modifications, and for years nobody would notice what's going on...

          Comment


          • Originally posted by indepe View Post
            ...because nobody would notice if that went missing as well. I can see the compiler writers scratching their head and asking themselves "why the heck did I put that careful code there, when I could have just done whatever I would have liked to do..."
            The embedded complier developers who made some the horrible C90 screw up. Never put the careful code in there in the first place.

            Some are attempting to port code from some custom embedded C complier to gcc and incorrect presume GCC is wrong because the compiler they were using was to ISO C90/C89. (yes that is a common way you see written on some embedded compilers that warning of nightmare C90 is first because they used ISO C90 document without any of the fixes)

            Basically this list goes on. So far there 60 different reasons people have given for screwing this up for why they wrote a invalid patch and submitted it. The different distribution maintainers who have taken in invalid patch so far have used 20 different reasons..

            Originally posted by indepe View Post
            ...because none of them could find the C89 docs and go back to them like I did....
            Some of this is stupid company policies. Like business that have mandate that you must use ISO standard. So ANSI standards are not acceptable to be on your desktop or computer. C89 is a ANSI standard. Its simple to forgot "ISO/IEC 9899:2011" is C11 and C89 is ANSI. Yes crossing standard body headache. This is another level of stupidity that also explains why it took so long to notice that C90 was not C89 the first time.

            Yes these companies polices have still been causing problems. So some of them could not do what you did of grab the C89 document. Lot of the others that could have suffered from the other problem. You know the one "Someone else will do that" then no one does.

            Originally posted by indepe View Post
            ...because none of GCC and LLVM people would figure out what happened and talk to each other, but instead get confused about basic matters of the language and make all kinds of "horrible" compiler modifications, and for years nobody would notice what's going on...
            Please note it generally has not be the core GCC or LLVM people making the not to standard compiler modifications or accepting not to standard compiler modifications. The lead developers of GCC and LLVM don't have a copy of C90. Yet the documentation writers of both say that LLVM and GCC is C90 compatible....... Remember you had to buy C90 from ISO. Most open source project lead used C89 from ANSI because it was free. This also means they are not 100 percent aware how badly screwed the C90 documents are. Yes that lack of knowledge means they have not build tests into the LLVM or GCC testsuite to pick up C90 errors.

            So welcome to another level of fun here. GCC and LLVM claim C90 compatibility but its not based of the C90 documents but based off the ANSI C89.

            Distribution downstream maintainers may in fact be using C90 from ISO instead of ANSI C89 so are open to take in a patch they should not.

            indepe there are levels on levels of screw. This basically looks like the spectre bug handling except its with the C language define and compiler implementations.

            Comment


            • Originally posted by oiaohm View Post
              Yes this is a case of going to the Wikipedia is safer
              I think this is such a case as well. I will go with Wikipedia's description of C90 as C89 reformatted, instead of this exploding nightmare.

              Although the GCC documentation above does describe something that really came with ANSI C89 but not with ISO C90:
              "The ANSI standard, but not the ISO standard, also came with a Rationale document."



              Lots of missing sentences...
              Last edited by indepe; 17 September 2021, 05:42 AM.

              Comment


              • Originally posted by indepe View Post
                I think this is such a case as well. I will go with Wikipedia's description of C90 as C89 reformatted, instead of this exploding nightmare.

                Although the GCC documentation above does describe something that really came with ANSI C89 but not with ISO C90:
                "The ANSI standard, but not the ISO standard, also came with a Rationale document."



                Lots of missing sentences...
                Yep none of the rationale document of c89 gets into C90 either. So C90 is C89 missing about 8-10 pages then missing rationale document so is missing even more pages. So a compiler based purely on ISO C90 is a dumpster fire. A compiler based purely on C89 without rationale small paper bin not great but not complete mess.

                C90 is C89 lossy reformatted. You could say C90 like a jpeg version of a picture except with a written standard. Yes C90 looks on paper a lot like C89 but a lot of critical details are missing because the reformatting lost stuff.. Yes some of gcc strange warnings are explained by C90 existence and the embedded compilers that spawned from C90. Yes some of those C90 compilers thought it was the correct thing to turn unsigned to into signed always.

                Its very important not to use a ISO C90 document instead of a ANSI C89 as that mistake will cause trouble.

                Comment


                • Originally posted by oiaohm View Post
                  The bad word in the second bit is corresponding. You can have a ranking table like this:

                  3 unsigned int
                  3 signed int
                  2 unsigned
                  2 signed
                  1 int
                  That may explain it. Except, where do you have it from that int, signed and signed int are to be interpreted as different types? If different, then yes, the standard says they must have different rank, but if they are the same type, they of course must have the same rank too. I always thought of them as the same type, and when reading it this way, the ranking system seems a lot less cursed. Could this be the explanation?

                  We can ask C++17 if they are the same type, at least in that language. This holds on gcc and clang on x86_64:

                  Code:
                  #include <type_traits>
                  #include <stdint.h>
                  
                  static_assert(std::is_same_v<int, signed>);
                  static_assert(std::is_same_v<int, signed int>);
                  static_assert(std::is_same_v<long, long int>);
                  static_assert(std::is_same_v<long, signed long>);
                  static_assert(std::is_same_v<long, signed long int>);
                  
                  // x86_64
                  static_assert(std::is_same_v<int, int32_t>);
                  static_assert(std::is_same_v<long, int64_t>);
                  We can also ask if types that are required to have different rank are also different types, which they are:

                  Code:
                  static_assert(not std::is_same_v<long, long long>);
                  static_assert(not std::is_same_v<unsigned long, unsigned long long>);
                  So far, so good, I would say. Now, let's see if we can provocate an implicit cast to the signed type, for a case where the types have the same number of bits, by choosing a signed type with higher rank than the “corresponding” unsigned type, for any of the plausible suspects for “corresponding”:

                  Code:
                  template <typename Signed, typename Unsigned>
                  constexpr bool gt()
                  {
                      Signed negative = -1;
                      Unsigned positive = 1;
                      return negative > positive;
                  }
                  
                  static_assert(gt<long long, unsigned long>());
                  static_assert(gt<long long, unsigned long int>());
                  static_assert(gt<long long int, unsigned long>());
                  static_assert(gt<long long int, unsigned long int>());
                  static_assert(gt<signed long long, unsigned long>());
                  static_assert(gt<signed long long, unsigned long int>());
                  static_assert(gt<signed long long int, unsigned long>());
                  static_assert(gt<signed long long int, unsigned long int>());
                  Assuming I didn't hit any UB (which of course would invalidate the result), the unsigned type seems to win even when the signed type ranks higher. I think I see why:
                  1. (irrelevant) If both operands have the same type, then no further conversion is needed.
                  2. (irrelevant) Otherwise, if both operands have signed integer types or both have unsigned integer types …
                  3. (irrelevant) Otherwise, if the unsigned operand has rank greater or equal rank than the signed operand …
                  4. (irrelevant) Otherwise, if the signed operand can represent all of the values of the unsigned operand…
                  5. (relevant) Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
                  Only rule 4 could cause implicit conversion to signed, which speaks about representing all the values of the other – doesn't care about rank!
                  Last edited by andreano; 17 September 2021, 06:47 PM.

                  Comment


                  • Originally posted by andreano View Post
                    That may explain it. Except, where do you have it from that int, signed and signed int are to be interpreted as different types? If different, then yes, the standard says they must have different rank, but if they are the same type, they of course must have the same rank too. I always thought of them as the same type, and when reading it this way, the ranking system seems a lot less cursed. Could this be the explanation?
                    At least for C11 according to http://www.open-std.org/jtc1/sc22/wg...docs/n1570.pdf (which was the emphasis at that time),
                    "int", "signed" and "signed int" definitely are the same type (with a possible exception for "int" in "bitfield"s).

                    On page 112 in chapter 6.7.2:

                    Each of the comma-separated multisets designates the same type, except that for bit-
                    fields, it is implementation-defined whether the specifier int designates the same type as
                    signed int or the same type as unsigned int.
                    The relevant subset of these comma-separated multisets:
                    — char
                    — signed char
                    — unsigned char
                    — short, signed short, short int, or signed short int
                    — unsigned short, or unsigned short int
                    — int, signed, or signed int
                    — unsigned, or unsigned int
                    — long, signed long, long int, or signed long int
                    — unsigned long, or unsigned long int
                    — long long, signed long long, long long int, or signed long long int
                    — unsigned long long, or unsigned long long int
                    ---
                    Regarding the second part of your post:

                    Originally posted by andreano View Post
                    Assuming I didn't hit any UB (which of course would invalidate the result), the unsigned type seems to win even when the signed type ranks higher. I think I see why:
                    1. (irrelevant) If both operands have the same type, then no further conversion is needed.
                    2. (irrelevant) Otherwise, if both operands have signed integer types or both have unsigned integer types …
                    3. (irrelevant) Otherwise, if the unsigned operand has rank greater or equal rank than the signed operand …
                    4. (irrelevant) Otherwise, if the signed operand can represent all of the values of the unsigned operand…
                    5. (relevant) Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
                    Only rule 4 could cause implicit conversion to signed, which speaks about representing all the values of the other – doesn't care about rank!
                    In the example that was discussed previously, rule 3 would already be effective, but even so I would agree from the perspective of those C11 rules: an unsigned operand is converted to signed only if the signed type can hold all values. If that is not the case, the signed value will be converted to an unsigned type, the question is only which one. So these conversions will be defined behavior.

                    Which does mean that just regarding "defined behavior", it doesn't matter if the types are "corresponding". But just in that regard, it also doesn't matter if they are the "same", doesn't it?

                    Nevertheless, the result may be very unexpected when ("when" more than "if") the mixed signedness escapes attention. So: much better to use a typecast.

                    Comment


                    • Originally posted by andreano View Post

                      That may explain it. Except, where do you have it from that int, signed and signed int are to be interpreted as different types? If different, then yes, the standard says they must have different rank, but if they are the same type, they of course must have the same rank too. I always thought of them as the same type, and when reading it this way, the ranking system seems a lot less cursed. Could this be the explanation?

                      We can ask C++17 if they are the same type, at least in that language. This holds on gcc and clang on x86_64:

                      Code:
                      #include <type_traits>
                      #include <stdint.h>
                      
                      static_assert(std::is_same_v<int, signed>);
                      static_assert(std::is_same_v<int, signed int>);
                      static_assert(std::is_same_v<long, long int>);
                      static_assert(std::is_same_v<long, signed long>);
                      static_assert(std::is_same_v<long, signed long int>);
                      
                      // x86_64
                      static_assert(std::is_same_v<int, int32_t>);
                      static_assert(std::is_same_v<long, int64_t>);
                      We can also ask if types that are required to have different rank are also different types, which they are:

                      Code:
                      static_assert(not std::is_same_v<long, long long>);
                      static_assert(not std::is_same_v<unsigned long, unsigned long long>);
                      So far, so good, I would say. Now, let's see if we can provocate an implicit cast to the signed type, for a case where the types have the same number of bits, by choosing a signed type with higher rank than the “corresponding” unsigned type, for any of the plausible suspects for “corresponding”:

                      Code:
                      template <typename Signed, typename Unsigned>
                      constexpr bool gt()
                      {
                      Signed negative = -1;
                      Unsigned positive = 1;
                      return negative > positive;
                      }
                      
                      static_assert(gt<long long, unsigned long>());
                      static_assert(gt<long long, unsigned long int>());
                      static_assert(gt<long long int, unsigned long>());
                      static_assert(gt<long long int, unsigned long int>());
                      static_assert(gt<signed long long, unsigned long>());
                      static_assert(gt<signed long long, unsigned long int>());
                      static_assert(gt<signed long long int, unsigned long>());
                      static_assert(gt<signed long long int, unsigned long int>());
                      Assuming I didn't hit any UB (which of course would invalidate the result), the unsigned type seems to win even when the signed type ranks higher. I think I see why:
                      1. (irrelevant) If both operands have the same type, then no further conversion is needed.
                      2. (irrelevant) Otherwise, if both operands have signed integer types or both have unsigned integer types …
                      3. (irrelevant) Otherwise, if the unsigned operand has rank greater or equal rank than the signed operand …
                      4. (irrelevant) Otherwise, if the signed operand can represent all of the values of the unsigned operand…
                      5. (relevant) Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
                      Only rule 4 could cause implicit conversion to signed, which speaks about representing all the values of the other – doesn't care about rank!
                      You got the C++ version of introduction wrong. std::is_same_v comes in C++11 this is important to see the relationship of the problem to C11 and how the C++ standard responded to the C11 draft being goofed.

                      Originally posted by indepe View Post
                      At least for C11 according to http://www.open-std.org/jtc1/sc22/wg...docs/n1570.pdf (which was the emphasis at that time),
                      "int", "signed" and "signed int" definitely are the same type (with a possible exception for "int" in "bitfield"s).
                      This is a case indepe you need to read the C++ standards in this case C++11. Yes C++11 design is based off a draft versions of C11. Yes that include the draft C11 versions that allow for your conversion order to be totally upside down.

                      C++17 you are technically not allow upside down auto conversion to be correct it was forbid in C++14 so only valid for 3 years of the C++ standard as in allowed in C++11 then revoked in C++14. When I say upside down that is unsigned to signed conversion. But C++11 you are allowed upside down auto conversion. Yes you are allowed the rank system screwed up that way with C++11 as well.. Yes this is all traces back to C90 and early C11 draft being based off C90 and then C++11 being based off C11 draft this is a chain of fail. Hopefully we are now at the end of this chain and no one starts it again.

                      There are reasons you will want to avoid C++11, C11 draft and C90 based compilers. Yes the cause of this line of fail is C90. Yes and you have gcc still checking your code for issues that could cause you trouble if you use C++11 or C11 draft or C90 based compilers.

                      This is just a cursed standard making process. Its horrible but standard making process does at times serous-ally goof the process and when this is for a programming language results in some serous-ally goofed compilers being out there to run into. Note this is the C and C++ example of one of these goof. There are other programming language who standard have had equal goofs. Really it would be egg on face if rust ever has a stuff up like this.

                      Comment

                      Working...
                      X