Passing a char pointer to a function accepting a reference to a char array

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
7
down vote

favorite
2












I'm trying to call this method



#define SIZE 16
void DoSomething(char(&value)[SIZE])




From this method:



void BeforeDoingSomething(char* value, int len)

if (len == SIZE)

DoSomething(value);




Attempting to do this gives me this error:




a reference of type "char (&)[16]" (not const-qualified) cannot be initialized with a value of type "char *"




Any tips for how to get the compiler to accept value passed in the function BeforeDoingSomething?










share|improve this question























  • How sure are you that value points to the start of a char[SIZE]? You might be able to reinterpret_cast but I'm not certain. I wouldn't recommend in any case.
    – François Andrieux
    3 hours ago











  • I found a related question here. While it might strictly speaking solve your problem, this feels like an awkward situation. I would encourage you to think about redesigning slightly. Why does DoSomething always need an array of length SIZE? Why can't BeforeDoingSomething always use an array of length SIZE instead of a pointer and length?
    – alter igel
    3 hours ago










  • The reason for this awkward situation is because this is happening within a DLL. The developer who wrote DoSomething wrote it this way, and when a call is made into my DLL it's in the form inside of BeforeDoingSomething. I'm not sure how to even go about enforcing something like char(&value)[SIZE] when it comes to people calling into the DLL (which the callers will not be C++)
    – Zulukas
    3 hours ago














up vote
7
down vote

favorite
2












I'm trying to call this method



#define SIZE 16
void DoSomething(char(&value)[SIZE])




From this method:



void BeforeDoingSomething(char* value, int len)

if (len == SIZE)

DoSomething(value);




Attempting to do this gives me this error:




a reference of type "char (&)[16]" (not const-qualified) cannot be initialized with a value of type "char *"




Any tips for how to get the compiler to accept value passed in the function BeforeDoingSomething?










share|improve this question























  • How sure are you that value points to the start of a char[SIZE]? You might be able to reinterpret_cast but I'm not certain. I wouldn't recommend in any case.
    – François Andrieux
    3 hours ago











  • I found a related question here. While it might strictly speaking solve your problem, this feels like an awkward situation. I would encourage you to think about redesigning slightly. Why does DoSomething always need an array of length SIZE? Why can't BeforeDoingSomething always use an array of length SIZE instead of a pointer and length?
    – alter igel
    3 hours ago










  • The reason for this awkward situation is because this is happening within a DLL. The developer who wrote DoSomething wrote it this way, and when a call is made into my DLL it's in the form inside of BeforeDoingSomething. I'm not sure how to even go about enforcing something like char(&value)[SIZE] when it comes to people calling into the DLL (which the callers will not be C++)
    – Zulukas
    3 hours ago












up vote
7
down vote

favorite
2









up vote
7
down vote

favorite
2






2





I'm trying to call this method



#define SIZE 16
void DoSomething(char(&value)[SIZE])




From this method:



void BeforeDoingSomething(char* value, int len)

if (len == SIZE)

DoSomething(value);




Attempting to do this gives me this error:




a reference of type "char (&)[16]" (not const-qualified) cannot be initialized with a value of type "char *"




Any tips for how to get the compiler to accept value passed in the function BeforeDoingSomething?










share|improve this question















I'm trying to call this method



#define SIZE 16
void DoSomething(char(&value)[SIZE])




From this method:



void BeforeDoingSomething(char* value, int len)

if (len == SIZE)

DoSomething(value);




Attempting to do this gives me this error:




a reference of type "char (&)[16]" (not const-qualified) cannot be initialized with a value of type "char *"




Any tips for how to get the compiler to accept value passed in the function BeforeDoingSomething?







c++






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 5 mins ago









user2357112

142k12146224




142k12146224










asked 3 hours ago









Zulukas

305412




