Skip to main content
deleted 2 characters in body
Source Link
chux
  • 33.7k
  • 2
  • 38
  • 92

variable length arrays are required in C99 and optional in C11, C17/18.

To detect, something like

#if defined(__STDC__) && defined(__STDC_VERSION__) && \
    (__STDC_VERSION__ == 199901 || (__STDC_VERSION__ >= 201112 && __STDC_NO_VLA__ != 1))
    #define VLA_OK 1
#else
    #define VLA_OK 0
#ednif#endif

If code does not use a variable length arrays, code could take advantage that the address of the first element of the 2D array is equivalent to &arr[0][0] and that 2D arrays are continuous.

void fill(void *arr, size_t rows, size_t cols, int val) {
   int *a = arr;
   for(size_t i = 0; i < rows; i++) {
     for(size_t j = 0; j < cols; j++) {
       *a++ = val;
    }
  }
}

Sample usage

#define IN 5
#define JN 3
int arr[IN][JN];
fill(arr, IN, JN, 0x45);

This does lose type checking.
Code instead could oblige passing the address of the first int

//        v---v---- type checked
void fill(int *arr, size_t rows, size_t cols, int val) {
   for(size_t i = 0; i < rows; i++) {
     for(size_t j = 0; j < cols; j++) {
       *arr++ = val;
    }
  }
}

Sample usage

#define IN 5
#define JN 3
int arr[IN][JN];
fill(&arr[0][0], IN, JN, 0x45);
// or
fill(arr[0], IN, JN, 0x45);

variable length arrays are required in C99 and optional in C11, C17/18.

To detect, something like

#if defined(__STDC__) && defined(__STDC_VERSION__) && \
    (__STDC_VERSION__ == 199901 || (__STDC_VERSION__ >= 201112 && __STDC_NO_VLA__ != 1))
    #define VLA_OK 1
#else
    #define VLA_OK 0
#ednif

If code does not use a variable length arrays, code could take advantage that the address of the first element of the 2D array is equivalent to &arr[0][0] and that 2D arrays are continuous.

void fill(void *arr, size_t rows, size_t cols, int val) {
   int *a = arr;
   for(size_t i = 0; i < rows; i++) {
     for(size_t j = 0; j < cols; j++) {
       *a++ = val;
    }
  }
}

Sample usage

#define IN 5
#define JN 3
int arr[IN][JN];
fill(arr, IN, JN, 0x45);

This does lose type checking.
Code instead could oblige passing the address of the first int

//        v---v---- type checked
void fill(int *arr, size_t rows, size_t cols, int val) {
   for(size_t i = 0; i < rows; i++) {
     for(size_t j = 0; j < cols; j++) {
       *arr++ = val;
    }
  }
}

Sample usage

#define IN 5
#define JN 3
int arr[IN][JN];
fill(&arr[0][0], IN, JN, 0x45);
// or
fill(arr[0], IN, JN, 0x45);

variable length arrays are required in C99 and optional in C11, C17/18.

To detect, something like

#if defined(__STDC__) && defined(__STDC_VERSION__) && \
    (__STDC_VERSION__ == 199901 || (__STDC_VERSION__ >= 201112 && __STDC_NO_VLA__ != 1))
    #define VLA_OK 1
#else
    #define VLA_OK 0
#endif

If code does not use variable length arrays, code could take advantage that the address of the first element of the 2D array is equivalent to &arr[0][0] and that 2D arrays are continuous.

void fill(void *arr, size_t rows, size_t cols, int val) {
   int *a = arr;
   for(size_t i = 0; i < rows; i++) {
     for(size_t j = 0; j < cols; j++) {
       *a++ = val;
    }
  }
}

Sample usage

#define IN 5
#define JN 3
int arr[IN][JN];
fill(arr, IN, JN, 0x45);

This does lose type checking.
Code instead could oblige passing the address of the first int

//        v---v---- type checked
void fill(int *arr, size_t rows, size_t cols, int val) {
   for(size_t i = 0; i < rows; i++) {
     for(size_t j = 0; j < cols; j++) {
       *arr++ = val;
    }
  }
}

Sample usage

#define IN 5
#define JN 3
int arr[IN][JN];
fill(&arr[0][0], IN, JN, 0x45);
// or
fill(arr[0], IN, JN, 0x45);
Source Link
chux
  • 33.7k
  • 2
  • 38
  • 92

variable length arrays are required in C99 and optional in C11, C17/18.

To detect, something like

#if defined(__STDC__) && defined(__STDC_VERSION__) && \
    (__STDC_VERSION__ == 199901 || (__STDC_VERSION__ >= 201112 && __STDC_NO_VLA__ != 1))
    #define VLA_OK 1
#else
    #define VLA_OK 0
#ednif

If code does not use a variable length arrays, code could take advantage that the address of the first element of the 2D array is equivalent to &arr[0][0] and that 2D arrays are continuous.

void fill(void *arr, size_t rows, size_t cols, int val) {
   int *a = arr;
   for(size_t i = 0; i < rows; i++) {
     for(size_t j = 0; j < cols; j++) {
       *a++ = val;
    }
  }
}

Sample usage

#define IN 5
#define JN 3
int arr[IN][JN];
fill(arr, IN, JN, 0x45);

This does lose type checking.
Code instead could oblige passing the address of the first int

//        v---v---- type checked
void fill(int *arr, size_t rows, size_t cols, int val) {
   for(size_t i = 0; i < rows; i++) {
     for(size_t j = 0; j < cols; j++) {
       *arr++ = val;
    }
  }
}

Sample usage

#define IN 5
#define JN 3
int arr[IN][JN];
fill(&arr[0][0], IN, JN, 0x45);
// or
fill(arr[0], IN, JN, 0x45);