5

I read through this(How to initialize a unsigned char array?), but it doesn't quite answer my question.

I know I can create an array of strings like this:

const char *str[] =
{
  "first",
  "second",
  "third",
  "fourth"
};

and if I want to write() these I can use: write(fd, str[3], sizeof(str[3]));

But what if I need an array of unsigned chars of variable length? I tried this:

const unsigned char *cmd[] =
{
  {0xfe, 0x58},
  {0xfe, 0x51},
  {0xfe, 0x7c, 0x01, 0x02, 0x00, 0x23},
  {0xfe, 0x3d, 0x02, 0x0f}
};

and I get gcc compile warnings such as * "braces around scalar initializer" * "initialization makes pointer from integer without cast"

5
  • 1
    You can't do that without introducing names for your sub-arrays. And BTW your code is bugged write(fd, str[3], strlen(str[3]));. strlen not sizeof. sizeof on a pointer gives you the size of the pointer, not the size of the data it is pointing to. Commented Mar 25, 2013 at 15:41
  • 1
    There is no such thing as an array of variable length. Your str is an array of pointers, not of variable-length arrays. It is OK to initialize a pointer with a string literal. There are no array literals and you cannot initialize pointers with braced lists. Commented Mar 25, 2013 at 15:49
  • OK, got it. I understand and agree on the comments here. Thanks!! Commented Mar 25, 2013 at 15:57
  • Terminology note: In C, "Variable Length Array" aka VLA has a very specific meaning: it is an array where the length is determined at runtime (ie. is a variable or a function argument). Standard C++ does not have VLAs. Also, the whole feature is a bit problematic, read up on it before using it in C (and in most cases, you should decide you don't actually want to use it, then). Commented Oct 7, 2014 at 11:10
  • I know this worked for me years (decades) ago in Borland Turbo C++ v3.0. See this answer, it looks like GCC isn't casting to char[] on its own without some help: stackoverflow.com/a/15619960/14055985 Commented Apr 4, 2021 at 20:56

3 Answers 3

6

This is one way

const unsigned char cmd1[] = {0xfe, 0x58};
const unsigned char cmd2[] = {0xfe, 0x51};
const unsigned char cmd3[] = {0xfe, 0x7c, 0x01, 0x02, 0x00, 0x23};
const unsigned char cmd4[] = {0xfe, 0x3d, 0x02, 0x0f};

const unsigned char *cmd[] =
{
  cmd1,
  cmd2,
  cmd3,
  cmd4
};
Sign up to request clarification or add additional context in comments.

2 Comments

Can you explain why the naming is needed for the subarray?
n.m. explains it in the comments above.
1

When multidimensional arrays are used, you must specify the size of the last dimension in order for the compiler to calculate the proper address arithmetic. Your cmd pointer array has two dimensions. The second dimension has a maximum length of 6 elements, so:

const unsigned char cmd[][6] =
{
      {0xfe, 0x58},
      {0xfe, 0x51},
      {0xfe, 0x7c, 0x01, 0x02, 0x00, 0x23},
      {0xfe, 0x3d, 0x02, 0x0f}
};

From the ANSI C standard: "If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. At the end of its initializer list, the array no longer has incomplete type."

ANSI C draft Standard C11

Comments

1

This worked for me (compiles with clang & gcc):

const unsigned char *cmd[] =
{
    (unsigned char[]){0xfe, 0x58},
    (unsigned char[]){0xfe, 0x51},
    (unsigned char[]){0xfe, 0x7c, 0x01, 0x02, 0x00, 0x23},
    (unsigned char[]){0xfe, 0x3d, 0x02, 0x0f}
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.