Initialize an array in C - c

Since it's not possible to assign values to a const after it's initialized, how can I achieve this?
const double input1[1000][2];
for(int i = 0; i < 1000; i++){
input1[i][0] = i;
input1[i][1] = i*2;
}

You'll have to generate the explicit initialization (i.e. the { {0, 0}, {1, 2}, {2, 4}, ... etc etc ... {1000, 2000} }.
You can do this with map/apply macros, or with your build system - having it run some script which generates that initialization sequence and plants it into the file.

You mentioned in the comments that this data is a training session data for a neural network.
I assume that you don't want to input 2000 values by hand and I assume that these values
come from another file, perhaps a csv or the output of another program that
generates the training data.
In that case, I'd write a script that generates a header file from the training
data that looks like this:
// training_data.h
// trainng data, automatically generated by script gen_training_data.py
// do not modify this file
#ifndef TRAINING_DATA_H
#define TRAINING_DATA_H
const double traing_data[1000][2] = {
{ 0, 1 },
{ 0, 2 },
....
};
#endif
The script (that you can write with other languages, bash, python, perl) would
take the training data and generate the header file for you, so you don't have
to write 2000 values by hand. Then you can use it in your C program like this:
#include <stdio.h>
#include "training_data.h" // include auto generated file
int main(void)
{
...
feed_to_neural_network(training_data);
...
}
If you use a build system like cmake, you can let cmake execute your script so
that it autogenerates the header file before compiling. That would save you on
the long run a lot of time.

I don't understand why would you want to store the index value in the first index. But removing const can solve your issue. But better thing to do would be, to just store the value instead of index. Like following:
double input1[1000];
for (int i = 0; i < 1000; i++)
{
input1[i] = i * 2;
}

Related

How to initialize struct members at compile time, depending on the value of previously defined entries in an array

