stupid void**

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Chris Becke

    stupid void**

    In C and in older C++ compilers, you could write code like this

    void a(void** pp); // declare a function that takes a pointer to a pointer-to-void.
    struct I {}; // some struct.
    I *i1,**i2; // some kinds of i.

    a(&i1); // this works
    a(i2); // this also worked.
    a(i1); // error: incorrect levels of indirection
    a(&i2); // error: incorrect levels of indirection

    Now, c++ compilers just don't like void* anymore. meaning we absolutely have to static cast to a void** because c++ compiler are too damn high and mighty to let a void** slip past on a mere levels of indirection check.

    a((void**)&i1); // this works
    a((void**)i2); // this also worked.
    a((void**)i1); // oops
    a((void**)&i2); // oops

    Yay for c++ helping us avoid bugs.
    indirection checking was useful damnit.
  • Andrey Tarasevich

    #2
    Re: stupid void**

    Chris Becke wrote:
    In C and in older C++ compilers, you could write code like this
    >
    void a(void** pp); // declare a function that takes a pointer to a pointer-to-void.
    struct I {}; // some struct.
    I *i1,**i2; // some kinds of i.
    >
    a(&i1); // this works
    a(i2); // this also worked.
    a(i1); // error: incorrect levels of indirection
    a(&i2); // error: incorrect levels of indirection
    No, you couldn't. Neither in C nor in C++. None of these ever "worked".
    Apparently, you've been using some silly old broken compiler and a bunch
    of your own hacks, and for some reason mistook that compiler's silly
    quirks for C and/or C++ language features.
    Now, c++ compilers just don't like void* anymore. meaning we absolutely
    have to static cast to a void** because c++ compiler are too damn high
    and mighty to let a void** slip past on a mere levels of
    indirection check.
    Huh? You seemed to be talking about 'void**'. And here you suddenly
    mention 'void*', which has very little to do with 'void**'.

    BTW, "static cast to void**"? The casts in question cannot be performed
    by 'static_cast'. If your compiler allows it, it probably means that you
    are continuing to stick with some rather silly compiler.
    a((void**)&i1); // this works
    a((void**)i2); // this also worked.
    a((void**)i1); // oops
    a((void**)&i2); // oops
    >
    Yay for c++ helping us avoid bugs.
    indirection checking was useful damnit.
    All these four calls are "bugs", just like the original four calls were.
    The are "bugs" in a sense that that the resultant pointer cannot be
    immediately used as a 'void**' pointer anyway. The compiler you are
    using now looks better because it refuses to compile the useless
    original code. This should have been something to make you think about
    what you are doing. Instead, you decided to slap a cast on it to sweep
    the error under the carpet. Well, no wonder all you get from it is a
    bunch of "oops"!

    --
    Best regards,
    Andrey Tarasevich

    Comment

    • blargg

      #3
      Re: stupid void**

      Chris Becke wrote:
      In C and in older C++ compilers, you could write code like this
      >
      void a(void** pp); // declare a function that takes a pointer to a
      pointer-to-void.
      struct I {}; // some struct.
      I *i1,**i2; // some kinds of i.
      >
      a(&i1); // this works
      a(i2); // this also worked.
      a(i1); // error: incorrect levels of indirection
      a(&i2); // error: incorrect levels of indirection
      >
      Now, c++ compilers just don't like void* anymore. meaning we absolutely
      have to static cast to a void** because c++ compiler are too damn high
      and mighty to let a void** slip past on a mere levels of indirection
      check.
      >
      a((void**)&i1); // this works
      a((void**)i2); // this also worked.
      a((void**)i1); // oops
      a((void**)&i2); // oops
      >
      Yay for c++ helping us avoid bugs.
      Yes, indeed, disallowing it eliminates bugs. If T** implicitly converted
      to void**, you could do

      int* p;
      void** pp = &p; // error, but you're arguing that this be allowed
      char c;
      *pp = &c; // if allowed, would be equivalent to
      // reinterpret_cas t<void*&(p) = &c
      *p = 1234; // oops, p points to a char

      without any casting. Also, if the standard required a compiler to allow
      this, it would have to use the same representation for all pointer types,
      rather than as currently where it can use fewer bits for pointers to types
      with alignment requirements more strict than char's.

      Comment

      • Old Wolf

        #4
        Re: stupid void**

        On Nov 12, 10:21 pm, "Chris Becke" <chris.be...@gm ail.comwrote:
        In C and in older C++ compilers, you could write code like this
        >
          void a(void** pp); // declare a function that takes a pointer to a pointer-to-void.
          struct I {}; // some struct.
          I *i1,**i2; // some kinds of i.
        >
          a(&i1);  // this works
          a(i2);     // this also worked.
          a(i1);     // error: incorrect levels of indirection
          a(&i2);  // error: incorrect levels of indirection
        Just backing up what Andrey said; none of these ever
        worked in any standard version of C or C++. A void**
        can only point to exactly a void* , not anything else.

        Comment

        • Chris Becke

          #5
          Re: stupid void**

          "blargg" <blargg.h4g@gis hpuppy.comwrote in message news:blargg.h4g-121108123825000 1@192.168.1.4.. .
          Chris Becke wrote:
          without any casting. Also, if the standard required a compiler to allow
          this, it would have to use the same representation for all pointer types,
          rather than as currently where it can use fewer bits for pointers to types
          with alignment requirements more strict than char's.
          C99 still allows transformation to AND from void*

          void* x;
          int* y;
          x=y; // both are legal in C99. At least the latest versions of MSVC and GCC compile this fragment.
          y=x;

          That aside, I do get the problem with pointer representations .

          But, it seems a bit subversive to have a universal pointer type, and then disallow it being used as a universal pointer type. In its current form in c++, void* should have just been thrown out. It saves us a typecast only when casting to, not from void*s, and c++ hasn't introduced any kind of indirection counting typecast, making void* worse than dangerous. All because some overly zelous individual decided that void** needs to be treated as a special case, definately note a pointer to a thing that is a void*.


          Comment

          • James Kanze

            #6
            Re: stupid void**

            On Nov 13, 9:18 am, "Chris Becke" <chris.be...@gm ail.comwrote:
            "blargg" <blargg....@gis hpuppy.comwrote in
            messagenews:bla rgg.h4g-121108123825000 1@192.168.1.4.. .
            Chris Becke wrote:
            without any casting. Also, if the standard required a
            compiler to allow this, it would have to use the same
            representation for all pointer types, rather than as
            currently where it can use fewer bits for pointers to types
            with alignment requirements more strict than char's.
            C99 still allows transformation to AND from void*
            void* x;
            int* y;
            x=y; // both are legal in C99. At least the latest versions of MSVC and GCC compile this fragment.
            y=x;
            As does C++. The only difference is that C++ requires a
            static_cast for the conversion from void*.
            That aside, I do get the problem with pointer representations .
            But, it seems a bit subversive to have a universal pointer
            type, and then disallow it being used as a universal pointer
            type.
            The universal pointer type is void*, not void**.
            In its current form in c++, void* should have just been thrown
            out. It saves us a typecast only when casting to, not from
            void*s,
            Which is probably a mistake---it should probably require the
            conversion to be explicit in both directions.
            and c++ hasn't introduced any kind of indirection
            counting typecast, making void* worse than dangerous.
            I'm not sure that I follow you here. C++ didn't change the
            meaning of void* from that of C.
            All because some overly zelous individual decided that void**
            needs to be treated as a special case, definately note a
            pointer to a thing that is a void*.
            What? void** (unlike void*) isn't a special case at all; it's a
            pointer to a void*, and only to a void*. If I understand your
            initial code, you wanted it to point to an int*.

            And I don't know who you mean by "some overly zealous
            individual". It's been that way in both C and C++ ever since
            there was void.

            --
            James Kanze (GABI Software) email:james.kan ze@gmail.com
            Conseils en informatique orientée objet/
            Beratung in objektorientier ter Datenverarbeitu ng
            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

            Comment

            • James Kanze

              #7
              Re: stupid void**

              On Nov 13, 1:15 am, Old Wolf <oldw...@inspir e.net.nzwrote:
              On Nov 12, 10:21 pm, "Chris Becke" <chris.be...@gm ail.comwrote:
              In C and in older C++ compilers, you could write code like this
              void a(void** pp); // declare a function that takes a pointer to a pointer-to-void.
              struct I {}; // some struct.
              I *i1,**i2; // some kinds of i.
              >
              a(&i1); // this works
              a(i2); // this also worked.
              a(i1); // error: incorrect levels of indirection
              a(&i2); // error: incorrect levels of indirection
              Just backing up what Andrey said; none of these ever
              worked in any standard version of C or C++. A void**
              can only point to exactly a void* , not anything else.
              You can drop the standard---they've never worked in any version
              of C or C++. (Some very, very early versions of C did allow
              implicit conversions between any pointer types. Even then,
              however, this was documented as and "unintentio nal"
              feature---that the language itself required an explicit
              conversion. And of course, this was long before there was a
              keyword void.)

              --
              James Kanze (GABI Software) email:james.kan ze@gmail.com
              Conseils en informatique orientée objet/
              Beratung in objektorientier ter Datenverarbeitu ng
              9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

              Comment

              • Andrey Tarasevich

                #8
                Re: stupid void**

                Chris Becke wrote:
                >
                C99 still allows transformation to AND from void*
                >
                void* x;
                int* y;
                x=y; // both are legal in C99. At least the latest versions of MSVC and GCC compile this fragment.
                y=x;
                >
                That aside, I do get the problem with pointer representations .
                >
                But, it seems a bit subversive to have a universal pointer type, and then
                disallow it being used as a universal pointer type. In its current
                form in c++, void* should have just been thrown out.
                This is all great, but it is about 'void*', while your original message
                was about 'void**', which is a completely different thing.
                It saves us a typecast only when casting to, not from void*s, and c++
                hasn't introduced any kind of indirection counting typecast,
                C doesn't have any "indirectio n counting typecasts" either. If you saw
                something like that in the past, it probably was a fancy feature of some
                specific compiler.
                making void* worse than dangerous.
                'void*'??? No.
                All because some overly zelous individual decided that void** needs to
                be treated as a special case, definately note a pointer to a thing
                that is a void*.
                No, you got it completely upside down. 'void**' is not treated as a
                special case. The contrary is true: 'void**' is treated as a general
                case. 'int**' cannot converted to 'void**' for precisely the same
                reasons why, say, 'int*' cannot be converted to 'double*' (despite the
                valid 'int' -'double' conversion).

                --
                Best regards,
                Andrey Tarasevich

                Comment

                • Rolf Magnus

                  #9
                  Re: stupid void**

                  Chris Becke wrote:
                  "blargg" <blargg.h4g@gis hpuppy.comwrote in message
                  news:blargg.h4g-121108123825000 1@192.168.1.4.. .
                  >Chris Becke wrote:
                  >without any casting. Also, if the standard required a compiler to allow
                  >this, it would have to use the same representation for all pointer types,
                  >rather than as currently where it can use fewer bits for pointers to
                  >types with alignment requirements more strict than char's.
                  >
                  C99 still allows transformation to AND from void*
                  Yes. but a pointer to void is not the same as a pointer to a pointer.
                  But, it seems a bit subversive to have a universal pointer type, and then
                  disallow it being used as a universal pointer type.
                  It's not. For any pointer, the standard requires that its value can be
                  converted to void* and back without loss. What it doesn't say is that such a
                  pointer can be converted into a pointer to pointer and back without loss.
                  It saves us a typecast only when casting to, not from void*s, and c++
                  hasn't introduced any kind of indirection counting typecast, making void*
                  worse than dangerous.
                  A void** isn't just a void pointer with one additional level of indirection
                  or something like that. It's a different pointer type.
                  All because some overly zelous individual decided that void** needs to be
                  treated as a special case, definately note a pointer to a thing that is a
                  void*.
                  There is no special case. void** is just handle the same as pointers to any
                  other pointer type.

                  Comment

                  • Pete Becker

                    #10
                    Re: stupid void**

                    On 2008-11-13 13:28:17 -0500, Rolf Magnus <ramagnus@t-online.desaid:
                    >
                    A void** isn't just a void pointer with one additional level of indirection
                    or something like that. It's a different pointer type.
                    And it can be implicitly converted to void*, just like any other pointer type.

                    --
                    Pete
                    Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
                    Standard C++ Library Extensions: a Tutorial and Reference
                    (www.petebecker.com/tr1book)

                    Comment

                    • Old Wolf

                      #11
                      Re: stupid void**

                      On Nov 13, 10:57 pm, James Kanze <james.ka...@gm ail.comwrote:
                      On Nov 13, 1:15 am, Old Wolf <oldw...@inspir e.net.nzwrote:
                      Just backing up what Andrey said; none of these ever
                      worked in any standard version of C or C++. A void**
                      can only point to exactly a void* , not anything else.
                      >
                      You can drop the standard---they've never worked in any version
                      of C or C++.
                      I'm generally cautious about saying "any version
                      of C" -- there have been a lot of weird compiler
                      extensions and bugs over the years!

                      Comment

                      Working...