Why is a temporary char** argument illegal?

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











up vote
16
down vote

favorite
1












I have a function, f(char **p), and I wanted to call it in the simplest way I could.



I tried



char ** p = "a", "b";
f(p);


and got:




scalar object requires one element in initializer




so I changed it into



char * p[2] = "a", "b";
f(p);


and that went fine [would have been also fine with just char * p].



Why can't I create an array of pointers on the fly like the following?



f("a", "b");









share|improve this question



























    up vote
    16
    down vote

    favorite
    1












    I have a function, f(char **p), and I wanted to call it in the simplest way I could.



    I tried



    char ** p = "a", "b";
    f(p);


    and got:




    scalar object requires one element in initializer




    so I changed it into



    char * p[2] = "a", "b";
    f(p);


    and that went fine [would have been also fine with just char * p].



    Why can't I create an array of pointers on the fly like the following?



    f("a", "b");









    share|improve this question

























      up vote
      16
      down vote

      favorite
      1









      up vote
      16
      down vote

      favorite
      1






      1





      I have a function, f(char **p), and I wanted to call it in the simplest way I could.



      I tried



      char ** p = "a", "b";
      f(p);


      and got:




      scalar object requires one element in initializer




      so I changed it into



      char * p[2] = "a", "b";
      f(p);


      and that went fine [would have been also fine with just char * p].



      Why can't I create an array of pointers on the fly like the following?



      f("a", "b");









      share|improve this question















      I have a function, f(char **p), and I wanted to call it in the simplest way I could.



      I tried



      char ** p = "a", "b";
      f(p);


      and got:




      scalar object requires one element in initializer




      so I changed it into



      char * p[2] = "a", "b";
      f(p);


      and that went fine [would have been also fine with just char * p].



      Why can't I create an array of pointers on the fly like the following?



      f("a", "b");






      c






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 17 mins ago









      Peter Mortensen

      13.2k1983111




      13.2k1983111










      asked 5 hours ago









      CIsForCookies

      6,55111443




      6,55111443






















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          24
          down vote



          accepted










          This gives a warning:



          char ** p = "a", "b";


          because p is not an array.



          This is also not legal:



          f("a", "b");


          since curly braces by themselves are not allowed in an expression (but can be used as an initializer).



          It is possible to create an array on the fly like that using a compound literal:



          f((char *)"a", "b");


          You could also use a compound literal to initialize a temporary:



          char ** p = (char *)"a", "b";


          Unlike the first statement, this is valid because the literal is an array of type char *[2] and will decay to a char ** which can be used to initialize a variable of this type.



          See section 6.5.2.5 of the C standard for more details on compound literals.






          share|improve this answer





























            up vote
            11
            down vote













            This declaration char ** p = "a", "b"; triggers a warning because C does not know how to interpret the content of braces:



            • Declaration type char** suggests it's a single pointer-to-pointer-to-char

            • Content of specifies two items.

            You need to tell C that you are initializing a pointer to pointer with a pointer to the initial element of an anonymous array by specifying a type in front of the braces:



            char ** p = (char*)"a", "b"


            This construct is called a "compound literal". It could be used in a declaration, but it also works as an expression.



            Note: if you are planning to pass an array like that to a function, you need to provide a way to determine the size of the array. One approach is to pass NULL to "terminate" the array, like this:



            void f(char **p) 
            int i = 0;
            while (*p)
            printf("%d:%sn", i++, *p++);


            int main(void)
            f((char*)"a", "b", NULL);
            return 0;



            Demo.






            share|improve this answer



























              up vote
              3
              down vote













              C99 and later added compound literals for the exact purpose: creating array and structs on the fly

              Example:



              struct foo int a; char b[2]; structure;
              structure = ((struct foo) 1, 'a', 0);
              int *y = (int ) 1, 2, 3;
              int *z = (int ) 1;


              Apart from std C99 and later, GCC provide this feature as an extension too.

              In you case this will work



              f((char *)"a","b");


              (char *)"a","b" is a compound literal which creates an array of 2 pointers to char on the fly.






              share|improve this answer






















              • GCC provide this feature as an extension too - This (f((char *)"a","b");) would not have worked on Clang?
                – CIsForCookies
                5 hours ago






              • 1




                @CIsForCookies; Clang also provide the same as an extension. In clang int y = (int ) 1, 2, 3; will work too while GCC will throw an error.
                – haccks
                5 hours ago











              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: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              ,
              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%2f53083520%2fwhy-is-a-temporary-char-argument-illegal%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
              24
              down vote



              accepted










              This gives a warning:



              char ** p = "a", "b";


              because p is not an array.



              This is also not legal:



              f("a", "b");


              since curly braces by themselves are not allowed in an expression (but can be used as an initializer).



              It is possible to create an array on the fly like that using a compound literal:



              f((char *)"a", "b");


              You could also use a compound literal to initialize a temporary:



              char ** p = (char *)"a", "b";


              Unlike the first statement, this is valid because the literal is an array of type char *[2] and will decay to a char ** which can be used to initialize a variable of this type.



              See section 6.5.2.5 of the C standard for more details on compound literals.






              share|improve this answer


























                up vote
                24
                down vote



                accepted










                This gives a warning:



                char ** p = "a", "b";


                because p is not an array.



                This is also not legal:



                f("a", "b");


                since curly braces by themselves are not allowed in an expression (but can be used as an initializer).



                It is possible to create an array on the fly like that using a compound literal:



                f((char *)"a", "b");


                You could also use a compound literal to initialize a temporary:



                char ** p = (char *)"a", "b";


                Unlike the first statement, this is valid because the literal is an array of type char *[2] and will decay to a char ** which can be used to initialize a variable of this type.



                See section 6.5.2.5 of the C standard for more details on compound literals.






                share|improve this answer
























                  up vote
                  24
                  down vote



                  accepted







                  up vote
                  24
                  down vote



                  accepted






                  This gives a warning:



                  char ** p = "a", "b";


                  because p is not an array.



                  This is also not legal:



                  f("a", "b");


                  since curly braces by themselves are not allowed in an expression (but can be used as an initializer).



                  It is possible to create an array on the fly like that using a compound literal:



                  f((char *)"a", "b");


                  You could also use a compound literal to initialize a temporary:



                  char ** p = (char *)"a", "b";


                  Unlike the first statement, this is valid because the literal is an array of type char *[2] and will decay to a char ** which can be used to initialize a variable of this type.



                  See section 6.5.2.5 of the C standard for more details on compound literals.






                  share|improve this answer














                  This gives a warning:



                  char ** p = "a", "b";


                  because p is not an array.



                  This is also not legal:



                  f("a", "b");


                  since curly braces by themselves are not allowed in an expression (but can be used as an initializer).



                  It is possible to create an array on the fly like that using a compound literal:



                  f((char *)"a", "b");


                  You could also use a compound literal to initialize a temporary:



                  char ** p = (char *)"a", "b";


                  Unlike the first statement, this is valid because the literal is an array of type char *[2] and will decay to a char ** which can be used to initialize a variable of this type.



                  See section 6.5.2.5 of the C standard for more details on compound literals.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 5 hours ago

























                  answered 5 hours ago









                  dbush

                  86.7k1092125




                  86.7k1092125






















                      up vote
                      11
                      down vote













                      This declaration char ** p = "a", "b"; triggers a warning because C does not know how to interpret the content of braces:



                      • Declaration type char** suggests it's a single pointer-to-pointer-to-char

                      • Content of specifies two items.

                      You need to tell C that you are initializing a pointer to pointer with a pointer to the initial element of an anonymous array by specifying a type in front of the braces:



                      char ** p = (char*)"a", "b"


                      This construct is called a "compound literal". It could be used in a declaration, but it also works as an expression.



                      Note: if you are planning to pass an array like that to a function, you need to provide a way to determine the size of the array. One approach is to pass NULL to "terminate" the array, like this:



                      void f(char **p) 
                      int i = 0;
                      while (*p)
                      printf("%d:%sn", i++, *p++);


                      int main(void)
                      f((char*)"a", "b", NULL);
                      return 0;



                      Demo.






                      share|improve this answer
























                        up vote
                        11
                        down vote













                        This declaration char ** p = "a", "b"; triggers a warning because C does not know how to interpret the content of braces:



                        • Declaration type char** suggests it's a single pointer-to-pointer-to-char

                        • Content of specifies two items.

                        You need to tell C that you are initializing a pointer to pointer with a pointer to the initial element of an anonymous array by specifying a type in front of the braces:



                        char ** p = (char*)"a", "b"


                        This construct is called a "compound literal". It could be used in a declaration, but it also works as an expression.



                        Note: if you are planning to pass an array like that to a function, you need to provide a way to determine the size of the array. One approach is to pass NULL to "terminate" the array, like this:



                        void f(char **p) 
                        int i = 0;
                        while (*p)
                        printf("%d:%sn", i++, *p++);


                        int main(void)
                        f((char*)"a", "b", NULL);
                        return 0;



                        Demo.






                        share|improve this answer






















                          up vote
                          11
                          down vote










                          up vote
                          11
                          down vote









                          This declaration char ** p = "a", "b"; triggers a warning because C does not know how to interpret the content of braces:



                          • Declaration type char** suggests it's a single pointer-to-pointer-to-char

                          • Content of specifies two items.

                          You need to tell C that you are initializing a pointer to pointer with a pointer to the initial element of an anonymous array by specifying a type in front of the braces:



                          char ** p = (char*)"a", "b"


                          This construct is called a "compound literal". It could be used in a declaration, but it also works as an expression.



                          Note: if you are planning to pass an array like that to a function, you need to provide a way to determine the size of the array. One approach is to pass NULL to "terminate" the array, like this:



                          void f(char **p) 
                          int i = 0;
                          while (*p)
                          printf("%d:%sn", i++, *p++);


                          int main(void)
                          f((char*)"a", "b", NULL);
                          return 0;



                          Demo.






                          share|improve this answer












                          This declaration char ** p = "a", "b"; triggers a warning because C does not know how to interpret the content of braces:



                          • Declaration type char** suggests it's a single pointer-to-pointer-to-char

                          • Content of specifies two items.

                          You need to tell C that you are initializing a pointer to pointer with a pointer to the initial element of an anonymous array by specifying a type in front of the braces:



                          char ** p = (char*)"a", "b"


                          This construct is called a "compound literal". It could be used in a declaration, but it also works as an expression.



                          Note: if you are planning to pass an array like that to a function, you need to provide a way to determine the size of the array. One approach is to pass NULL to "terminate" the array, like this:



                          void f(char **p) 
                          int i = 0;
                          while (*p)
                          printf("%d:%sn", i++, *p++);


                          int main(void)
                          f((char*)"a", "b", NULL);
                          return 0;



                          Demo.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered 5 hours ago









                          dasblinkenlight

                          603k547591176




                          603k547591176




















                              up vote
                              3
                              down vote













                              C99 and later added compound literals for the exact purpose: creating array and structs on the fly

                              Example:



                              struct foo int a; char b[2]; structure;
                              structure = ((struct foo) 1, 'a', 0);
                              int *y = (int ) 1, 2, 3;
                              int *z = (int ) 1;


                              Apart from std C99 and later, GCC provide this feature as an extension too.

                              In you case this will work



                              f((char *)"a","b");


                              (char *)"a","b" is a compound literal which creates an array of 2 pointers to char on the fly.






                              share|improve this answer






















                              • GCC provide this feature as an extension too - This (f((char *)"a","b");) would not have worked on Clang?
                                – CIsForCookies
                                5 hours ago






                              • 1




                                @CIsForCookies; Clang also provide the same as an extension. In clang int y = (int ) 1, 2, 3; will work too while GCC will throw an error.
                                – haccks
                                5 hours ago















                              up vote
                              3
                              down vote













                              C99 and later added compound literals for the exact purpose: creating array and structs on the fly

                              Example:



                              struct foo int a; char b[2]; structure;
                              structure = ((struct foo) 1, 'a', 0);
                              int *y = (int ) 1, 2, 3;
                              int *z = (int ) 1;


                              Apart from std C99 and later, GCC provide this feature as an extension too.

                              In you case this will work



                              f((char *)"a","b");


                              (char *)"a","b" is a compound literal which creates an array of 2 pointers to char on the fly.






                              share|improve this answer






















                              • GCC provide this feature as an extension too - This (f((char *)"a","b");) would not have worked on Clang?
                                – CIsForCookies
                                5 hours ago






                              • 1




                                @CIsForCookies; Clang also provide the same as an extension. In clang int y = (int ) 1, 2, 3; will work too while GCC will throw an error.
                                – haccks
                                5 hours ago













                              up vote
                              3
                              down vote










                              up vote
                              3
                              down vote









                              C99 and later added compound literals for the exact purpose: creating array and structs on the fly

                              Example:



                              struct foo int a; char b[2]; structure;
                              structure = ((struct foo) 1, 'a', 0);
                              int *y = (int ) 1, 2, 3;
                              int *z = (int ) 1;


                              Apart from std C99 and later, GCC provide this feature as an extension too.

                              In you case this will work



                              f((char *)"a","b");


                              (char *)"a","b" is a compound literal which creates an array of 2 pointers to char on the fly.






                              share|improve this answer














                              C99 and later added compound literals for the exact purpose: creating array and structs on the fly

                              Example:



                              struct foo int a; char b[2]; structure;
                              structure = ((struct foo) 1, 'a', 0);
                              int *y = (int ) 1, 2, 3;
                              int *z = (int ) 1;


                              Apart from std C99 and later, GCC provide this feature as an extension too.

                              In you case this will work



                              f((char *)"a","b");


                              (char *)"a","b" is a compound literal which creates an array of 2 pointers to char on the fly.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited 5 hours ago

























                              answered 5 hours ago









                              haccks

                              84.8k20125216




                              84.8k20125216











                              • GCC provide this feature as an extension too - This (f((char *)"a","b");) would not have worked on Clang?
                                – CIsForCookies
                                5 hours ago






                              • 1




                                @CIsForCookies; Clang also provide the same as an extension. In clang int y = (int ) 1, 2, 3; will work too while GCC will throw an error.
                                – haccks
                                5 hours ago

















                              • GCC provide this feature as an extension too - This (f((char *)"a","b");) would not have worked on Clang?
                                – CIsForCookies
                                5 hours ago






                              • 1




                                @CIsForCookies; Clang also provide the same as an extension. In clang int y = (int ) 1, 2, 3; will work too while GCC will throw an error.
                                – haccks
                                5 hours ago
















                              GCC provide this feature as an extension too - This (f((char *)"a","b");) would not have worked on Clang?
                              – CIsForCookies
                              5 hours ago




                              GCC provide this feature as an extension too - This (f((char *)"a","b");) would not have worked on Clang?
                              – CIsForCookies
                              5 hours ago




                              1




                              1




                              @CIsForCookies; Clang also provide the same as an extension. In clang int y = (int ) 1, 2, 3; will work too while GCC will throw an error.
                              – haccks
                              5 hours ago





                              @CIsForCookies; Clang also provide the same as an extension. In clang int y = (int ) 1, 2, 3; will work too while GCC will throw an error.
                              – haccks
                              5 hours ago


















                               

                              draft saved


                              draft discarded















































                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53083520%2fwhy-is-a-temporary-char-argument-illegal%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Comments

                              Popular posts from this blog

                              Long meetings (6-7 hours a day): Being “babysat” by supervisor

                              Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

                              Confectionery