Suppose I have a structure used for describing values stored inside a virtual memory map:
typedef struct
{
uint16_t u16ID;
uint16_t u16Offset;
uint8_t u8Size;
} MemMap_t;
const MemMap_t memoryMap[3] =
{
{
.u16ID = 0,
.u16Offset = 0,
.u8Size = 3
},
{
.u16ID = 1,
.u16Offset = 3,
.u8Size = 2
},
{
.u16ID = 2,
.u16Offset = 5,
.u8Size = 3
}
};
Each entry contains an offset for addressing the memory location and the size of the value it contains
The offset of each following value is dependent on the offset and size of the values before it
In this example I set all offsets manually.
The reason why I implemented it that way is that it allows me to change the layout of the entire memory map later on,
the structure still making it possible to look up the offset and size of an entry with a certain ID.
The problem with this is that setting the offsets manually is going to get unwieldy quite quickly once the map becomes bigger
and changing the size of an entry at the beginning would require manually changing all offsets of the entries after that one.
I came up with some ways to just calculate the offsets at runtime, but as the target system this will run on is a very RAM constrained embedded system, I really want to keep the entire map as a constant.
Is there an elegant way to calculate the offsets of the map entries at compile time?
After some experiments, found something that may work for large number of attributes. Posting as new answer, as my previous answer took very different approach.
Consider create a proxy structure that describe the object described by MamMap_t, using series of char[] objects.
static struct MemMap_v {
char t0[3] ;
char t1[2] ;
char t2[3] ;
char t3[10] ;
} vv ;
const MemMap_t memoryMap[3] =
{
{
.u16ID = 0,
.u16Offset = vv.t0 - vv.t0,
.u8Size = sizeof(vv.t0)
},
{
.u16ID = 1,
.u16Offset = vv.t1 - vv.t0,
.u8Size = sizeof(vv.t1)
},
{
.u16ID = 2,
.u16Offset = vv.t2 - vv.t0,
.u8Size = sizeof(vv.t2)
}
};
Is there an elegant way to calculate the offsets of the map entries at compile time?
Yes: write yourself a code generator that accepts input data describing the memory map and outputs C source for the initializer or for the whole declaration. Have the appropriate source file #include that. Structure this program so that the form of its input data is convenient for you to maintain.
If the number of map entries were bounded by a (very) small number, and if their IDs were certain to be consecutive and to correspond to their indices in the memoryMap array, then I feel pretty confident that it would be possible to write a set of preprocessor macros that did the job without a separate program. Such a preprocessor-based solution would be messy, and difficult to debug and maintain. I do not recommend this alternative.
Short Answer: not possible to calculate values at compile time, given data structure.
Alternative:
Consider using symbolic constants for the sizes. E_0, E_1, E_2, ..., then you can calculate the offset at compile time (E_0, E_0+E_1, E_0+E_1+E_2). Not very elegant, and does not scale well for large number of items, but will meet the requirements.
Second alternative will be to create a function that will return the pointer to memoryMap. The function can initialize the offset on the first call. The program will call getMemoryMap instead of memoryMap.
static MemMap_t memoryMap[3] =
{
...
}
const MemMap_t *getMemoryMap() {
MemMap_t *p = memoryMap ;
static bool offsetDone ;
if ( !offsetDone ) {
offsetDone = true ;
for (int i=1; i<sizeof(memoryMap)/sizeof(memoryMap[0]) ; i++ ) {
p[i].u16Offset = p[i-1].u16Offset + p[i-1].u8Size ;
} ;
return p;
}

Best way to extract all enums from C project

I'm writing my own enums-based backtrace. Basically each function call will append it's error to a pre-defined stack which will eventually include all errors across all function calls.
I want to create an efficient way to parse it. In the end I got int backtrace[] with enum values from all over my codebase, and I'd like to relate each enum value to it's name.
This should of course be done post-failure (not at runtime), so what I'm missing is a way, maybe as a part of the compilation step, to dump all my enums and there values to a file. Then i can write a script that parse the errors.
Is there an easy (cross-platform) static tool that does that?
Not sure how you log the errors, but how about:
typedef enum
{
E_SUCCESS = 0,
E_FAIL,
...
} error_t;
typedef struct
{
error_t code;
char * error_name;
} backtrace_entry_t;
backtrace_entry_t backtrace[..];
#define FUNC_EXIT(error_code__) \
do { \
backtrace[func_id].code = (error_code__); \
backtrace[func_id].error_name = #error_code__; \
} while (0)
Then, when you call FUNC_EXIT(E_SUCCESS);, you'll get for the backtrace for the function to be: {.code = 0, .error_name = "E_SUCCESS"}
The problem is, you can't get the right name if you call FUNC_EXIT(var);, where var is some local variable.
Another option, although still not an automagical one:
typedef enum
{
E_SUCCESS = 0,
E_FAIL,
...
NOF_ERROR_CODES
} error_t;
#define MAP_E_CODE_TO_NAME(error_code__) [error_code__] = #error_code__
const char * error_to_name_mapping[NOF_ERROR_CODES] = {
MAP_E_CODE_TO_NAME(E_SUCCESS),
MAP_E_CODE_TO_NAME(E_FAIL),
...
};
Will give a const char * array with {"E_SUCCESS", "E_FAIL", ...}, which you can use like this:
printf("The name of error code %d is '%s'", error, error_to_name_mapping[error]);
The problem here is that you have to have positive value to errors with increasing values.

Create shared parameter file for C and Python

I need to create a parameter file that can be managed across a Python 3.7 and a C code base. This file needs to be modifiable either by the C or the Python program with the changes being taking effect on the other software (an update function will handle reading the updated file). It's best if the file is not human readable, as it contains information that is better left obfuscated.
**Is there a recommended method to do so? **
I could create separate python and C files, but the set of parameters will change over time (for code maintenance), and the values would be changed by these programs. The list would also be very long. It would be a hassle to maintain two different files and update them over time. Also, the file may need to be exchanged between users, such that a version modified by the software ran by user1 needs to be readable by the software run by user2. The idea is that other parts of both codes could access parts of the parameter list without knowing the full contents of the list.
To clarify the example, I could have a parameter.h file containing:
struct {
double par1 =1.1;
int par 2 =2;
} par_list
And I could have a parameter.py with:
class par_list:
def(__self__):
self.par1 = double(1.1)
self.par2 = int(2)
Then, by doing a import in Python or a include in C, I could initialize the parameter list. But in this case the parameters are being read on different files.
I'm considering using some kind of binary file to keep the values, and create a script that writes both the Python and C code that reads and updates the values. I'm concerned because the binary file would need to be interchangeable between ARM architecture running Linux, and x86 architecture running Windows.
Here is an example working with numpy:
C code:
#include <stdio.h>
#include <stdint.h>
struct Struct_format{
uint8_t the_unsigned_int8;
int32_t the_signed_int32[2];
double the_double;
};
typedef struct Struct_format upperStruct;
//Use separate file to define default value:
void printStruct(upperStruct test_struct){
printf("test_struct.the_unsigned_int8 = %d\n", test_struct.the_unsigned_int8);
printf("test_struct.the_signed_int32[0] = %d\n", test_struct.the_signed_int32[0]);
printf("test_struct.the_signed_int32[1] = %d\n", test_struct.the_signed_int32[1]);
printf("test_struct.the_double = %f\n", test_struct.the_double);
}
void main(){
//Define a "default" value:
upperStruct fromC2Python = {4U,{-3,-1},2.1};
printf("Printing fromC2Python\n");
printStruct(fromC2Python);
//Save this default in a file:
FILE * fid = fopen("fromC2Python.bin","w");
fwrite((void *)&fromC2Python, sizeof(fromC2Python) ,1, fid);
fclose(fid);
//Now load the file created by Python:
upperStruct fromPython2C;
FILE * fid_py = fopen("fromPython2C.bin","r");
fread(&fromPython2C, sizeof(fromPython2C) ,1, fid_py);
fclose(fid_py);
printf("Printing fromPython2C\n");
printStruct(fromPython2C);
}
Python code:
import numpy
datatype = numpy.dtype([('potato',
[('time', numpy.uint8),
('sec', numpy.int32, 2)]),
('temp', numpy.float64)],
align=True)
fromPython2C = numpy.array([((5, (-6, -7)), 61.55)], dtype=datatype)
print(fromPython2C)
fromPython2C.tofile("fromPython2C.bin", sep="")
fromC2Python = numpy.fromfile("fromC2Python.bin", dtype=datatype, count=-1, sep="")
print(fromC2Python)
print(fromC2Python['potato'])
print(fromC2Python['potato']['time'])
print(fromC2Python['temp'])
The ideia is that numpy allows reading and writing to structured binary files. Hence, it suffices to create the dtype specification with a text parser.

Can gcc/clang optimize initialization computing?

I recently wrote a parser generator tool that takes a BNF grammar (as a string) and a set of actions (as a function pointer array) and output a parser (= a state automaton, allocated on the heap). I then use another function to use that parser on my input data and generates a abstract syntax tree.
In the initial parser generation, there is quite a lot of steps, and i was wondering if gcc or clang are able to optimize this, given constant inputs to the parser generation function (and never using the pointers values, only dereferencing them) ? Is is possible to run the function at compile time, and embed the result (aka, the allocated memory) in the executable ?
(obviously, that would be using link time optimization, since the compiler would need to be able to check that the whole function does indeed have the same result with the same parameters)
What you could do in this case is have code that generates code.
Have your initial parser generator as a separate piece of code that runs independently. The output of this code would be a header file containing a set of variable definitions initialized to the proper values. You then use this file in your main code.
As an example, suppose you have a program that needs to know the number of bits that are set in a given byte. You could do this manually whenever you need:
int count_bits(uint8_t b)
{
int count = 0;
while (b) {
count += b & 1;
b >>= 1;
}
return count;
}
Or you can generate the table in a separate program:
int main()
{
FILE *header = fopen("bitcount.h", "w");
if (!header) {
perror("fopen failed");
exit(1);
}
fprintf(header, "int bit_counts[256] = {\n");
int count;
unsigned v;
for (v=0,count=0; v<256; v++) {
uint8_t b = v;
while (b) {
count += b & 1;
b >>= 1;
}
fprintf(header, " %d,\n" count);
}
fprintf(header, "};\n");
fclose(header);
return 0;
}
This create a file called bitcount.h that looks like this:
int bit_counts[256] = {
0,
1,
1,
2,
...
7,
};
That you can include in your "real" code.

Using array in .h file

I am trying to learn to program in C (not C++!). I've read about external variables, which should (according to the writer) give a nicer code. In order to use the external variables, I must #define them in the .h file, before I can use them in main.c file, using the extern command in front of the variable. I am trying to create an array in the .h file like this:
#define timeVals[4][2];
timeVals[0][0] = 7;
timeVals[0][1] = 45;
timeVals[1][0] = 8;
timeVals[1][1] = 15;
timeVals[2][0] = 9;
timeVals[2][1] = 30;
timeVals[3][0] = 10;
timeVals[3][1] = 25;
(it's a clock I'm trying to make, simple program in console). The first column indicates hours and the second indicates minutes. In my main I have written
extern int timeVals[][];
but I get an error telling me that " expected identifier or '(' before '[' token|" and I can't see what the issue is... any ideas or advices?
I am using the .h file to learn how to use external variables, so I can't move the values back into main.c
First, this:
#define timeVals[4][2];
Is a confusion. You mean this:
int timeVals[4][2];
Put that in your .h file, then in your .c file, something like this:
int timeVals[4][2] = {
{ 1, 2 }, // ...
};
That's how you initialize the entire array (any unspecified elements will be zero).

Resources