multi-dimensioned array initialization using const - c

This kind of initialization works
int arr[3][4] = { {1,2,3,4}, {1,2,3,4}, {1,2,3,4} } ;
but this one here doesn't
const size_t row_size = 3;
const size_t col_size = 4;
int arr[row_size][col_size] = { {1,2,3,4},{1,2,3,4},{1,2,3,4}};
these codes are in c but after changing the file extension to c++ and re-compiling
it works fine. why such a behavior?

That used to be a problem with C and macros were used to solve such problems. But in C++ if you use "const" keyword then the compiler should automatically replace those values during compile time so there shouldn't be any problem with g++. That code runs perfectly fine when compiled with g++. Maybe you are trying to compile it with gcc (I got the same error with gcc which is as expected).

Actually, having a const-variable doesn't mean it is constant at compile time. For example, I can
void f(int x) {
const int y = x;
int m[y]; // should that work?
}
It won't work in good old C++03, as compiler cannot determine y at compile time. Though it would be possible in C++ soon with the feature called Variable Length Arrays, it seems all you want is plain compile-time constant. Just say it's also static:
static const int size_t row_size = 3;
Since now, you can use it in compile-time.

Related

"Variable may not be initialized" when specifying the array size with another variable

I am trying to compile the following code:
int rows = 4;
int columns = 4;
int numblock[columns][rows] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
And it tells me that the variable may not be initialized. When I write int numblock[4][4] instead, the compiler doesn't complain.
I guess it is related to this: C compile error: "Variable-sized object may not be initialized"
Can someone please explain this to me?
Edit - from a comment by op:
.. I set columns and rows = 4. It should know the size, shouldn't it?
The answer is already in the link you provide but I'll try to clarify as the linked answer wasn't clear to you.
First - what you have is called VLA, i.e. a Variable Length Array. The idea is simply that you can use another variable to set the size of the array. So this allows the size to be set at run time.
The problem you have is because: It is not allowed to initialize a VLA
It is as simple as that - it is just not supported in C.
It works fine with the initializer when the array is defined with numbers (e.g. [4][4]). That is because the size of the array is known at compile time
The fact you you initialize rows and columns to 4 makes no difference. The compiler do not track whether these variables are changed before the array is created. For instance like this:
void foo()
{
int rows = 4;
int columns = 4;
rows = rows + 42; // or scanf("%d", &rows) to get the number of rows from a user
int numblock[columns][rows]; // no - initializer here - not allowed
}
Even if you make rows and columns constants - like const int rows = 4; - it still won't work in C (but in C++ it will).
One way to "initialize" a VLA is to use memset - like:
void foo()
{
int rows = 4;
int columns = 4;
int numblock[columns][rows]; // no - initializer here - not allowed
memset(numblock, 0, sizeof numblock); // but using memset is easy
}
If you want a fixed number of rows/columns the C way is to use defines. Like:
#define ROWS 4
#define COLUMNS 4
void foo()
{
int numblock[ROWS][COLUMNS] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
}
This will work because defines are resolved at compile time
I found that if I initialize n at 0 in the variable declarations, but do not initialize the array until inside of the body of the program (int main ()), that the compiler does not complain and the program functions as expected. This may not be the preferred way, and I think perhaps the use of #define may be a more elegant way.

std::array equivalent in C

