Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (Cyborg)
  • No Skin
Collapse
Brand Logo

CIRCLE WITH A DOT

  1. Home
  2. Uncategorized
  3. "Fun bug of the month, mesa edition, episode may"

"Fun bug of the month, mesa edition, episode may"

Scheduled Pinned Locked Moved Uncategorized
25 Posts 11 Posters 33 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • karolherbst@chaos.socialK karolherbst@chaos.social

    "Fun bug of the month, mesa edition, episode may"

    so if you do "uint64_t some_var = 1 << 31;" in C you get "0xffffffff80000000" as the value, because that's super obvious and not confusing at all.

    It's pretty funny getting reminded how non-intuitive and broken C is from time to time.

    pavel@social.kernel.orgP This user is from outside of this forum
    pavel@social.kernel.orgP This user is from outside of this forum
    pavel@social.kernel.org
    wrote last edited by
    #15
    @karolherbst C is 1973 or so. If you believe it is confusing, try assembly :-).
    1 Reply Last reply
    0
    • trilader@chaos.socialT trilader@chaos.social

      @karolherbst For my understanding: That's default int promotion + sign extend on 64 bit extension? Would 1L << 31L fix this or is there other pitfalls with that?

      pavel@social.kernel.orgP This user is from outside of this forum
      pavel@social.kernel.orgP This user is from outside of this forum
      pavel@social.kernel.org
      wrote last edited by
      #16
      @trilader @karolherbst Yes, int promotion. 1L<<31L would still be broken on 32-bit architectures (as long is 32 bit there). You'd need 1LL or something, AFAICT.
      1 Reply Last reply
      0
      • trilader@chaos.socialT trilader@chaos.social

        @karolherbst For my understanding: That's default int promotion + sign extend on 64 bit extension? Would 1L << 31L fix this or is there other pitfalls with that?

        pavel@social.kernel.orgP This user is from outside of this forum
        pavel@social.kernel.orgP This user is from outside of this forum
        pavel@social.kernel.org
        wrote last edited by
        #17
        @trilader @karolherbst Actually right solution would be uint64_t some_var = ((uint 64_t)1) << 31; AFAICT.
        karolherbst@chaos.socialK 1 Reply Last reply
        0
        • david_chisnall@infosec.exchangeD david_chisnall@infosec.exchange

          @karolherbst @jann

          It’s UB in the general case because, if the operand is not a constant, you want to lower it to a shift instruction but C works with targets that have different number representations. Ones or twos complements, or explicit sign bits are all permitted, but all of these will give different behaviours if you flip the top bit.

          For wider shifts, different ISAs had different semantics for shifts wider than the register, so C made that fully undefined.

          This combination lets you lower source-level shifts to a shift instruction.

          C also doesn’t mandate that this be constant evaluated unless the result is used as a constant, so there’s no way to force implementations to diagnose the UB at compile time for this case. But, as a QoI issue, it is permitted and compilers should.

          karolherbst@chaos.socialK This user is from outside of this forum
          karolherbst@chaos.socialK This user is from outside of this forum
          karolherbst@chaos.social
          wrote last edited by
          #18

          @david_chisnall @jann at least C23 fixes one part of this by requiring two's complement for integers.

          But also, I just wished C would mandate that constants are just assumed to be of the "expected" type, because in 99.999999% of all cases a programmer really meant the obvious thing with "uint64_t x = 1 << 31".

          But I guess we'll just keep those horrible semantics C has in a couple of areas, because nobody want to fix those things, because "it could break things".

          blp@framapiaf.orgB 1 Reply Last reply
          0
          • pavel@social.kernel.orgP pavel@social.kernel.org
            @trilader @karolherbst Actually right solution would be uint64_t some_var = ((uint 64_t)1) << 31; AFAICT.
            karolherbst@chaos.socialK This user is from outside of this forum
            karolherbst@chaos.socialK This user is from outside of this forum
            karolherbst@chaos.social
            wrote last edited by
            #19

            @pavel @trilader the actual right solution would be to fix the language 😛

            pavel@social.kernel.orgP 1 Reply Last reply
            0
            • karolherbst@chaos.socialK karolherbst@chaos.social

              @david_chisnall @jann at least C23 fixes one part of this by requiring two's complement for integers.

              But also, I just wished C would mandate that constants are just assumed to be of the "expected" type, because in 99.999999% of all cases a programmer really meant the obvious thing with "uint64_t x = 1 << 31".

              But I guess we'll just keep those horrible semantics C has in a couple of areas, because nobody want to fix those things, because "it could break things".

              blp@framapiaf.orgB This user is from outside of this forum
              blp@framapiaf.orgB This user is from outside of this forum
              blp@framapiaf.org
              wrote last edited by
              #20

              @karolherbst @david_chisnall @jann That particular change would break a lot!

              1 Reply Last reply
              0
              • karolherbst@chaos.socialK karolherbst@chaos.social

                "Fun bug of the month, mesa edition, episode may"

                so if you do "uint64_t some_var = 1 << 31;" in C you get "0xffffffff80000000" as the value, because that's super obvious and not confusing at all.

                It's pretty funny getting reminded how non-intuitive and broken C is from time to time.

                L This user is from outside of this forum
                L This user is from outside of this forum
                lalufu@mastodon.social
                wrote last edited by
                #21

                @karolherbst I recently read https://www.os2museum.com/wp/bitfield-pitfalls/ which is a similar pitfall?

                1 Reply Last reply
                0
                • karolherbst@chaos.socialK karolherbst@chaos.social

                  @pavel @trilader the actual right solution would be to fix the language 😛

                  pavel@social.kernel.orgP This user is from outside of this forum
                  pavel@social.kernel.orgP This user is from outside of this forum
                  pavel@social.kernel.org
                  wrote last edited by
                  #22
                  @karolherbst @trilader Yeah, travelling to 1972 and changing the language would be best :-).
                  1 Reply Last reply
                  0
                  • karolherbst@chaos.socialK karolherbst@chaos.social

                    "Fun bug of the month, mesa edition, episode may"

                    so if you do "uint64_t some_var = 1 << 31;" in C you get "0xffffffff80000000" as the value, because that's super obvious and not confusing at all.

                    It's pretty funny getting reminded how non-intuitive and broken C is from time to time.

                    lkundrak@metalhead.clubL This user is from outside of this forum
                    lkundrak@metalhead.clubL This user is from outside of this forum
                    lkundrak@metalhead.club
                    wrote last edited by
                    #23

                    @karolherbst taking off my "understands sign extension" badge

                    wore it with pride, but the pride was misplaced

                    1 Reply Last reply
                    0
                    • trilader@chaos.socialT trilader@chaos.social

                      @karolherbst For my understanding: That's default int promotion + sign extend on 64 bit extension? Would 1L << 31L fix this or is there other pitfalls with that?

                      lkundrak@metalhead.clubL This user is from outside of this forum
                      lkundrak@metalhead.clubL This user is from outside of this forum
                      lkundrak@metalhead.club
                      wrote last edited by
                      #24

                      @trilader @karolherbst 1L << alone would do the trick on real world 64-bit machines, but i think compiler is still fully allowed to do the wrong thing. msvc perhaps still has 32-bit longs on 64-bit platforms?

                      i think you need to make sure it's unsigned so that sign extension has no chance of occurring, so my money is on 1U << 31?

                      1 Reply Last reply
                      0
                      • karolherbst@chaos.socialK karolherbst@chaos.social

                        "Fun bug of the month, mesa edition, episode may"

                        so if you do "uint64_t some_var = 1 << 31;" in C you get "0xffffffff80000000" as the value, because that's super obvious and not confusing at all.

                        It's pretty funny getting reminded how non-intuitive and broken C is from time to time.

                        eniko@mastodon.gamedev.placeE This user is from outside of this forum
                        eniko@mastodon.gamedev.placeE This user is from outside of this forum
                        eniko@mastodon.gamedev.place
                        wrote last edited by
                        #25

                        @karolherbst ohhh, footgun i didn't know about yet!

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups