Passing a char pointer to a function accept a char reference of size?

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











up vote
6
down vote

favorite
1












I'm not quite sure if I titled the question correctly, but essentially, I have this scenario:



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 time "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
    1 hour 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
    1 hour 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
    1 hour ago














up vote
6
down vote

favorite
1












I'm not quite sure if I titled the question correctly, but essentially, I have this scenario:



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 time "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
    1 hour 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
    1 hour 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
    1 hour ago












up vote
6
down vote

favorite
1









up vote
6
down vote

favorite
1






1





I'm not quite sure if I titled the question correctly, but essentially, I have this scenario:



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 time "char *"




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










share|improve this question













I'm not quite sure if I titled the question correctly, but essentially, I have this scenario:



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 time "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










asked 1 hour ago









Zulukas

300312




300312











  • 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
    1 hour 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
    1 hour 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
    1 hour 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
    1 hour 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
    1 hour 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
    1 hour 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
1 hour 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
1 hour 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
1 hour 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
1 hour 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
1 hour 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
1 hour ago












3 Answers
3






active

oldest

votes

















up vote
4
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
    57 mins ago






  • 1




    @Quimby Exactly.
    – user2079303
    56 mins ago










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










  • @user2079303 Thank you.
    – Quimby
    51 mins 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
    49 mins 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
    1
    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-accept-a-char-reference-of-size%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
      4
      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
        57 mins ago






      • 1




        @Quimby Exactly.
        – user2079303
        56 mins ago










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










      • @user2079303 Thank you.
        – Quimby
        51 mins 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
        49 mins ago















      up vote
      4
      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
        57 mins ago






      • 1




        @Quimby Exactly.
        – user2079303
        56 mins ago










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










      • @user2079303 Thank you.
        – Quimby
        51 mins 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
        49 mins ago













      up vote
      4
      down vote



      accepted







      up vote
      4
      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 33 mins ago

























      answered 1 hour ago









      user2079303

      69.6k550109




      69.6k550109











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






      • 1




        @Quimby Exactly.
        – user2079303
        56 mins ago










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










      • @user2079303 Thank you.
        – Quimby
        51 mins 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
        49 mins ago

















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






      • 1




        @Quimby Exactly.
        – user2079303
        56 mins ago










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










      • @user2079303 Thank you.
        – Quimby
        51 mins 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
        49 mins ago
















      Is std::launder here because of the strict aliasing rule?
      – Quimby
      57 mins ago




      Is std::launder here because of the strict aliasing rule?
      – Quimby
      57 mins ago




      1




      1




      @Quimby Exactly.
      – user2079303
      56 mins ago




      @Quimby Exactly.
      – user2079303
      56 mins ago












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




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












      @user2079303 Thank you.
      – Quimby
      51 mins ago




      @user2079303 Thank you.
      – Quimby
      51 mins 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
      49 mins 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
      49 mins 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 1 hour ago









          geza

          10.1k22465




          10.1k22465




















              up vote
              1
              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
                1
                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
                  1
                  down vote










                  up vote
                  1
                  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 38 mins ago

























                  answered 47 mins ago









                  crayzeewulf

                  4,00211927




                  4,00211927



























                       

                      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-accept-a-char-reference-of-size%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