I'm working on building a watch based on the Arduino/ATMega. The primary goal for now is to switch between "modes” (different functions) by pressing a button on the side. Initially, I had a long if statement like this:
if (counter == 0)
mode1();
enter code
else if (counter == 1)
mode2();
.... Repeat....
But that seems inefficient. So, I tried to make an array of the functions without actually calling them, and then call the indexed function later. The code segment is as follows (Apologies for the mess, it’s very much a WIP)
int Modes[3] = {showTime,flashlight,antiAnxiety} //these are all void functions that are defined earlier.
int scroller(){
int counter = 0;
int timeLeft = millis()+5000;
while (timer <= millis()){
...more code...
}
Modes[counter]();
}
However, when I try to compile that, I get an error:
Error: expression cannot be used as a function.
That logic works in Python, so I’m assuming there’s a concept I don’t know that gets abstracted away in higher-level languages. I’m quite willing to learn it, I just need to know what it is.
The type is wrong - instead of int you need void (*)() as type (because you have an array of void someFunction() function pointers, not an array of integers - and while the former can be converted to the latter in a way, as memory address, you cannot call an integer).
void (*Modes[3])() = {showTime, flashlight, antiAnxiety};
This code becomes easier to understand with a type definition:
typedef void (*func_type)();
func_type Modes[3] = {showTime, flashlight, antiAnxiety};
Related
I'm trying to understand a Function/Method in a Library in order to port it to Java however some parameters don't make any sense to me and reading the source code the library is based on is not helping.
Function (Note the API has few comments (We can also ignore the calc handle since it's got a supplier method))
Ssr calc_ssr(CalcHandle *calc, NoteInfo *rows, size_t num_rows, float music_rate, float score_goal) {
std::vector<NoteInfo> note_info(rows, rows + num_rows);
auto skillsets = MinaSDCalc(
note_info,
music_rate,
score_goal,
reinterpret_cast<Calc*>(calc)
);
return skillset_vector_to_ssr(skillsets);
}
NoteInfo Struct
struct NoteInfo
{
unsigned int notes;
float rowTime;
};
MinaSDCalc
// Function to generate SSR rating
auto
MinaSDCalc(const std::vector<NoteInfo>& NoteInfo,
const float musicrate,
const float goal,
Calc* calc) -> std::vector<float>
{
if (NoteInfo.size() <= 1) {
return dimples_the_all_zero_output;
}
calc->ssr = true;
calc->debugmode = false;
return calc->CalcMain(NoteInfo, musicrate, min(goal, ssr_goal_cap));
}
Calc expected input file data (Only care about the #Notes: ...)
Pastebin
Question
What is NoteInfo in calc_ssr, I don't know any C or C++ so the *rows to me just seems like a pointer to a Noteinfo instance, however the MinaSDCalc methods requires an Array/Vector which using a pointer to a single instance doesn't make sense to me (pairing this with the fact that NoteInfo needs another parameter rowTime which I think is time of Note occurrence in the file which means that value must not be constant otherwise the produced result would be inaccurate)
Github Project: https://github.com/kangalioo/minacalc-standalone (The code alone may not explain enough but it's worth a try; best to look at API.h and discern what's used from there. Though I do warn you a lot of the Code is esoteric)
Sorry if this doesn't make much sense but I've been looking into this since June/July and this API is the closest abstraction from the bare C++ code I could find.
NoteInfo * rows here is pass by pointer. So, rows actually is a pointer to an instance of type NoteInfo. This is one of the ways to pass arrays in c++ to a function. Since arrays are contiguous in memory so we can just increment the pointer by one and get the next element of the array.
for example look at these three ways to do exactly one thing, parameter to pass an array to a function :-
1. void myFunction(int *param) {}
2. void myFunction(int param[10]) {}
3. void myFunction(int param[]) {}
Look into this link for more understanding : https://www.tutorialspoint.com/cplusplus/cpp_passing_arrays_to_functions.htm
Also search for pass by pointer and pass by reference to look into different ways of passing arguments in c++.
2.however the MinaSDCalc methods requires an Array/Vector which using a pointer to a single instance doesn't make sense to me: as to this question of yours, you can now see MinaSDCalc is actually getting an array and not a single instance as passing the pointer is also one of the ways of passing an array in c++.
Say I want to store the size of a std::vector in an int I have the following options, to my knowledge:
int size = vector.size(); // Throws an implicit conversion warning
int size = (int)vector.size(); // C like typecasting is discouraged and forbidden in many code standards
int size = static_cast<int>(vector.size()); // This makes me want to gouge my eyes out (it's ugly)
Is there any other option that avoids all of the above issues?
I'm going to frame challenge this question. You shouldn't want a short and elegant solution to this problem.
Casting in any language, including C++, is basically the programmer's equivalent to swearing: you'll do it sometimes because it's easy and effortless, but you shouldn't. It means that somewhere, somehow, your design got screwed up. Maybe you need to pass the size of an array to an old API, but the old API didn't use size_t. Maybe you designed a piece of code to use float's, but in the actual implementation, you treat them like int's.
Regardless, casting is being used to patch over mistakes made elsewhere in the code. You shouldn't want a short and simple solution to resolve that. You should prefer something explicit and tedious, for two reasons:
It signals to other programmers that the cast isn't a mistake: that it's something intentional and necessary
To make you less likely to do it; and to instead focus on making sure your types are what you intended, rather than what the target API is expecting.
So embrace the static_cast, dynamic_cast, const_cast, and reinterpret_cast style of writing your code. Instead of trying to find ways to make the casts easier, find ways to refactor your code so they're less necessary.
If you're prepared to disregard all of that instead, then write something like this:
template<typename T, typename U>
T as(U && u) {
return static_cast<T>(u);
}
int size = as<int>(values.size());
bool poly_type::operator==(base_type const& o) {
if(this == &o)
return true;
if(typeid(*this) == typeid(o)) {
return as<poly_type const&>(o).value == value;
} else {
return false;
}
}
That'll at least reduce the amount of typing you end up using.
I'm going to answer your question just like you've asked. The other answers say why you shouldn't do it. But if you still want to have this, use this function:
#include <assert.h>
#include <limits.h>
inline int toInt(std::size_t value) {
assert(value<=MAX_INT);
return static_cast<int>(value);
}
Usage:
int size = toInt(vector.size());
toInt asserts if the input value is out of range. Feel free to modify it to your needs.
Storing a vector size , which might exceed the maximum value of int, in an int is an ugly operation in the first place. This is reflected in your compiler warning or the fact that you have to write ugly code to suppress the warning.
The presence of the static_cast informs other people reading the code that there is a potential bug here, the program might malfunction in various ways if the vector size does exceed INT_MAX.
Obviously (I hope?) the best solution is to use the right type for the value being stored, auto size = vector.size();.
If you really are determined to use int for whatever reason then I would recommend adding code to handle the case of the vector begin too large (e.g. throw before the int declaration if it is), or add a code comment explaining why that was never possible.
With no comments, the reader can't tell if your cast was just because you wanted to shut the compiler up and didn't care about the potential bug; or if you knew what you were doing.
currently I'm trying to use a C/C++ Code based Library in Matlab/Simulink by means of the Matlab legacy_code tool. I am very new to this, please have some patience with me.
I stumbled upon the problem, that I got class members which return an array.
What I did upon now is to follow the Matlab legacy-code examples, especially this one:
Integrate External C++ Object Methods
As far as I can see, the legacy_code tool demands a wrapper function to be wrapped around a method call, so basicaly I could, within this wrapper function manipulate the return value of the called methad any way necessary. This far no problem.
But, I'm not certain how to receive an array of information from the called method an then pass this array to Matlab/Simulink.
e.g. A method's return value is an pointer pointing at an array of information of which, let us assume, we know the length of valid information it holds.
/* Simple example */
uint8_t* BUS::answerRcvd()
{
static int r[10];
int i;
srand( (unsigned)time( NULL ) );
for ( i = 0; i < 10; ++i)
{
r[i] = rand();
}
return r;
}
Is there a way to create a wrapper function for such a method that would receive an array of information and pass it along to matlab?
Might there be a possibility to handle that array as e.g. single values of uint8_t (if way stay with the given example) and pass these like in an ordinary matlab function?
[a,b,c] = function()
I'm open to any suggestion, thank you very much in advance.
Ok, looks like I found a Solution to my problem.
As a wrapper function its possible to use the following pattern
void myfunc(double u1, double u2, double u3, double *y1, double *y2)
{
*y1=u1;
*y2=(u2+u3)/2;
}
This wrapper function the is then interfaced by the Legacy Code Tool (LCT) as followed:
def = legacy_code('initialize')
def.OutputFcnSpec = 'void myfunc(double u1, double u2, double u3, double y1[1], double y2[1])'
Simple as that. On C/C++ code use pointer nomenclature / syntax, on Matlab use array nomenclature / syntax.
I hope, this will help some people like me who need a solution to interface with legacy code which should not only accept multiple inputs, but multiple outputs as well.
In hindsight the option tuuse pointers is pretty obvious, but if you don't knoe how to teach your LCT how to interface with it, it easily becomes an tiring task.
I was wondering if there was a simple way to write an alias of a c++ class function. For instance, if I have some list container object, a logical function would be
int list::length() { return len; }
But another logical alias that programmers might use could be
int list::size() { return len; }
So, instead of writing both functions with their full body, is there any way to make list::size() an alias of list::length() such that it isn't a duplicate when compiled, but rather references the same function?
I've read that you can do this with #define, but I don't want to cause any confusion with other code-names somewhere totally out of scope (i.e. a 'size' variable).
I've also read that function pointers can fix it, but that isn't exactly an alias (since it has to apply de-referencing), nor can function pointers be given a declaration, giving it a confusing help-line to users (I would think), plus the confusion if ever I need to nest my code inside another object (I have to adjust the scope).
One of my guesses is, will the following be taken as a direct function alias by most optimizing compilers:
inline int list::length() { return len; }
inline int list::size() { return length(); }
Or, is there any strict 'alias' syntax for c++? (I couldn't find any - wasn't sure)
So then, what would be the most efficient way of doing this?
EDIT: I've accepted the answer simply to wrap up the question, since it's only a curiosity of mine. Anyone with good information, please add comments or answer, and I may even change my answer.
I would not use the preprocessor and #define to do this. In general preprocessor should be a last resort in C++. See this C++ FAQ on inline functions which also contains a section on the various evils of using macros of the preprocessor.
The approach I would use would be to have a function that will have several different aliases with a more complicated function and interface you would do something like the following:
int list::length(string xString, int iValue) {
int iReturnValue = 0; // init the return value
// do stuff with xString and iValue and other things
return iReturnValue;
}
Then do something like the following for an alias.
inline int list::size(string xString, int iValue) {return length(xString, iValue);}
The inline should basically just replace the alias with the actual function call.
See also this stack overflow posting Giving a function implementation more than one name. It provides some reasons why you might not want to do this.
I have a quick question regarding the scope of dynamic arrays, which I assume is causing a bug in a program I'm writing. This snippet checks a function parameter and branches to either the first or the second, depending on what the user passes.
When I run the program, however, I get a scope related error:
error: ‘Array’ was not declared in this scope
Unless my knowledge of C++ fails me, I know that variables created within a conditional fall out of scope when when the branch is finished. However, I dynamically allocated these arrays, so I cannot understand why I can't manipulate the arrays later in the program, since the pointer should remain.
//Prepare to store integers
if (flag == 1) {
int *Array;
Array = new int[input.length()];
}
//Prepare to store chars
else if (flag == 2) {
char *Array;
Array = new char[input.length()];
}
Can anyone shed some light on this?
Declare Array before if. And you can't declare array of different types as one variable, so I think you should use to pointers.
int *char_array = nullptr;
int *int_array = nullptr;
//Prepare to store integers
if (flag == 1) {
int_array = new int[input.length()];
}
//Prepare to store chars
else if (flag == 2) {
char_array = new char[input.length()];
}
if (char_array)
{
//do something with char_array
}
else if (int_array)
{
//do something with int_array
}
Also as j_random_hacker points, you might want to change you program design to avoid lot's of if
While you are right that since you dynamically allocated them on the heap, the memory won't be released to the system until you explicitly delete it (or the program ends), the pointer to the memory falls out of scope when the block it was declared in exits. Therefore, your pointer(s) need to exist at a wider scope if they will be used after the block.
The memory remains allocated (i.e. taking up valuable space), there's just no way to access it after the closing }, because at that point the program loses the ability to address it. To avoid this, you need to assign the pointer returned by new[] to a pointer variable declared in an outer scope.
As a separate issue, it looks as though you're trying to allocate memory of one of 2 different types. If you want to do this portably, you're obliged to either use a void * to hold the pointer, or (less commonly done) a union type containing a pointer of each type. Either way, you will need to maintain state information that lets the program know which kind of allocation has been made. Usually, wanting to do this is an indication of poor design, because every single access will require switching on this state information.
If I understand your intend correctly what you are trying to do is: depending on some logic allocate memory to store n elements of either int or char and then later in your function access that array as either int or char without the need for a single if statement.
If the above understanding is correct than the simple answer is: "C++ is a strong-typed language and what you want is not possible".
However... C++ is also an extremely powerful and flexible language, so here's what can be done:
Casting. Something like the following:
void * Array;
if(flag1) Array = new int[len]
else Array = new char[len];
// ... later in the function
if(flag) // access as int array
int i = ((int*)Array)[0];
Yes, this is ugly and you'll have to have those ifs sprinkled around the function. So here's an alternative: template
template<class T> T foo(size_t _len)
{
T* Array = new T[_len];
T element = Array[0];
return element;
}
Yet another, even more obscure way of doing things, could be the use of unions:
union int_or_char {int i; char c;};
int_or_char *Array = new int_or_char[len];
if(flag) // access as int
int element = Array[0].i;
But one way or the other (or the third) there's no way around the fact that the compiler has to know how to deal with the data you are trying to work with.
Turix's answer is right. You need to keep in mind that two things are being allocated here, The memory for the array and the memory when the location of the array is stored.
So even though the memory from the array is allocated from the heap and will be available to the code where ever required, the memory where the location of the array is stored (the Array variable) is allocated in the stack and will be lost as soon as it goes out of scope. Which in this case is when the if block end. You can't even use it in the else part of the same if.
Another different code suggestion from Andrew I would give is :
void *Array = nullptr;
if (flag == 1) {
Array = new int[input.length()];
} else if (flag == 2) {
Array = new char[input.length()];
}
Then you can directly use if as you intended.
This part I am not sure : In case you want to know if its an int or char you can use the typeid literal. Doesn't work, at least I can't get it to work.
Alternatively you can use your flag variable to guess what type it is.