I'm new to C and C++, and I've read that at least in C++ it's preferable to use std::array or std::vector when using vectors and arrays, specially when passing these into a function.
In my research I found the following, which makes sense. I suppose using std::vector would fix the problem of indexing outside of the variable's scope.
void foo(int arr[10]) { arr[9] = 0; }
void bar() {
int data[] = {1, 2};
foo(data);
}
The above code is wrong but the compiler thinks everything is fine and
issues no warning about the buffer overrun.
Instead use std::array or std::vector, which have consistent value
semantics and lack any 'special' behavior that produces errors like
the above.
(answer from bames53, thanks btw!)
What I want to code is
float foo(int X, int Y, int l){
// X and Y are arrays of length l
float z[l];
for (int i = 0; i < l; i ++){
z[i] = X[i]+Y[i];
}
return z;
}
int bar(){
int l = 100;
int X[l];
int Y[l];
float z[l];
z = foo(X,Y,l);
return 0;
}
I want this to be coded in C, so my question is is there a std::vector construct for C? I couldn't find anything on that.
Thanks in advance, also please excuse my coding (I'm green as grass in C and C++)
Standard C has nothing like std::vector or other container structures. All you get is built-in arrays and malloc.
I suppose using std::vector would fix the problem of indexing outside of the variable's scope.
You might think so, but you'd be wrong: Indexing outside of the bounds of a std::vector is just as bad as with a built-in array. The operator[] of std::vector doesn't do any bounds checking either (or at least it is not guaranteed to). If you want your index operations checked, you need to use arr.at(i) instead of arr[i].
Also note that code like
float z[l];
...
return z;
is wrong because there are no array values in C (or C++, for that matter). When you try to get the value of an array, you actually get a pointer to its first element. But that first element (and all other elements, and the whole array) is destroyed when the function returns, so this is a classic use-after-free bug: The caller gets a dangling pointer to an object that doesn't exist anymore.
The customary C solution is to have the caller deal with memory allocation and pass an output parameter that the function just writes to:
void foo(float *z, const int *X, const int *Y, int l){
// X and Y are arrays of length l
for (int i = 0; i < l; i ++){
z[i] = X[i]+Y[i];
}
}
That said, there are some libraries that provide dynamic data structures for C, but they necessarily look and feel very different from C++ and std::vector (e.g. I know about GLib).
Your question might be sensitive for some programmers of the language.
Using constructs of one language into another can be considered cursing as different languages have different design decisions.
C++ and C share a huge part, in a way that C code can (without a lot of modifications) be compiled as C++. However, if you learn to master C++, you will realize that a lot of strange things happen because how C works.
Back to the point: C++ contains a standard library with containers as std::vector. These containers make use of several C++ constructions that ain't available in C:
RAII (the fact that a Destructor gets executed when the instance goes out-of-scope) will prevent a memory leak of the allocated memory
Templates will allow type safety to not mix doubles, floats, classes ...
Operator overloading will allow different signatures for the same function (like erase)
Member functions
None of these exist in C, so in order to have a similar structure, several adaptions are required for getting a data structure that behaves almost the same.
In my experience, most C projects have their own generic version of data structures, often based on void*. Often this will look similar like:
struct Vector
{
void *data;
long size;
long capacity;
};
Vector *CreateVector()
{
Vector *v = (Vector *)(malloc(sizeof(Vector)));
memset(v, 0, sizeof(Vector));
return v;
}
void DestroyVector(Vector *v)
{
if (v->data)
{
for (long i = 0; i < v->size; ++i)
free(data[i]);
free(v->data);
}
free(v);
}
// ...
Alternatively, you could mix C and C++.
struct Vector
{
void *cppVector;
};
#ifdef __cplusplus
extern "C" {
#endif
Vector CreateVector()
void DestroyVector(Vector v)
#ifdef __cplusplus
}
#endif
vectorimplementation.cpp
#include "vector.h"
struct CDataFree
{
void operator(void *ptr) { if (ptr) free(ptr); }
};
using CData = std::unique_ptr<void*, CDataFree>;
Vector CreateVector()
{
Vector v;
v.cppVector = static_cast<void*>(std::make_unique<std::vector<CData>>().release());
return v;
}
void DestroyVector(Vector v)
{
auto cppV = static_cast<std::vector<CData>>(v.cppVector);
auto freeAsUniquePtr = std::unique_ptr<std::vector<CData>>(cppV);
}
// ...
The closest equivalent of std::array in c is probably a preprocessor macro defintion like
#define ARRAY(type,name,length) \
type name[(length)]

Loop unrolling in inlined functions in C

I have a question about C compiler optimization and when/how loops in inline functions are unrolled.
I am developing a numerical code which does something like the example below. Basically, my_for() would compute some kind of stencil and call op() to do something with the data in my_type *arg for each i. Here, my_func() wraps my_for(), creating the argument and sending the function pointer to my_op()... who’s job it is to modify the ith double for each of the (arg->n) double arrays arg->dest[j].
typedef struct my_type {
int const n;
double *dest[16];
double const *src[16];
} my_type;
static inline void my_for( void (*op)(my_type *,int), my_type *arg, int N ) {
int i;
for( i=0; i<N; ++i )
op( arg, i );
}
static inline void my_op( my_type *arg, int i ) {
int j;
int const n = arg->n;
for( j=0; j<n; ++j )
arg->dest[j][i] += arg->src[j][i];
}
void my_func( double *dest0, double *dest1, double const *src0, double const *src1, int N ) {
my_type Arg = {
.n = 2,
.dest = { dest0, dest1 },
.src = { src0, src1 }
};
my_for( &my_op, &Arg, N );
}
This works fine. The functions are inlining as they should and the code is (almost) as efficient as having written everything inline in a single function and unrolled the j loop, without any sort of my_type Arg.
Here’s the confusion: if I set int const n = 2; rather than int const n = arg->n; in my_op(), then the code becomes as fast as the unrolled single-function version. So, the question is: why? If everything is being inlined into my_func(), why doesn’t the compiler see that I am literally defining Arg.n = 2? Furthermore, there is no improvement when I explicitly make the bound on the j loop arg->n, which should look just like the speedier int const n = 2; after inlining. I also tried using my_type const everywhere to really signal this const-ness to the compiler, but it just doesn't want to unroll the loop.
In my numerical code, this amounts to about a 15% performance hit. If it matters, there, n=4 and these j loops appear in a couple of conditional branches in an op().
I am compiling with icc (ICC) 12.1.5 20120612. I tried #pragma unroll. Here are my compiler options (did I miss any good ones?):
-O3 -ipo -static -unroll-aggressive -fp-model precise -fp-model source -openmp -std=gnu99 -Wall -Wextra -Wno-unused -Winline -pedantic
Thanks!
Well, obviously the compiler isn't 'smart' enough to propagate the n constant and unroll the for loop. Actually it plays it safe since arg->n can change between instantiation and usage.
In order to have consistent performance across compiler generations and squeeze the maximum out of your code, do the unrolling by hand.
What people like myself do in these situations (performance is king) is rely on macros.
Macros will 'inline' in debug builds (useful) and can be templated (to a point) using macro parameters. Macro parameters which are compile time constants are guaranteed to remain this way.
It's faster, because your program does not assign memory to the variable.
If you don't have to perform any operations on unknown values they are treated as if they were #define constant 2 with type checking. They are just added while the compilation.
Could you please chose one of the two tags (I mean C or C++), it's confusing, because the languages treat const values differently - C treats them like normal variables which value just can't be changed, and in C++ they do or don't have memory assigned depending on the context (if you need their address or if you need to compute them when the program is running, then memory is assigned).
Source: "Thinking in C++". No exact quote.

variably modified array at file scope in C

I have some code like this:
static int a = 6;
static int b = 3;
static int Hello[a][b] =
{
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3}
};
but when I compile it, it says error:
variably modified 'Hello' at file scope
how could this happen? and how could I fix it?
You can not have static array which size is given as a variable
That's why constants should be #defined:
#define a 6
This way preprocessor will replace a with 6, making it valid declaration.
Simple answer variable modified array at file scope is not possible.
Detailed :
make it compile time integral constant expression, since array length must be specified at the compile time.
like this :
#define a 6
#define b 3
Or, follow c99 standard. and compile like for gcc.
gcc -Wall -std=c99 test.c -o test.out
The problem here is variable length array with providing length may not be initialized so you are getting this error.
simply
static int a =6;
static int b =3;
void any_func()
{
int Hello [a][b]; // no need of initialization no static array means no file scope.
}
Now use for loop or any loop to fill the array.
For more info just a DEMO :
#include <stdio.h>
static int a = 6;
int main()
{
int Hello[a]={1,2,3,4,5,6}; // see here initialization of array Hello it's in function
//scope but still error
return 0;
}
root#Omkant:~/c# clang -std=c99 vararr.c -o vararr
vararr.c:8:11: error: variable-sized object may not be initialized
int Hello[a]={1,2,3,4,5,6};
^
1 error generated.
If you remove static and provide initialization then it will generate error as above.
But if you keep static as well as initialization the still will be error.
But if you remove initialization and keep static the below error will come.
error: variable length array declaration not allowed at file scope
static int Hello[a];
^ ~
1 error generated.
So variable length array declaration not allowed at file scope so make it function or block scope inside any function (but remember making it function scope must remove initialization)
NOTE : Since it's C tagged so making a and b as const won't help you but in C++ const will work fine.
When using CLANG/LLVM the following works:
static const int a = 6;
static const int b = 3;
static int Hello[a][b] =
{
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3},
{ 1,2,3}
};
(To see it in the generated assembly, one needs to use Hello so it will not be optimized out)
However, this will generate an error if C99 mode is selected (-std=c99),
it will only generate a warning (Wgnu-folding-constant) if -pedantic is selected.
GCC does not seem to allow this (const is interpreted as read-only)
See explanation in this thread:
"Initializer element is not constant" error for no reason in Linux GCC, compiling C
Yea, this is annnoying:
const int len = 10;
int stuff[len];
Gives the error. I try to get away from doing #define x, because const int is a better way of declaring a constant, but then you have these cases where const int is not a true constant, even though the compiler knows full well it is.

