This is purely for readability. I want to have a very large constant array of values, but it makes my file a lot less pleasant to read. So I'd like to have that array initialized after use, though I want it to be constant. I know this is probably impossible, but it's probably also very common. So what workarounds are there ? I do not want to create a separate file right now.
Some thing like :
static const float array_of_values[1000];
float getValueFromArray(int index)
{
return array_of_values[index];
}
array_of_values = {0.123f, 0.456f, 0.789f ...};
First of all what you're doing is not initialization, it's plain assignment. And you can't assign to an array. And you can't have general statements outside of functions. If you want to initialize the array, you need to do it when defining the array.
With that said, you have to remember (or learn) that any definition without explicit initialization is tentative.
That means you can create a tentative definition, basically to get the declaration out of the way. Then at a later place in the source file you can add the actual definition:
static const float array_of_values[1000];
float getValueFromArray(int index)
{
return array_of_values[index];
}
static const float array_of_values[] = { 0.123f, 0.456f, 0.789f, /* ... */ };
These are common solutions to make the file less cumbersome to read:
static const float array_of_values[1000] = { MACRO }; // macro being an initalizer list
or
static const float array_of_values[1000] =
{
#include "initlist.h"
};
I would personally recommend the macro version since it's more flexible and less mysterious. You could still declare the macro in a separate header file.
There's also tentative definitions which is generally a bad idea, again because it makes the code mysterious and hard to read:
static const float array_of_values[1000];
float getValueFromArray(int index)
{
return array_of_values[index];
}
static const float array_of_values[1000] = {0.123f, 0.456f, 0.789f};
#include <stdio.h>
int main (void)
{
printf("%f\n", array_of_values[0]);
printf("%f\n", getValueFromArray(0));
}
Try this:
#include <stdio.h>
static float array_of_values_base[1000]; // the effective array has "base" in its identifier
static const float *array_of_values = array_of_values_base; // your array is now a pointer
float getValueFromArray(int index)
{
return array_of_values[index];
}
int main(void) {
array_of_values_base[0] = 0.123f;
array_of_values_base[1] = 0.456f;
array_of_values_base[2] = 0.789f;
// ...
printf("value at index 1 is %f\n", getValueFromArray(1));
}
Related
I have recently run into some trouble while trying to perform the following logic:
static const int size = getSize();
int getSize() {
return 50;
}
The error I have received is initialiser element is not constant
Having read online I understand that this issue is because the compiler evaluates the static const expression at compilation and therefore cannot know what the value is supposed to be.
My question is how do I get around this?
If I have a library that contains many functions but they all require this logic how are they supposed to use it without having to calculate it each time?
And even if they have to, what if the logic itself can change throughout runtime but I only ever want the first value I receive from the function?
Perhaps I should clarify that the logic in getSize is just an example, it could also contain logic that retrieves the file size from a specific file.
Unlike in C++ you cannot initialize global variables with the result of a function in C, but only with real constants known at compile time.
You need to write:
static const int size = 50;
If the constant must be computed by a function you can do this:
Dont declare static const int size = ... anymore, but write this:
int getSize()
{
static int initialized;
static int size;
if (!initialized)
{
size = SomeComplexFunctionOfYours();
initialized = 1;
}
return size;
}
int main(void)
{
...
int somevar = getSize();
...
That way SomeComplexFunctionOfYours() will be called only once upon the first invocation of getSize(). There is a small price to be paid: each time you invoke getSize(), a test needs to be performed.
Or you can initialize it explicitely like this, but then size cannot be const anymore:
static int size;
void InitializeConstants()
{
size = SomeComplexFunctionOfYours();
}
int main(void)
{
InitializeConstants();
...
int somevar = size;
...
The compiler needs to know the value of your constant variable at the compilation time, because its a constant.
Also you can't initialize a variable with a function.
You should do something like this :
#define SIZE 50
static const int size = SIZE;
If I convert const int to int inside a void it works.
But when I create an extern const int it doesn't.
void ReadFromEpprom()
{
int Start = 343;
const int End=Start; //This works
}
Example 2
Header File
extern const int End;
Source file
const int End;
void ReadFromEpprom()
{
int Start = 343;
End=Start; //This doesn't work
}
In second situation I get error:
(364) attempt to modify object qualified const
How can I solve this?
Should I make it with another way?
When you declare a constant variable this means the variable will not change.So it makes sense that constant variables must be initialized immediately.You are doing this in your first example which is correct.In your second example you have a constant variable and then you are trying to modify it's value.This is incorrect since the variable is already constant.
The extern here is a red herring.
If you use const int End then you need to initialise End at the point of this declaration. That's because it's const.
So const int End = Start; works fine, but const int End; is not syntactically viable.
In C you can't arrange things so you have a const at global scope and a function that sets the value at run-time. But what you could do is embed the value in a function (as as static), and call that function to initialise and subsequently retrieve the value.
Initialiazation versus assignment:
A const object can be initialized (given a value at the declaration), but not assigned (given a value later).
This is initialization, and "works". It is initialization the local variable End that exist inside ReadFromEpprom().
void ReadFromEpprom()
{
...
const int End=Start; //This works
End=Start; attempts to assigned End that exist at file scope, outside of ReadFromEpprom(). const objects cannot be assigned.
const int End;
void ReadFromEpprom()
{
...
End=Start; //This doesn't work
}
How can I solve this?
Let external code to read localEnd via a function ReadEnd(), yet allow local code to write localEnd.
static int localEnd;
int ReadEnd() {
return localEnd;
}
void ReadFromEpprom() {
int Start = 343;
localEnd = Start;
}
I agree with all the other answers.
It seems that you want to initialize a const value with a value that will be determined at run time, which is impossible.
What you can do is two workarounds.
Remove const. Add a comment near its definition that the variable is set only once in the very beginning.
Use a function instead of a const int variable; implement the "run code only once" idea inside this function.
Header file:
int CalcEnd();
Source file:
int CalcEnd()
{
static int init_done = 0;
static int result;
if (!init_done)
{
result = 343; // or any complex calculation you need to do
init_done = 1;
}
return result;
}
Note how the function uses static variables and logic to do initialization only once.
If you use the function idea, and don't want to remember typing the parentheses in the function call (CalcEnd()), you can define a macro:
#define End MyCalcEnd()
This will make it appear as if End were const int variable, when actually it's a function call. This usage of macros is controversial, use it only if you are sure it will not lead to confusion later.
In C, I am trying to pass a single-variable function into an optimization routine (optimization_routine). The optimization routine takes as input a pointer func1ptr to a function of a single float variable. However, I need to be able to pass multiple variables into this function. Thus, I am trying to construct a function pointer of one variable where all but the first inputs are "constants" into the function variable (sort of analogous to a partial derivative in calculus). I think I can do this with function pointers, but I can't figure out a syntax that makes sense.
That is, I have a function like this:
float function_all_inputs( float A, int B, float C, char D);
The optimization function requires a pointer like this:
typedef (*func1ptr)(float);
void optimization_function( func1ptr fp );
Thus, I want to construct a function of this form:
// create a function of A only at runtime using inputs B,C,D
func1ptr fp = ( & function_all_inputs(A,B,C,D))(A);
The function pointed to by fp should have the signature:
float function_one_input(float A);
Inputs B, C, and D are calculated elsewhere in the code, and thus are not known at compile-time; however, they are constant inside optimization_function.
I think I can do this in pure C using function pointers, however, I can't figure out the correct syntax. None of the examples I found online cover this case. Any advice you can provide would be appreciated.
It sounds like you are asking how to create a closure to capture parameters in C, and you can take a look at some options in the linked question.
However, without custom extensions, I think you will need to use global variables to achieve the effect you are looking for.
// Pass this wrapper with the name "wrapper" into the function
// that requires a function pointer
void wrapper(float a) {
// Where last four arguments are global variables that are computed first.
function_all_inputs(a, b, c, d, e);
}
// No need to create an explicit function pointer.
// Passing the name of the function is sufficient.
optimization_function(wrapper);
You need to write a wrapper function, like
int b;
float c;
char d;
int wrap(float a) {
return function_all_inputs(a, b, c, d);
}
Consider concurrency an re-entrancy though:
If multiple threads can use the wrapper, and need it to pass different data, make those globals thread-local:
_Thread_local int b;
If you need full re-entrancy, things get complicated:
You need to (also) save the variables before using a nested invocation with different parameters.
Writing a second (and maybe third) version of the wrapper using different globals may be better.
If you need more active at the same time, you can try a pool of those functions, though it gets unwieldy really fast. Better change your optimization-function by adding a context-parameter, and pass those extra-parameters with that.
For full freedom, you really need a way to write functions at runtime, at least enough to recover a context-pointer. That's not possible in pure C though.
If sizeof(float) >= sizeof(void*) on your platform, then you can "hack" it as follows:
typedef struct
{
float a;
int b;
float c;
char d;
}
params;
int function_all_inputs(float a, int b, float c, char d)
{
...
}
int function_one_input(float f)
{
params* p;
memcpy((void*)&p, (void*)&f, sizeof(void*));
return function_all_inputs(p->a, p->b, p->c, p->d);
}
int optimize()
{
float f;
params v;
params* p = &v;
v.a = ...;
v.b = ...;
v.c = ...;
v.d = ...;
memcpy((void*)&f, (void*)&p, sizeof(void*));
return optimization_function(function_one_input, f);
}
You weren't very consistent in your question about the return-value type, so I used int.
This may be overkill, but libffi supports creating closures in the following way:
#include <stdio.h>
#include <ffi.h>
typedef struct BCD { int B; float C; char D; } BCD;
void function_one_input_binding
(ffi_cif* cif, int* result, void** args, BCD* bcd) {
*result = function_all_inputs(*(float*)args[0], bcd->B, bcd->C, bcd->D);
}
int main() {
ffi_cif cif;
ffi_type* args[1];
ffi_closure* closure;
int (*function_one_input)(float);
// Allocate a closure.
closure = ffi_closure_alloc(sizeof(ffi_closure), &function_one_input);
// Tell libffi the parameter and return types.
args[0] = &ffi_type_float;
ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_int, args);
// Bind closure data.
BCD bcd = { .B = 1, .C = 2.5, .D = 'x' };
ffi_prep_closure_loc(
closure, &cif, function_one_input_binding, &bcd, function_one_input);
// Call the function.
int result = function_one_input(42.5);
// Free the allocated closure.
ffi_closure_free(closure);
return 0;
}
I've got a bunch of C functions which get assigned to an array of function pointers, along the lines of this:
typedef int (*func)(int);
int SomeLongName1(int a) {
// ...
}
// ...
int SomeLongName1000(int a) {
// ...
}
func f[] = { SomeLongName1, ... , SomeLongName1000 };
This is a lot of work to create and is prone to errors. For instance, there could be a typo in the function name such that a valid function is still named, but the wrong one. Or, if a new function is added at the end one could forget to go in and explicitly add it to the list of function pointers as well.
In order to avoid having to explicitly declare the array of function pointers I have tried various tricks such as macros, which make the code hard to understand and require knowing how the macro works, and I am generally unsatisfied with them.
What I would like to do is something like this:
typedef int (*func)(int);
func f[] = {
int SomeLongName1(int a) {
// ...
}
// ...
int SomeLongName1000(int a) {
// ...
}
};
This way, the array would be automatically created, and if there was some way to put a null pointer at the end so I can determine how many function pointers there are that would be great as well.
However, the above isn't valid C and I'm coming up empty with any way of accomplishing this. If it is something compiler specific (e.g. a GCC extension) that would be ok.
All the functions are statically known at compile time, so I would like to avoid having to do any run-time initialization of the function pointer array - not that I have found a method to do it that way either.
This related question How to define an array of functions, seems to ask the same question, but does not carry it to its logical conclusion. Specifically, I don't want to have to re-type anything I have already typed so as to save time and avoid errors.
If you don't care about the order of functions in the array, and are willing to use a GCC extension, then you can achieve what you want using a whole bunch of initializer (constructor) functions. This obviously isn't ideal because of the sheer number of extra functions defined, but it is certainly one approach you can consider. It constructs the array at runtime.
Define the function append to append a single function to an array (reallocating if needed). Then, the code is basically
#define ARRAYFUNC(name) int name(int); \
void __attribute__((constructor)) __init_##name(void) { append(func); } \
int name(int a)
ARRAYFUNC(func1) {
...
}
ARRAYFUNC(func2) {
...
}
You could use the C preprocessor (X-Macros) for this:
#include <stdio.h>
// define a list of function names and bodies
#define FUNCS \
FUNC(add, { return a+b; }) \
FUNC(mul, { return a*b; }) \
FUNC(div, { return a/b; })
// let the preprocessor make up the actual function implementations
#define FUNC(name, body) int name(int a, int b) body
FUNCS
#undef FUNC
typedef int (*func)(int, int);
// let the preprocessor populate the array of function pointers
func f[] = {
#define FUNC(name, body) name,
FUNCS
#undef FUNC
};
// use it:
int main () {
int a = 2, b = 3, i = 0;
for (; i < sizeof(f)/sizeof(*f); i++) {
printf("%d\n", f[i](a,b));
}
return 0;
}
The output is:
$ gcc test.c && ./a.out
5
6
0
What I would use to solve such a situation (only if I can't avoid it, of course), is to use preprocessing. Not the one available from the C preprocessor, it does not provide the required functionality in a sensible syntax, but a really powerful one like m4.
With m4, your code could look like this:
define(`functionList', `, 0')
define(`functionArrayMember', `define(`functionList', `$1, 'FunctionList)$1')
define(`buildFunctionArray', `{ functionList }')
int functionArrayMember(SomeLongName1)(int a) {
return a+1;
}
//...
int functionArrayMember(SomeLongName1000)(int a) {
return a+1;
}
func f[] = buildFunctionArray();
You just need to provide the right m4 definition for functionArrayMember() and buildFunctionArray(), and you have the functionality you need.
I do not think there is any other way of doing what want to do.
What you wrote
func f[] = { SomeLongName1, ... , SomeLongName1000 };
already does what is best.
Maybe you could name your functions with an prefix 0000 to 1000, so that you can be sure each function is in the right place in your functions pointer array.
Also, if you really have 1000 different functions, they are surely things in common that could lead you to sort them in several arrays, reducing the numbering effort, and that is less error prone.
How do I approach a function echo_tpl that can take 1 parameter of type int or string ,and print it out?
C doesn't have templates. I think the best you could do is to use an union or to have the functions have different names. The latter way of having different names is the quasi-standard method of doing it (for instance fabs fabsf fabsl, also heavily used by OpenGL which also accounts for the fact C can't overload functions)
void echo_tpl_s(char const *string) { /* ... */ }
void echo_tpl_i(int number) { /* ... */ }
int main(void) {
echo_tpl_s("Hello world");
echo_tpl_i(42);
}
If there is a lot of common code, you may decide to factor it out in separate functions
void echo_tpl_s(char const *string) {
prepare_output_device();
printf("%s", string);
unprepare_output_device();
}
void echo_tpl_i(int number) {
prepare_output_device();
printf("%d", number);
unprepare_output_device();
}
Or you can take the union way, which will have the function names be equal but instead blow up the parameter type with meta informations.
enum Type {
Number,
String
};
struct Value {
enum Type type;
union {
int number;
char const *string;
} u;
};
void echo_tpl(struct Value value) {
switch(value.type) {
case Number: printf("%d", value.u.number); break;
case String: printf("%s", value.u.string); break;
}
}
int main(void) {
echo_tpl((struct Value) {
.type = String,
.u.string = "Hello world"
});
}
The union way is particular well-suited if you want to store the value somewhere and then execute the print function without caring what value type you pass to it. In C89 you would need to create the value separately since it doesn't have compound literals
int main(void) {
struct Value value;
value.type = String;
value.u.string = "Hello world";
echo_tpl(value);
}
It's a good idea to create functions for that, though
struct Value stringval(char const *string) {
struct Value value;
value.type = String;
value.u.string = string;
return value;
}
struct Value numberval(int number) {
struct Value value;
value.type = Number;
value.u.number = number;
return value;
}
int main(void) {
echo_tpl(stringval("Hello world!"));
}
Some compilers may provide extensions for writing such things. For instance Clang provides function overloading in C.
void echo_tpl(int value) __attribute__((overloadable)) {
printf("%d", value);
}
void echo_tpl(char const *value) __attribute__((overloadable)) {
printf("%s", value);
}
This solves the call-side of the function not to depend on the type. On the definition side, you still have to write the code twice. That's mainly because (as another answer explains) C doesn't have type-generic output functions. Of course if you use this feature, your code becomes nonportable.
The traditional way to translate templates to C is using the preprocessor. I'd do it something like this:
// this creates each template "instance"
#define ECHO_TPL_IMPLEMENT(t) void echo_tpl_##t(t param){\
/* this is where you write your function that uses param */ \
}
// this calls the specific template instance
#define ECHO_TPL(t, val) echo_tpl_##t(val)
// as i wrote it, the function only accepts a 1 word parameter type
// so for simplicity, i'm defining char* to be string
typedef char *string;
// i implement the function for the types int and string
ECHO_TPL_IMPLEMENT(int) // creates echo_tpl_int
ECHO_TPL_IMPLEMENT(string) // creates echo_tpl_string
main()
{
// then i just call them and let the preprocessor handle it
ECHO_TPL(string, "meep"); // will call echo_tpl_string
ECHO_TPL(int, 10); // will call echo_tpl_int
}
This is how the original C++ compilers handled templates, only they had (and still do to this day) more complex type mangling rules, where I just assumed types are 1 word and if they aren't, you'll have to typedef them.
edit: Note that I left the function empty. This is indeed how you write "templated functions" in C, but I cant really write the parameter like you asked because C doesn't have a type-independent file writing api. printf and write require information about the actual type (through the %d or %s and through the length in bytes of what to write respectively), and we don't have that.
Also note that this applies to C++ too. You can't use the C api to write to a file from a template either, you can only really use cout (or the boost format alternative or something similar). You'll have to think what you want to do with the actual function.
Late, but worth adding to this that as of the C11 standard, C now has some very limited support for overloading by using _Generic expressions, that select the right result expression at compile-time based on the type of an input. Nothing like templates but they can answer this old question like this:
#define echo_tpl(X) _Generic((X), int: echo_tpl_i, \
char *: echo_tpl_s)(X)
void echo_tpl_s(char const *string) { /* ... */ }
void echo_tpl_i(int number) { /* ... */ }
int main(void) {
echo_tpl("Hello world");
echo_tpl(42);
}
You still have to define the function implementations using separate names as you would in C99, but you can define a macro with the C++-ish name that inserts a _Generic expression at every point of use, in order to choose the right version for that call site, without making the function user think about the argument type.
It seemingly takes forever for C standards to be fully adopted and I have no idea which compilers implement this feature, but it will become widespread sooner if more people go forth and use it!
template <typename T>
void echo_tpl(const T& t) { std::cout << t; }
EDIT: I didn't spot the c tag. The above answer only works with C++.