305412











  • How sure are you that value points to the start of a char[SIZE]? You might be able to reinterpret_cast but I'm not certain. I wouldn't recommend in any case.
    – François Andrieux
    3 hours ago











  • I found a related question here. While it might strictly speaking solve your problem, this feels like an awkward situation. I would encourage you to think about redesigning slightly. Why does DoSomething always need an array of length SIZE? Why can't BeforeDoingSomething always use an array of length SIZE instead of a pointer and length?
    – alter igel
    3 hours ago










  • The reason for this awkward situation is because this is happening within a DLL. The developer who wrote DoSomething wrote it this way, and when a call is made into my DLL it's in the form inside of BeforeDoingSomething. I'm not sure how to even go about enforcing something like char(&value)[SIZE] when it comes to people calling into the DLL (which the callers will not be C++)
    – Zulukas
    3 hours ago
















  • How sure are you that value points to the start of a char[SIZE]? You might be able to reinterpret_cast but I'm not certain. I wouldn't recommend in any case.
    – François Andrieux
    3 hours ago











  • I found a related question here. While it might strictly speaking solve your problem, this feels like an awkward situation. I would encourage you to think about redesigning slightly. Why does DoSomething always need an array of length SIZE? Why can't BeforeDoingSomething always use an array of length SIZE instead of a pointer and length?
    – alter igel
    3 hours ago










  • The reason for this awkward situation is because this is happening within a DLL. The developer who wrote DoSomething wrote it this way, and when a call is made into my DLL it's in the form inside of BeforeDoingSomething. I'm not sure how to even go about enforcing something like char(&value)[SIZE] when it comes to people calling into the DLL (which the callers will not be C++)
    – Zulukas
    3 hours ago















How sure are you that value points to the start of a char[SIZE]? You might be able to reinterpret_cast but I'm not certain. I wouldn't recommend in any case.
– François Andrieux
3 hours ago





How sure are you that value points to the start of a char[SIZE]? You might be able to reinterpret_cast but I'm not certain. I wouldn't recommend in any case.
– François Andrieux
3 hours ago













I found a related question here. While it might strictly speaking solve your problem, this feels like an awkward situation. I would encourage you to think about redesigning slightly. Why does DoSomething always need an array of length SIZE? Why can't BeforeDoingSomething always use an array of length SIZE instead of a pointer and length?
– alter igel
3 hours ago




I found a related question here. While it might strictly speaking solve your problem, this feels like an awkward situation. I would encourage you to think about redesigning slightly. Why does DoSomething always need an array of length SIZE? Why can't BeforeDoingSomething always use an array of length SIZE instead of a pointer and length?
– alter igel
3 hours ago












The reason for this awkward situation is because this is happening within a DLL. The developer who wrote DoSomething wrote it this way, and when a call is made into my DLL it's in the form inside of BeforeDoingSomething. I'm not sure how to even go about enforcing something like char(&value)[SIZE] when it comes to people calling into the DLL (which the callers will not be C++)
– Zulukas
3 hours ago




The reason for this awkward situation is because this is happening within a DLL. The developer who wrote DoSomething wrote it this way, and when a call is made into my DLL it's in the form inside of BeforeDoingSomething. I'm not sure how to even go about enforcing something like char(&value)[SIZE] when it comes to people calling into the DLL (which the callers will not be C++)
– Zulukas
3 hours ago












3 Answers
3






active

oldest

votes

















up vote
6
down vote



accepted










As the error explains, you cannot initialize a reference to an array using a pointer.



If and only if you can prove that value does in fact point to (first element of) an array of appropriate type, then what you can do is explicitly reinterpret the pointer, and indirect it:



DoSomething(*std::launder(reinterpret_cast<char(*)[SIZE]>(value)));





share|improve this answer






















  • Is std::launder here because of the strict aliasing rule?
    – Quimby
    3 hours ago






  • 1




    @Quimby Exactly.
    – user2079303
    3 hours ago










  • I think that launder is mandatory here, it is needed in the case of char array as well.
    – geza
    3 hours ago










  • @user2079303 Thank you.
    – Quimby
    3 hours ago










  • @Quimby: Nope. It has nothing to do with strict aliasing rule. It is there to get a pointer which actually points to the char array (as reinterpret_cast doesn't do that for you, as the pointers are not interconvertible).
    – geza
    3 hours ago


















up vote
2
down vote













You can do it like this, but only in the case if there is a char[16] at the address where value points:



DoSomething(*std::launder(reinterpret_cast<char (*)[16]>(value)));


It is the same case as the first example here.






share|improve this answer



























    up vote
    2
    down vote













    The use of std::launder as suggested by @user2079303 is a good option if you are sure that value does indeed point to an array of the right size as mentioned in their answer.



    Yet another approach: since SIZE is fairly small in this case, it may be safer/simpler to create a temporary copy of value and pass it to DoSomething(). But it all depends on what DoSomething() is actually doing (for example, does it modify the array passed to it). For example:



    #include <iostream>
    #include <vector>
    #include <string>

    constexpr int SIZE = 16 ;

    void DoSomething(char (&value)[SIZE])

    std::cout << "Do it!" << std::endl ;


    void BeforeDoingSomething(char* value, int len)

    if (len == SIZE)

    char tmp_array[SIZE] ;
    std::copy(value, value + len, tmp_array) ;
    DoSomething(tmp_array);
    else
    std::cout << "Length: " << len << std::endl ;



    int main()

    std::string foo (SIZE, '-') ;
    BeforeDoingSomething(foo.data(), foo.size()) ;

    std::vector<char> bar (SIZE) ;
    BeforeDoingSomething(bar.data(), bar.size()) ;

    std::string qux ;
    BeforeDoingSomething(qux.data(), qux.size()) ;

    return 0 ;



    Try it online here.






    share|improve this answer






















      Your Answer





      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: false,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52560364%2fpassing-a-char-pointer-to-a-function-accepting-a-reference-to-a-char-array%23new-answer', 'question_page');

      );

      Post as a guest






























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      6
      down vote



      accepted










      As the error explains, you cannot initialize a reference to an array using a pointer.



      If and only if you can prove that value does in fact point to (first element of) an array of appropriate type, then what you can do is explicitly reinterpret the pointer, and indirect it:



      DoSomething(*std::launder(reinterpret_cast<char(*)[SIZE]>(value)));





      share|improve this answer






















      • Is std::launder here because of the strict aliasing rule?
        – Quimby
        3 hours ago






      • 1




        @Quimby Exactly.
        – user2079303
        3 hours ago










      • I think that launder is mandatory here, it is needed in the case of char array as well.
        – geza
        3 hours ago










      • @user2079303 Thank you.
        – Quimby
        3 hours ago










      • @Quimby: Nope. It has nothing to do with strict aliasing rule. It is there to get a pointer which actually points to the char array (as reinterpret_cast doesn't do that for you, as the pointers are not interconvertible).
        – geza
        3 hours ago















      up vote
      6
      down vote



      accepted










      As the error explains, you cannot initialize a reference to an array using a pointer.



      If and only if you can prove that value does in fact point to (first element of) an array of appropriate type, then what you can do is explicitly reinterpret the pointer, and indirect it:



      DoSomething(*std::launder(reinterpret_cast<char(*)[SIZE]>(value)));





      share|improve this answer






















      • Is std::launder here because of the strict aliasing rule?
        – Quimby
        3 hours ago






      • 1




        @Quimby Exactly.
        – user2079303
        3 hours ago










      • I think that launder is mandatory here, it is needed in the case of char array as well.
        – geza
        3 hours ago










      • @user2079303 Thank you.
        – Quimby
        3 hours ago










      • @Quimby: Nope. It has nothing to do with strict aliasing rule. It is there to get a pointer which actually points to the char array (as reinterpret_cast doesn't do that for you, as the pointers are not interconvertible).
        – geza
        3 hours ago













      up vote
      6
      down vote



      accepted







      up vote
      6
      down vote



      accepted






      As the error explains, you cannot initialize a reference to an array using a pointer.



      If and only if you can prove that value does in fact point to (first element of) an array of appropriate type, then what you can do is explicitly reinterpret the pointer, and indirect it:



      DoSomething(*std::launder(reinterpret_cast<char(*)[SIZE]>(value)));





      share|improve this answer














      As the error explains, you cannot initialize a reference to an array using a pointer.



      If and only if you can prove that value does in fact point to (first element of) an array of appropriate type, then what you can do is explicitly reinterpret the pointer, and indirect it:



      DoSomething(*std::launder(reinterpret_cast<char(*)[SIZE]>(value)));






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 3 hours ago

























      answered 3 hours ago









      user2079303

      69.6k550109




      69.6k550109











      • Is std::launder here because of the strict aliasing rule?
        – Quimby
        3 hours ago






      • 1




        @Quimby Exactly.
        – user2079303
        3 hours ago










      • I think that launder is mandatory here, it is needed in the case of char array as well.
        – geza
        3 hours ago










      • @user2079303 Thank you.
        – Quimby
        3 hours ago










      • @Quimby: Nope. It has nothing to do with strict aliasing rule. It is there to get a pointer which actually points to the char array (as reinterpret_cast doesn't do that for you, as the pointers are not interconvertible).
        – geza
        3 hours ago

















      • Is std::launder here because of the strict aliasing rule?
        – Quimby
        3 hours ago






      • 1




        @Quimby Exactly.
        – user2079303
        3 hours ago










      • I think that launder is mandatory here, it is needed in the case of char array as well.
        – geza
        3 hours ago










      • @user2079303 Thank you.
        – Quimby
        3 hours ago










      • @Quimby: Nope. It has nothing to do with strict aliasing rule. It is there to get a pointer which actually points to the char array (as reinterpret_cast doesn't do that for you, as the pointers are not interconvertible).
        – geza
        3 hours ago
















      Is std::launder here because of the strict aliasing rule?
      – Quimby
      3 hours ago




      Is std::launder here because of the strict aliasing rule?
      – Quimby
      3 hours ago




      1




      1




      @Quimby Exactly.
      – user2079303
      3 hours ago




      @Quimby Exactly.
      – user2079303
      3 hours ago












      I think that launder is mandatory here, it is needed in the case of char array as well.
      – geza
      3 hours ago




      I think that launder is mandatory here, it is needed in the case of char array as well.
      – geza
      3 hours ago












      @user2079303 Thank you.
      – Quimby
      3 hours ago




      @user2079303 Thank you.
      – Quimby
      3 hours ago












      @Quimby: Nope. It has nothing to do with strict aliasing rule. It is there to get a pointer which actually points to the char array (as reinterpret_cast doesn't do that for you, as the pointers are not interconvertible).
      – geza
      3 hours ago





      @Quimby: Nope. It has nothing to do with strict aliasing rule. It is there to get a pointer which actually points to the char array (as reinterpret_cast doesn't do that for you, as the pointers are not interconvertible).
      – geza
      3 hours ago













      up vote
      2
      down vote













      You can do it like this, but only in the case if there is a char[16] at the address where value points:



      DoSomething(*std::launder(reinterpret_cast<char (*)[16]>(value)));


      It is the same case as the first example here.






      share|improve this answer
























        up vote
        2
        down vote













        You can do it like this, but only in the case if there is a char[16] at the address where value points:



        DoSomething(*std::launder(reinterpret_cast<char (*)[16]>(value)));


        It is the same case as the first example here.






        share|improve this answer






















          up vote
          2
          down vote










          up vote
          2
          down vote









          You can do it like this, but only in the case if there is a char[16] at the address where value points:



          DoSomething(*std::launder(reinterpret_cast<char (*)[16]>(value)));


          It is the same case as the first example here.






          share|improve this answer












          You can do it like this, but only in the case if there is a char[16] at the address where value points:



          DoSomething(*std::launder(reinterpret_cast<char (*)[16]>(value)));


          It is the same case as the first example here.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 3 hours ago









          geza

          10.2k22465




          10.2k22465




















              up vote
              2
              down vote













              The use of std::launder as suggested by @user2079303 is a good option if you are sure that value does indeed point to an array of the right size as mentioned in their answer.



              Yet another approach: since SIZE is fairly small in this case, it may be safer/simpler to create a temporary copy of value and pass it to DoSomething(). But it all depends on what DoSomething() is actually doing (for example, does it modify the array passed to it). For example:



              #include <iostream>
              #include <vector>
              #include <string>

              constexpr int SIZE = 16 ;

              void DoSomething(char (&value)[SIZE])

              std::cout << "Do it!" << std::endl ;


              void BeforeDoingSomething(char* value, int len)

              if (len == SIZE)

              char tmp_array[SIZE] ;
              std::copy(value, value + len, tmp_array) ;
              DoSomething(tmp_array);
              else
              std::cout << "Length: " << len << std::endl ;



              int main()

              std::string foo (SIZE, '-') ;
              BeforeDoingSomething(foo.data(), foo.size()) ;

              std::vector<char> bar (SIZE) ;
              BeforeDoingSomething(bar.data(), bar.size()) ;

              std::string qux ;
              BeforeDoingSomething(qux.data(), qux.size()) ;

              return 0 ;



              Try it online here.






              share|improve this answer


























                up vote
                2
                down vote













                The use of std::launder as suggested by @user2079303 is a good option if you are sure that value does indeed point to an array of the right size as mentioned in their answer.



                Yet another approach: since SIZE is fairly small in this case, it may be safer/simpler to create a temporary copy of value and pass it to DoSomething(). But it all depends on what DoSomething() is actually doing (for example, does it modify the array passed to it). For example:



                #include <iostream>
                #include <vector>
                #include <string>

                constexpr int SIZE = 16 ;

                void DoSomething(char (&value)[SIZE])

                std::cout << "Do it!" << std::endl ;


                void BeforeDoingSomething(char* value, int len)

                if (len == SIZE)

                char tmp_array[SIZE] ;
                std::copy(value, value + len, tmp_array) ;
                DoSomething(tmp_array);
                else
                std::cout << "Length: " << len << std::endl ;



                int main()

                std::string foo (SIZE, '-') ;
                BeforeDoingSomething(foo.data(), foo.size()) ;

                std::vector<char> bar (SIZE) ;
                BeforeDoingSomething(bar.data(), bar.size()) ;

                std::string qux ;
                BeforeDoingSomething(qux.data(), qux.size()) ;

                return 0 ;



                Try it online here.






                share|improve this answer
























                  up vote
                  2
                  down vote










                  up vote
                  2
                  down vote









                  The use of std::launder as suggested by @user2079303 is a good option if you are sure that value does indeed point to an array of the right size as mentioned in their answer.



                  Yet another approach: since SIZE is fairly small in this case, it may be safer/simpler to create a temporary copy of value and pass it to DoSomething(). But it all depends on what DoSomething() is actually doing (for example, does it modify the array passed to it). For example:



                  #include <iostream>
                  #include <vector>
                  #include <string>

                  constexpr int SIZE = 16 ;

                  void DoSomething(char (&value)[SIZE])

                  std::cout << "Do it!" << std::endl ;


                  void BeforeDoingSomething(char* value, int len)

                  if (len == SIZE)

                  char tmp_array[SIZE] ;
                  std::copy(value, value + len, tmp_array) ;
                  DoSomething(tmp_array);
                  else
                  std::cout << "Length: " << len << std::endl ;



                  int main()

                  std::string foo (SIZE, '-') ;
                  BeforeDoingSomething(foo.data(), foo.size()) ;

                  std::vector<char> bar (SIZE) ;
                  BeforeDoingSomething(bar.data(), bar.size()) ;

                  std::string qux ;
                  BeforeDoingSomething(qux.data(), qux.size()) ;

                  return 0 ;



                  Try it online here.






                  share|improve this answer














                  The use of std::launder as suggested by @user2079303 is a good option if you are sure that value does indeed point to an array of the right size as mentioned in their answer.



                  Yet another approach: since SIZE is fairly small in this case, it may be safer/simpler to create a temporary copy of value and pass it to DoSomething(). But it all depends on what DoSomething() is actually doing (for example, does it modify the array passed to it). For example:



                  #include <iostream>
                  #include <vector>
                  #include <string>

                  constexpr int SIZE = 16 ;

                  void DoSomething(char (&value)[SIZE])

                  std::cout << "Do it!" << std::endl ;


                  void BeforeDoingSomething(char* value, int len)

                  if (len == SIZE)

                  char tmp_array[SIZE] ;
                  std::copy(value, value + len, tmp_array) ;
                  DoSomething(tmp_array);
                  else
                  std::cout << "Length: " << len << std::endl ;



                  int main()

                  std::string foo (SIZE, '-') ;
                  BeforeDoingSomething(foo.data(), foo.size()) ;

                  std::vector<char> bar (SIZE) ;
                  BeforeDoingSomething(bar.data(), bar.size()) ;

                  std::string qux ;
                  BeforeDoingSomething(qux.data(), qux.size()) ;

                  return 0 ;



                  Try it online here.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 3 hours ago

























                  answered 3 hours ago









                  crayzeewulf

                  4,03011927




                  4,03011927



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52560364%2fpassing-a-char-pointer-to-a-function-accepting-a-reference-to-a-char-array%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Comments

                      Popular posts from this blog

                      What does second last employer means? [closed]

                      Installing NextGIS Connect into QGIS 3?

                      One-line joke