Dynamically creating functions in C

How can I dynamically create a function in C?
I try to summarize my C problem as follows:
I have a matrix and I want to be able to use some function to generate its elements.
function has no arguments
Hence I define the following:
typedef double(function)(unsigned int,unsigned int);
/* writes f(x,y) to each element x,y of the matrix*/
void apply(double ** matrix, function * f);
Now I need to generate constant functions within the code. I thought about creating a nested function and returning its pointer, but GCC manual (which allows nested functions) says:
"If you try to call the nested function through its address after the
containing function has exited, all hell will break loose."
which I would kind of expect from this code...
function * createConstantFunction(const double value){
double function(unsigned int,unsigned int){
return value;
}
return &function;
}
So how can I get it to work?
Thanks!
C is a compiled language. You can't create code at run-time "in C"; there is no specific C support to emit instructions to memory and so on. You can of course try just allocating memory, making sure it's executable, and emit raw machine code there. Then call it from C using a suitable function pointer.
You won't get any help from the language itself though, this is just like generating code and calling it in BASIC on an old 8-bit machine.
You must be familiar with some programming language which supports closure mechanism ,don't you?
Unfortunately, C does not support closure like that itself.
You could find out some useful libraries which simulate closure in C if you insisted on closure. But most of those libraries are complex and machine-dependence.
Alternatively, you can change your mind to agree with the C-style closure if you could change the signature of double ()(unsigned,unsigned);.
In C, functions itself has no data (or context) except the parameters of it and the static variable which it could access.
So the context must be passed by yourself. Here is a example using extra parameter :
// first, add one extra parameter in the signature of function.
typedef double(function)(double extra, unsigned int,unsigned int);
// second, add one extra parameter in the signature of apply
void apply(double* matrix,unsigned width,unsigned height, function* f, double extra)
{
for (unsigned y=0; y< height; ++y)
for (unsigned x=0; x< width ++x)
matrix[ y*width + x ] = f(x, y, extra);
// apply will passing extra to f
}
// third, in constant_function, we could get the context: double extra, and return it
double constant_function(double value, unsigned x,unsigned y) { return value; }
void test(void)
{
double* matrix = get_a_matrix();
// fourth, passing the extra parameter to apply
apply(matrix, w, h, &constant_function, 1212.0);
// the matrix will be filled with 1212.0
}
Is a double extra enough? Yes, but only in this case.
How should we do if more context is required?
In C, the general purpose parameter is void*, we can pass any context though one void* parameter by passing the address of context.
Here is another example :
typedef double (function)(void* context, int, int );
void apply(double* matrix, int width,int height,function* f,void* context)
{
for (int y=0; y< height; ++y)
for (int x=0; x< width ++x)
matrix[ y*width + x ] = f(x, y, context); // passing the context
}
double constant_function(void* context,int x,int y)
{
// this function use an extra double parameter \
// and context points to its address
double* d = context;
return *d;
}
void test(void)
{
double* matrix = get_a_matrix();
double context = 326.0;
// fill matrix with 326.0
apply( matrix, w, h, &constant_function, &context);
}
(function,context) pair like &constant_function,&context is the C-style closure.
Each function(F) that needs a closure must has one context parameter which will be passed to closure as its context.
And the caller of F must use a correct (f,c) pair.
If you can change the signature of function to fit to C-style closure, your code will be simple and machine-independence.
If couldn't (function and apply is not written by you), try to persuade him to change his code.
If failed, you have no choice but to use some closure libraries.
Since you want to generate a function that follows a simple recipe,
this shouldn't be too tricky to do with some inline assembly and
a block of executable/writable memory.
This approach feels a bit hacky so I wouldn't recommend it in production code. Due to the use of inline assembly this solution works only on Intel x86-64 / AMD64, and will need to be translated to work with other architectures.
You might prefer this to other JIT-based solutions as it does not depend on any external library.
If you would like a longer explanation of how the below code works,
leave a comment and I'll add it.
For security reasons, the code page should be marked PROT_READ|PROT_EXEC after a function is generated (see mprotect).
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/mman.h>
int snippet_processor(char *buffer, double value, int action);
enum snippet_actions {
S_CALC_SIZE,
S_COPY,
};
typedef double (*callback_t) (unsigned int, unsigned int);
int main(int argc, char **argv) {
unsigned int pagesize = 4096;
char *codepage = 0;
int snipsz = 0;
callback_t f;
/* allocate some readable, writable and executable memory */
codepage = mmap(codepage,
pagesize,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANONYMOUS | MAP_PRIVATE,
0,
0);
// generate one function at `codepage` and call it
snipsz += snippet_processor(codepage, 12.55, S_COPY);
f = (callback_t) (codepage);
printf("result :: %f\n", f(1, 2));
/* ensure the next code address is byte aligned
* - add 7 bits to ensure an overflow to the next byte.
* If it doesn't overflow then it was already byte aligned.
* - Next, throw away any of the "extra" bit from the overflow,
* by using the negative of the alignment value
* (see how 2's complement works.
*/
codepage += (snipsz + 7) & -8;
// generate another function at `codepage` and call it
snipsz += snippet_processor(codepage, 16.1234, S_COPY);
f = (callback_t) (codepage);
printf("result :: %f\n", f(1, 2));
}
int snippet_processor(char *buffer, double value, int action) {
static void *snip_start = NULL;
static void *snip_end = NULL;
static void *double_start = NULL;
static int double_offset_start = 0;
static int size;
char *i, *j;
int sz;
char *func_start;
func_start = buffer;
if (snip_start == NULL) {
asm volatile(
// Don't actually execute the dynamic code snippet upon entry
"jmp .snippet_end\n"
/* BEGIN snippet */
".snippet_begin:\n"
"movq .value_start(%%rip), %%rax\n"
"movd %%rax, %%xmm0\n"
"ret\n"
/* this is where we store the value returned by this function */
".value_start:\n"
".double 1.34\n"
".snippet_end:\n"
/* END snippet */
"leaq .snippet_begin(%%rip), %0\n"
"leaq .snippet_end(%%rip), %1\n"
"leaq .value_start(%%rip), %2\n"
:
"=r"(snip_start),
"=r"(snip_end),
"=r"(double_start)
);
double_offset_start = (double_start - snip_start);
size = (snip_end - snip_start);
}
if (action == S_COPY) {
/* copy the snippet value */
i = snip_start;
while (i != snip_end) *(buffer++) = *(i++);
/* copy the float value */
sz = sizeof(double);
i = func_start + double_offset_start;
j = (char *) &value;
while (sz--) *(i++) = *(j++);
}
return size;
}
Using FFCALL, which handles the platform-specific trickery to make this work:
#include <stdio.h>
#include <stdarg.h>
#include <callback.h>
static double internalDoubleFunction(const double value, ...) {
return value;
}
double (*constDoubleFunction(const double value))() {
return alloc_callback(&internalDoubleFunction, value);
}
main() {
double (*fn)(unsigned int, unsigned int) = constDoubleFunction(5.0);
printf("%g\n", (*fn)(3, 4));
free_callback(fn);
return 0;
}
(Untested since I don't have FFCALL currently installed, but I remember that it works something like this.)
One way of doing would be to write a standard C file with the set of functions you want, compile it via gcc and the load it as a dynamic library to get pointers to the functions.
Ultimately, it probably would be better if you were able to specify your functions without having to define them on-the-fly (like via having a generic template function that takes arguments that define its specific behavior).
If you want to write code on the fly for execution, nanojit might be a good way to go.
In your code above, you're trying to create a closure. C doesn't support that. There are some heinous ways to fake it, but out of the box you're not going to be able to runtime bind a variable into your function.
As unwind already mentioned, "creating code at runtime" is not supported by the language and will be a lot of work.
I haven't used it myself, but one of my co-workers swears by Lua, an "embedded language". There is a Lua C API which will (theoretically, at least) allow you to perform dynamic (scripted) operations.
Of course, the downside would be that the end user may need some sort of training in Lua.
It may be a dumb question, but why does the function have to be generated within your application? Similarly what advantage does the end-user get from generating the function themselves (as opposed to selecting from one or more predefined functions that you provide)?
This mechanism is called reflection where code modifies its own behavior at runtime. Java supports reflection api to do this job.
But I think this support is not available in C.
Sun web site says :
Reflection is powerful, but should not
be used indiscriminately. If it is
possible to perform an operation
without using reflection, then it is
preferable to avoid using it. The
following concerns should be kept in
mind when accessing code via
reflection.
Drawbacks of Reflection
Performance Overhead Because
reflection involves types that are
dynamically resolved, certain Java
virtual machine optimizations can not
be performed. Consequently, reflective
operations have slower performance
than their non-reflective
counterparts, and should be avoided in
sections of code which are called
frequently in performance-sensitive
applications.
Security Restrictions
Reflection requires a runtime
permission which may not be present
when running under a security manager.
This is in an important consideration
for code which has to run in a
restricted security context, such as
in an Applet.
Exposure of Internals
Since reflection allows code to
perform operations that would be
illegal in non-reflective code, such
as accessing private fields and
methods, the use of reflection can
result in unexpected side-effects,
which may render code dysfunctional
and may destroy portability.
Reflective code breaks abstractions
and therefore may change behavior with
upgrades of the platform. .
It looks like you're coming from another language where you commonly use this type of code. C doesn't support it and it although you could certainly cook up something to dynamically generate code, it is very likely that this isn't worth the effort.
What you need to do instead is add an extra parameter to the function that references the matrix it is supposed to work on. This is most likely what a language supporting dynamic functions would do internally anyway.
If you really need to dynamically create the functions, maybe an embedded C interpreter could help. I've just googled for "embedded C interpreter" and got Ch as a result:
http://www.softintegration.com/
Never heard of it, so I don't know anything about it, but it seems to be worth a look.

Resources