3

I can successfully do a C cast of an initializer list for an array of char strings, but can't seem to get it to work with a C++ cast (static_cast):

int main()
{
   char x[] = "test 123";

   // This works fine:

   char **foo = (char *[]) { "a", x, "abc" };
   std::cout << "[0]: " << foo[0] << "    [1]: " << foo[1]
             << "    [2]: " << foo[2] << std::endl;

   // This will not compile ("expected primary-expression before '{' token"):

   //char **bar = static_cast<char *[]>( { "a", x, "abc" } );
   //std::cout << "[0]: " << bar[0] << "    [1]: " << bar[1]
   //          << "    [2]: " << bar[2] << std::endl;
}

Is it possible to use a C++ cast here? If so, what's the correct syntax? If not, why not, and is the C cast letting me get away with something I shouldn't be doing?

Ultimately, the reason I'm asking this is that I am calling a function that has a char array pointer as a parameter, and I would like to use an anonymous array as the calling argument.

I'm using GCC 4.4.6.

user3065699
  • 329
  • 1
  • 8
  • It's from C99, *"A postfix expression that consists of a parenthesized type name followed by a braced enclosed list of initializers is a **compound literal**. "*, it's not a braced initializer like in C++ – Piotr Skotnicki Oct 24 '16 at 06:17
  • If you want to use a braced initializer syntax anyway, change the signature of that function to accept `std::array` – Piotr Skotnicki Oct 24 '16 at 08:29

1 Answers1

4

I can successfully do a C cast of an initializer list for an array of char strings

No, you can't. You didn't use an initializer list nor a C cast at all. What you used was a compound literal. It is a C language feature that doesn't exist in C++. Some compilers do support them in C++ as a language extension.

I highly recommend you to use a compiler option that at least warns when you use non-standard features to avoid confusion like this.

but can't seem to get it to work with a C++ cast

You cannot cast an initializer list expression. You will have to initialize a named array normally, then the pointer - although you hardly ever really need a separate pointer variable since the array implicitly decays to a pointer in most contexts anyway.

const char* arr[] = { "a", x, "abc" };
const char** foo = arr;

the reason I'm asking this is that I am calling a function that has a char array pointer as a parameter, and I would like to use an anonymous array as the calling argument.

If you can modify the function, then there are ways to allow the call without a named array. You could accept an std::initializer_list, or a type that can be constructed from an initializer list such as an instance of std::array.


PS. Implicit conversion from string literal to char* is not allowed in C++ either - but allowed by some compilers as a language extension. Use const char* here.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • I had run across this document https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html. I wasn't sure it applied, since in this case 'x' is not a literal (but maybe its value is copied as a literal into the compound literal?). Also, that document was a little unclear on whether this was actually a cast or not. It refers to the parenthesized expression as a cast, but also says the result is different from a cast. Your answer (and Piotr's) provides more clarity. The function I referred to is legacy, so I may not be able to change it. – user3065699 Oct 24 '16 at 18:05
  • @user3065699 For clarity: the components of a compound literal are not required to be literals. The document that you link shows an example with a non-literal value for a field as well. – eerorika Oct 24 '16 at 18:16