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

  • #71
    Originally posted by andreano View Post
    I think my point still holds, that some of what -Wsign-compare complains about (such as equality comparison between equally large integer types of different signedness) is completely fine and language defined and therefore only detrimental to warn about.

    I think my point still holds, that some of what -Wsign-compare complains about (such as equality comparison between equally large integer types of different signedness) is completely fine and language defined and therefore only detrimental to warn about.
    This is you are wrong.
    https://wiki.sei.cmu.edu/confluence/...nversion+rules
    The rank of any extended signed integer type relative to another extended signed integer type with the same precision is implementation-defined but still subject to the other rules for determining the integer conversion rank.
    Unsigned to Unsigned in C is defined by the standard of C how it will be done. Compare between Signed vs Signed of different type or Signed vs unsigned is a do you fell lucky punk on how it converted if you do not put cast declares there. Implementation defined/undefined by standard behaviour is not exactly fun.

    The rules for - values to a unsigned Int are really horrible in the C standard if you compiler obeys them. That right all signed values get converted to that in the Noncompliant Code Example of that page as well. Yes that example there has two int of equal size and different signedness and how the standard says for it to screw up. Of course it does not have to screw up that way due to rank of unsigned vs signed being implementation defined.

    The reality if you are in C yes it defined as I will be compiler implementation detail how it works.

    -Wsign-compare is warning you when you are doing things that are in the defined C standard as noncompliant to C standard code and if that code does something you are not expecting that your problem. So -Wsign-compare errors are absolute ones you should not ignore..


    Code:
    int si = -1;
    unsigned int ui = 1;
    printf("%d\n", si < ui);
    This example is a lot more unpredictable than that page makes out as well.

    It all depends on the conversion rank of int vs unsigned int. Please note the compiler is free to put these in any order they like by the C standard.

    So if int(the signed one) is a high conversion rank than unsigned int then the unsigned value gets converted to the int(the signed one) here resulting this sample code is of course true(1). Now if the conversion rank is the other way over -1 in the int end up converted to unsgined end up a UINT_MAX so that compare is now false(0). This is valid for the C standard to have both these outcomes.

    Code:
    int si = -1;
    signed int ssi =  -2;
    printf("%d\n", si > ssi);
    Now this one is underhanded evil. If you compiler has a conversion rank pattern of signed int, unsigned int, int (yes valid by standard)the outcome here is really surprising to a lot of people false(0). What happened si was covered twice once to unsigned then finally back to signed int resulting in max - signed int value. So what you excepting as true value is now also a false.

    Horrible this is all perfectly valid to the c standard. These areas of horrible defined undefined are really nasty.

    Comparing signed to unsigned in C is dangerous and just as dangerous as comparing signed to signed of different types even if they are the same bit width all due to the C standard defines of ranks of conversion. The type conversion rules of C are a total stack of evil that can result in very wacky things happening and be perfectly valid to standard. -Wsign-compare is truly warning you about non standard conforming(not safe) C code.
    Last edited by oiaohm; 09 September 2021, 08:00 PM. Reason: added more detail explain.

    Comment


    • #72
      Originally posted by oiaohm View Post
      Horrible this is all perfectly valid to the c standard. These areas of horrible defined undefined are really nasty.
      Which makes the argument that "maybe -Werror will break the build on newer compiler versions" funnier, since keeping these kind of behavior could just break runtime on current compilers. I'd rather have a broken build than get my filesystems silently corrupted.

      Comment


      • #73
        Originally posted by andreano View Post
        I think my point still holds, that some of what -Wsign-compare complains about (such as equality comparison between equally large integer types of different signedness) is completely fine and language defined and therefore only detrimental to warn about.
        I think if you want to compare two such values for equality, and be "completely fine", you'd have to do this:

        Code:
        uint64_t uval = x;
        int64_t  sval = y:
        
        if ((sval >= 0) && ((uint64_t)sval == uval)) {
            // they are equal
        }
        (Pardon me for adding the typecast anyway.)

        A comparison like (sval == uval) only works if sval is always non-negative (or perhaps if uval is always small enough). So to make that visible to the reader of the code, it is much better to add a typecast and write at least "((uint64_t)sval == uval)", so that someone else, or your future self in 5 years, still can easily tell that the comparison depends on the range of the values to work correctly.

        So I don't expect a warning only if something is wrong, but also if something should or could be done more carefully (and benefits from thinking twice about it).

        Comment


        • #74
          Originally posted by indepe View Post
          The kernel doesn't have C++ though (or does it?). You can't necessarily do that with any compiler/language. However it has been done with C and gcc for more than a decade (even if apparently not always perfectly), so I'd expect that to work, and I expect Linus to know if that wasn't achievable.
          You're missing the point, this compiler (even though it was in a different mode) CAN and WILL throw warnings at you for valid code that you can't suppress in a proper way. There's no "bringing it to the maintainers", it's just an anti-pattern that shouldn't exist in a modern compiler.

          It is arrogant to believe that you don't have any bugs or oversight (especially with the language evolutions) and that you don't need to provide a way to disable a warning.

          Comment


          • #75
            Originally posted by Orphis View Post

            You're missing the point, this compiler (even though it was in a different mode) CAN and WILL throw warnings at you for valid code that you can't suppress in a proper way. There's no "bringing it to the maintainers", it's just an anti-pattern that shouldn't exist in a modern compiler.
            I didn't miss the point, I refuted your examples.

            Originally posted by Orphis View Post
            It is arrogant to believe that you don't have any bugs or oversight (especially with the language evolutions) and that you don't need to provide a way to disable a warning.
            You could say the same thing about a lot of other things in a compiler, there is just a lot of things that have to go right for the build product to be usable. Warnings are no exception, on the contrary. They are important and they have to work. I have more than decade experience with "no warnings" myself, clang and gcc. (And with running static analyzers additionally.)

            Comment


            • #76
              Originally posted by indepe View Post

              I think if you want to compare two such values for equality, and be "completely fine", you'd have to do this:

              Code:
              uint64_t uval = x;
              int64_t sval = y:
              
              if ((sval >= 0) && ((uint64_t)sval == uval)) {
              // they are equal
              }
              (Pardon me for adding the typecast anyway.)
              No the type case was in fact required if you want to remain out of defined undefined behaviour of C. If the sval is not type cast the compiler is in its right to covert the uval to int64_t and depending on the rank of conversions what in heck happens to it. A cast conversion under C is a direct from X type to Y type. A rank version where you let the compiler do it own thing could be 400 conversions deep for all you know and any one of those conversions could be buggy.

              Yes without type cast in theory the complier could choose to convert by uval uint64_t and sval int64_t to some other in the middle type with some other conversion quirk. Letting the C complier think for itself can be really bad move.

              C standard is pure evil with automatic type conversion the C standard when read careful truly does say you cannot trust it. It might work but you might be totally screwed over and both results is perfect valid for C todo to you..
              Last edited by oiaohm; 10 September 2021, 12:20 AM.

              Comment


              • #77
                Originally posted by sinepgib View Post
                Which makes the argument that "maybe -Werror will break the build on newer compiler versions" funnier, since keeping these kind of behavior could just break runtime on current compilers. I'd rather have a broken build than get my filesystems silently corrupted.
                Worse is the fact that newer compiler could be picking a a fault the older compiler was let slide so the kernel built with the older complier was like slowly destroying file system. This is why its kind of important to find out what in hell is this new warning.

                Originally posted by Orphis View Post
                You're missing the point, this compiler (even though it was in a different mode) CAN and WILL throw warnings at you for valid code that you can't suppress in a proper way. There's no "bringing it to the maintainers", it's just an anti-pattern that shouldn't exist in a modern compiler.
                The reality is it very rare of gcc or llvm to throw a warning on truly valid code.
                #pragma GCC diagnostic

                exists in both llvm and gcc to deal with this problem. Include the means to absolutely disable all warnings in section of code. Yes you can even print out message on each side stating that this warning has been suppressed.

                Originally posted by Orphis View Post
                It is arrogant to believe that you don't have any bugs or oversight (especially with the language evolutions) and that you don't need to provide a way to disable a warning.
                Orphis it like the arguement I had from person saying -Wsign-compare is wrong. The reality is every time this warning goes off you are doing something that is not supported by the C standard.

                This is the problem there is a lot of things people code that when you get out the C standard and read it what is coded is undefined behavour to C standard or worse define undefined behaviour in the C standard.

                Orphis there is a serous problem with people being over arrogant and thinking their code is valid code so the warning has to be wrong when in reality their code is in fact using undefined behaviour or define undefined behaviour of the C standard. Yes those case the warning is right person writing the program is wrong. Majority of the cases with warnings the developers is in the wrong.

                Comment


                • #78
                  Originally posted by oiaohm View Post
                  No the type case was in fact required if you want to remain out of defined undefined behaviour of C. If the sval is not type cast the compiler is in its right to covert the uval to int64_t and depending on the rank of conversions what in heck happens to it. A cast conversion under C is a direct from X type to Y type. A rank version where you let the compiler do it own thing could be 400 conversions deep for all you know and any one of those conversions could be buggy.
                  You may very well be correct there in terms of (un-)defined behavior, and in actual code I would use the typecast just as I have written it in the code section.

                  Comment


                  • #79
                    Originally posted by oiaohm View Post
                    The reality is it very rare of gcc or llvm to throw a warning on truly valid code.
                    #pragma GCC diagnostic

                    exists in both llvm and gcc to deal with this problem. Include the means to absolutely disable all warnings in section of code. Yes you can even print out message on each side stating that this warning has been suppressed.
                    It isn't usable in all contexts as I indicated above. It doesn't scale, and leads to code rot as you might disable a lot more than you should.

                    Originally posted by oiaohm View Post
                    It like the arguement I had from person saying -Wsign-compare is wrong. The reality is every time this warning goes off you are doing something that is not supported by the C standard.
                    No, it's not the same thing. Humans not understanding some warnings in their code doesn't preclude the fact that compilers can also be wrong sometimes.

                    Comment


                    • #80
                      Originally posted by Orphis View Post
                      It isn't usable in all contexts as I indicated above. It doesn't scale, and leads to code rot as you might disable a lot more than you should.
                      Not having -Werror on is also disabling checks than you should as well.

                      Should dealing with warnings auto scale the answer is no it should not.

                      Originally posted by Orphis View Post
                      No, it's not the same thing. Humans not understanding some warnings in their code doesn't preclude the fact that compilers can also be wrong sometimes.
                      The compiler being wrong is a lot more rare than the human being wrong with warnings.

                      Horrible fact here when a compiler warning is wrong and not disable by some flag compiler itself will also build wrong in the binary build in most cases.



                      The reality here is disabling warning by the command line options is high risk. -Werror on by default is the correct move.

                      Warnings from compilers are not something that you should just straight up ignore. Compiler throwing a warning always need more detailed inspection. Yes it could be adding __attribute__ value so the compiler understand what the code is doing better.

                      Orphis "gcc -w -Werror" this combination in the gcc command line is fun -w disables all warnings of course that makes -Werror a no op. So yes you can force gcc and llvm to build with a -Werror commandline set by overriding the gcc/llvm with alias with -w. Now should you most likely no.

                      Yes tell me some of the options that you have not been able turn off.

                      Each of these specific warning options also has a negative form beginning `-Wno-' to turn off warnings; for example, -Wno-implicit. This manual lists only one of the two forms, whichever is not the default.


                      This is something interest as well. When you cannot turn off a warning message with a command line flag starting with -Wno- with gcc and llvm you have a reportable compiler bug as you are using a broken compiler. Of course when you have turned off a warning message -Werror is not going to trigger.

                      Please note gcc and llvm negative form being warning disable with -Wno- is meant to be dominate over the positive form of normal -Wsomething. Yes this is why -w kills -Werror.

                      Yes nothing says that the compiler you have cannot be broken. Issue here strict rules to gcc and llvm warning menssages are clear you should be able to turn off all warning messages with command line -Wno- options and leave -Werror on if you cannot you have a gcc or llvm compiler bug. Yes that compiler bug could be a tip of a very big iceberg of problems.

                      Yes the -w option is fail safe that you should only need to use with a broken build of gcc or llvm. People normally don't want to find out what is the new warning option ruining their day. When in reality they should.

                      Orphis the reality here compliers have rules to their construction. Gcc and llvm a new warning has to own command group of warnings. All warnings must be able to be disabled by the command line using the -Wno- options and Diagnostic Pragmas if you have found some that cannot be I hope you have opened a bug report. Remember this is saying compiler bug. Yes to have this problem you are using a defective gcc or llvm.

                      Comment

                      Working...
                      X