currently I am doing the following:
enum TC_ID {
CMD01 = 'C'*'M'*'D'*'0'*'1',
CMD02 = 'C'*'M'*'D'*'0'*'2',
..
};
Which works, but is going to be quite effortfull for a whole lot of commands :D
So, I am looking for a Macro, or inline function or something else which multiplies all the chars of a char array/string with a fixed size, so that I don't have to type them in manually in my code.
Is something like this possible?
Some unnecessary but maybe interesting information:
Well, this looks kinda stupid, why am I doing this you might ask ;)
My goal is to use this enum in a switch statement, which in the end is used to execute telecommands for my project.
The size of my telecommands is always 5.
So I am calculating some kind of very simple hash value which will be used inside the switch statement:
char *id // contains the Telecommand as a string
TC_ID hash = static_cast<TC_ID>(id[0]*id[1]*id[2]*id[3]*id[4]);
switch (hash) {
case (CMD01):
// execute funtion..
break;
case (CMD02):
// do something else
break;
default:
// unknown command
}
I know that instead of a switch I could just use a lot of if else statements and strcmp, but I don't want to because it's ugly :D
EDIT: Also, using an appropriate hash function would be much better.
However, how can this be implemented in an enumeration, so that I can still use my switch statement for the commands?
I think what I want is basically some kind of hash table which I can generate at the start for all command words and then make a switch over all of them.. but just how?
EDIT2: My compiler version is C++98
EDIT3: Workaround solution in comment in answer post
This works (C++11):
constexpr int multChars(const char* s /*string*/, int t = 1 /*tally*/){
return *s ? multChars(s+1, t*(*s)) : t;
};
//--------------------------------------------------------
//test it on a template (won't compile unless N is evaluated at compile time)
#include <iostream>
template<int N>
void printN() { std::cout<<N<<'\n'; }
int main(){
printN<multChars("ab")>();
return 0;
}
The ascii code of 'a' is 97 and the ascii code of 'b' is 98.
This returns 9506 as expected.
Related
This is Arduino code, but I have a feeling my error is with C++ in general and not specific to Arduino. I'm new to pointers and strings, so I probably am doing something wrong in that regard.
This is from a much larger program, but I've whittled it down to as little code as I can where I can still reproduce the bug.
It should just iterate through the letters of text[] and save each letter into newText[0][0], as well as print newText[0][0] and the counter variable i.
void setup() {
Serial.begin(9600);
}
void loop() {
const char text[] = "chunk";
static char newText[][10] = {};
static unsigned int i=0;
static int code = 0;
if(code == 0){
newText[0][0] = text[i]; //This
Serial.print(i);
Serial.println(newText[0][0]); //This
i++;
if(i>=strlen(text)){
code=1;
}
}
}
But as I have the code, i jumps to some number like 104 by the second iteration, when it should be equal to 1. (The exact value varies depending on how exactly the code looks.) If I comment out either of the lines that have the comment //This, then the counter works fine. Also, if I switch Serial.print(i); and the line before it, then it counts fine.
static char newText[][10] = {};
This creates a zero sized array (to be more precise a matrix of 0 rows and 10 columns). This would be illegal in C++ but gcc has an extension to allow it. Nevertheless even with gcc's extension, it's UB when you access newText[0][0] which is outside the size of the array. When you have UB anything can happen, the program can appear to work as you expect, it can print gibberish, it can crash, etc., literally anything.
So you need to declare a size that accommodates all your accesses, e.g.:
static char newText[1][10] = {};
if you only want 1 row (but in this case you don't need a matrix, a one dimension array would do fine).
Tip: use the String class for strings instead of raw arrays.
I would like to know if there is any clever trick how to safely convert integer into enum. Before you vote that this is duplicate, I'm not asking about how to convert (int i; Enum e = static_cast<Enum>(i) is easy). I'm asking how to do it safely, verifying that resulting value really is in the enum.
Following code
enum class E {
A = 1,
B = 2
};
int main(int, char **) {
int i = 3;
E e = static_cast<E>(i);
}
will compile (AFAIK) but e will not contain valid value from the enum. Best way I came up with is something like
switch (i) {
case 1:
return E::A;
case 2:
return E::B;
default:
throw invalid_argument("");
}
which 1) doesn't look very smart 2) doesn't scale so well. I could probably put together some macros to make this easier but it still looks dumb.
So is there any "standard" way to do it?
Thanks
If you do not have to convert the numeric value as well, I'd suggest something like
switch (i)
{
case static_cast<int>(E::A):
case static_cast<int>(E::B):
return static_cast<E>(i);
default:
throw invalid_argument("");
}
At least that prevents some common mistakes like forgetting to change either the case or the return value or simply looking up the wrong numeric value. Also it's much more refactoring friendly (think about changing the numeric value - after all you define an enum so that you don't have to change the value in more than one place).
Unfortunately that still isn't very nice, but its the best way I know. Well, unless you want to use X macros.
I have found this very useful post and I`d like to clarify something about the compiler optimizations. Lets say we have this function (same like in the original post):
template<int action>
__global__ void kernel()
{
switch(action) {
case 1:
// First code
break;
case 2:
// Second code
break;
}
}
Would the compiler do the optimization in the sense of eliminating an unreachable code even in the case I called the function with template variable unknown in the time of compiling - something like creating two separete functions? E.g.:
kernel<argv[1][0]>();
Short answer: no.
Templates are instantiated and generated purely at compiletime, so you can't use the values in argv, since they are not known at compile time.
Makes me wonder why you did not just give it a try and threw that code at a compiler - it would have told you that template arguments must be compile time constants.
Update:
Since you told us in the comments that it's not primarily about performance, but about readability, i'd recommend using switch/case:
template <char c> void kernel() {
//...
switch(c) { /* ... */ }
}
switch (argv[1][0]) {
case 'a':
kernel<'a'>();
break;
case 'b':
kernel<'b'>();
break;
//...
}
Since the value you have to make the descision on (i.e. argv[1][0]), is only known at runtime, you have to use runtime descision mechanisms. Of those, switch/case is among the fastest, especially if there are not too many different cases (but more than two) and especially if there are no gaps between the cases (i.e. 'a', 'b', 'c', instead of 1, 55, 2048). The compiler then can produce very fast jumptables.
Being new to templates I`d had to study some essential matters. Finally I came up with the solution to my problem. If I want to call functions with template parameters depending on command line arguments I should do it like this:
if(argv[1][0] == '1')
kernel<1><<< ... >>>();
if(argv[1][0] == '2')
kernel<2><<< ... >>>();
I also checked ptx file of such program and found out that compiler makes in this case optimization producing two different kernel functions without switch statement.
My code that I have is quite large and complicated so I won't waste your time reading it, but you're going to have to make certain assumtions about variables in it as a result. I will tell you the values of the variables which I have confirmed in the debugger so you know with certainty. Know that I have omitted a lot of unrelated code in here so what you see isn't everything but I have included everything that is relevant.
// This is defined in a class:
char**** m_DataKeys;
// This is in a member function of the same class:
m_DataKeys = new char*** [m_iNumOfHeroes]; // m_iNumOfHeroes = 2
while ( pkvHero )
{
// iHeroNum = 0 and then 1 #define NUM_OF_ABILITIES 4
m_DataKeys[iHeroNum] = new char** [NUM_OF_ABILITIES];
for (int ability = 0; ability < NUM_OF_ABILITIES; ability++)
{
if (pkvExtraData) // only is true when iHeroNum == 1 and ability == 0
{
// iNumOfExtraData == 2
m_DataKeys[iHeroNum][ability] = new char* [iNumOfExtraData];
while ( pkvSubKey )
{
// iCurExtraDataNum increments from 0 to 2
m_DataKeys[iHeroNum][ability][iCurExtraDataNum] = new char [50];
I put a break point on the line
m_DataKeys[iHeroNum] = new char** [NUM_OF_ABILITIES];
Before the line is called and when iHeroNum == 0 the m_DataKeys array looks like:
m_DataKeys | 0x02072a60
pointer | 0xffeeffee
Error : expression cannot be evaluated
Which is expected. After the line gets called it looks like:
m_DataKeys | 0x02072a60
pointer | 0x02496b00
pointer | 0xffeeffee
Error : expression cannot be evaluated
Which seems to look correct. However, since I set a breakpoint there, I hit play and had it hit it on the next loop around, where iHeroNum == 1 now and ran the line and m_DataKeys then looked like this:
m_DataKeys | 0x02072a60
pointer | 0x02496b00
pointer | 0xffeeffee
Error : expression cannot be evaluated
Which is the exact same as before! The line didn't change the array.... At all!
For clarification, m_DataKeys is a 3 dimensional array of character pointers to character arrays of size 50.
I can't figure out why this is happening, it looks like my code is correct. Is it possible that the garbage collector is screwing me over here? Or maybe the new allocator?
Edit: A Symptom of a Larger Problem
Let me elaborate a little more on the structure of my code, because really, this is just a cheap solution to a bigger problem.
I already have structs as one of you wisely suggested:
struct HeroData
{
// Lots o data here
// ...
// .
//
AbilityData* Abilities[NUM_OF_ABILITIES];
}
struct AbilityData
{
// More data here
// ...
// .
CUtlMap<char*,int> ExtraData [MAX_ABILITY_LEVELS];
}
Now when it got complicated and I had to do this DataKeys arrays of pointers to arrays of pointers crap is only when the need arose to be loading in some data to a dynamic structure, where both the keys, the values, and the numbers of data are completely dynamic. So I thought to use a map of char arrays to ints, but the only problem is that I can't store the actual char array in my map, I have to use a char *. I tried defining the map as:
CUtlMap<char[50],int> ExtraData [MAX_ABILITY_LEVELS];
But that really didn't work and it seems sort of strange to me anyway. So, I had to find some place to stick all these ExtraDataKeys and for some reason I thought it cool to do it like this. How can I store char arrays in objects like arrays or maps?
Since you are using pointers as class members, my best guess is that you are violating The Rule Of Three. That is, you did not provide a copy constructor and a copy assignment operator for your class. That usually leads to strange data loss when passing objects of your class around.
Note that no sane C++ programmer would use char****. Here is my best attempt to fix your problem using vectors and strings, but there is probably a much better design for your specific problem:
#include <string>
#include <vector>
class Foo
{
int m_iNumOfHeroes;
std::vector<std::vector<std::vector<std::string> > > m_DataKeys;
enum { NUM_OF_ABILITIES = 4, iNumOfExtraData = 2 };
public:
explicit Foo(int iNumOfHeroes)
: m_iNumOfHeroes(iNumOfHeroes)
, m_DataKeys(m_iNumOfHeroes, std::vector<std::vector<std::string> >
(NUM_OF_ABILITIES, std::vector<std::string>(iNumOfExtraData)))
{
}
};
int main()
{
Foo x(2);
}
In case you have never seen that colon syntax in the constructor before, that is a member initializer list.
I really wish C++ had array bounds checking
std::vector and std::string do have bounds checking if you use the foo.at(i) syntax instead of foo[i]. In Debug mode, even foo[i] has bounds checking enabled in Visual C++, IIRC.
Though the code might be correct, I personally find that working with something like a char **** can get pretty confusing pretty fast.
This is just my personal preference, but I always try to organize things in the most clear and unambiguous way I can, so what I would do in your situation would be something like
struct Ability
{
char extraData[NUM_OF_EXTRA_DATA][50];
};
struct HeroData
{
Ability abilities[NUM_OF_ABILITIES];
};
class Foo
{
// here you can choose a
HeroData *heroArray;
// and then you would alloc it with "heroArray = new HeroData[m_iNumOfHeroes];"
// or you can more simply go with a
std::vector<HeroData> heroVector;
};
I think this makes things more clear, making it easier for you and other programmers working on that code to keep track of what is what inside your arrays.
I think you expect the wrong thing to happen (that the visual display in the debugger would change), even though your code seems correct.
Your debugger displays m_DataKeys, *m_DataKeys and **m_DataKeys, which is the same as m_DataKeys, m_DataKeys[0] and m_DataKeys[0][0]. When you change m_DataKeys[1], you are not going to notice it in your debugger output.
The following might help you: in my debugger (MS Visual Studio 2005), if you enter e.g. m_DataKeys,5 as your watch expression, you will see the first 5 elements of the array, that is, m_DataKeys[0], m_DataKeys[1], ..., m_DataKeys[4] - arranged in a neat table. If this syntax (with the ,5) doesn't work for you, just add m_DataKeys[1] into the debugger's watch window.
Not sure why this didn't occur to me last night, but I was pretty tired. Heres what I decided to do:
struct AbilityData
{
// Stuff
CUtlMap<char*,int> ExtraData [MAX_ABILITY_LEVELS];
char **DataKeys;
}
Thats what my abilityData struct now looks like, and it now works, but now I want to reorganize it to be like:
struct AbilityData
{
// Stuff
CUtlMap<char*,int[MAX_ABILITY_LEVELS]> ExtraData;
char **DataKeys;
}
Because it makes more sense that way, but then I run into the same problem that I had before with the char array. It almost seems like to me it might just be best to ditch the whole map idea and make it like:
struct AbilityData
{
// Stuff
int *ExtraData;
char **DataKeys;
}
Where ExtraData is now also a dynamically allocated array.
The only problem with that is that I now have to get my data via a function which will loop through all the DataKeys, find a matching key for my input string, then return the ExtraData associated with it.
In the following two versions of switch case, I am wondering which version is efficient.
1:
string* convertToString(int i)
{
switch(i)
{
case 1:
return new string("one");
case 2:
return new string("two");
case 3:
return new string("three");
.
.
default:
return new string("error");
}
}
2:
string* convertToString(int i)
{
string *intAsString;
switch(i)
{
case 1:
intAsString = new string("one");
break;
case 2:
intAsString = new string("two");
break;
case 3:
intAsString = new string("three");
break;
.
.
default:
intAsString = new string("error");
break;
}
return intAsString;
}
1: has multiple return statements will it cause compiler to generate extra code?
This is a premature optimization worry.
The former form is clearer and has fewer source lines, that is a compelling reason to chose it (in my opinion), of course.
You should (as usual) profile your program to determine if this function is even on the "hot list" for optimization. This will tell you if there is a performance penalty for using break.
As was pointed out in the comments, it's very possible that the main performance culprit of this code is the dynamically allocated strings. Generally, when implementing this kind of "integer to string" mapping function, you should return string constants.
Both are.
What you should really be concerned about is your use of pointers here. Is it necessary? Who will delete these strings? Isn't there a simpler alternative?
There should be no difference in the compiled code.
However:
You'll probably find returning the strings by value to be more efficient.
If there are a lot of strings consider prepopulating a vector with them (or declare a static array) and use i as the index in.
A switch statement is basically a series of if statements as generated machine instructions. One simple optimization strategy is to place the most frequent case first in the switch statement.
I also recommend the same solution as Sebastian but without the assert.
static const char *numberAsString[] = {
"Zero",
"One",
"Two",
"Three",
"Four",
"Five",
"Six",
};
const char *ConvertToString(int num) {
if (num < 1 || num >= (sizeof(numberAsString)/sizeof(char*)))
return "error";
return numberAsString[num];
}
You can never know how optimization will influence the code produced unless you compile with a specific compiler version, a specific set of settings and a specific code base.
C++ optimizing compilers may decide to turn your source code upside down to gain a specific optimization only available for compiler architecture so-and-so without you ever knowing it. A powerful optimizing compiler may e.g. find out that only 2 out of 10 cases are ever needed and will optimize away the whole switch-case-statement.
So my answer to your question is: Mu.
If you turn optimizing on, both functions will very likely generate equivalent code.
The compiler most probably will optimize both versions to the same code.
They will almost certainly both be compiled to an identical, highly-efficient branch table. Use whichever one you feel is clearer.
I would suggest something of the form:
void CScope::ToStr( int i, std::string& strOutput )
{
switch( i )
{
case 1:
strOutput = "Some text involving the number 1";
... etc etc
}
By returning a pointer to a string created on the heap, you risk memory leaks. Specifically regarding your question, I would suggest that the least number of return paths is more advisable than premature optimisation.
Consider keeping the strings as static constants:
static char const g_aaczNUMBER[][] =
{
{"Zero"}, { "One" }, ...
};
static char const g_aczERROR[] = { "Error" };
char* convertIntToString(int i) const {
return i<0 || 9<i ? g_aczERROR : g_aaczNUMBER[i];
}
You optimise[*] switch statements by doing as little work as possible in the switch (because it's uncertain whether the compiler will common up the duplication). If you insist on returning a string by pointer, and using a switch statement, I'd write this:
string *convertToString(int i) {
const char *str;
switch(i) {
case 1 : str = "one"; break;
// etc
default : str = "error"; break;
}
return new string(str);
}
But of course for this example I'd probably just use a lookup table:
const char *values[] = {"error", "one", ... };
string convertToString(unsigned int i) {
if (i >= sizeof(values)/sizeof(*values)) i = 0;
return values[i];
}
That said, I just answered a question about the static initialization order fiasco, so you don't in general want rules of thumb which demand globals. What you do has to depend on the context of the function.
[*] Where I mean the kind of rule-of-thumb optimisation that you do when writing portable code, or in your first version, in the hope of creating code that is clear to read and won't need too much real optimisation. Real optimisation involves real measurements.
There won't be any difference in efficiency here. Certainly none that will matter. The only benefit of going with option #2 is if you'll need to do some post-processing of the string that applies to all cases.
There should not be any measurable difference, return statements should not generate any machinery. They should put a pointer to the string object (allocated on the heap) on the stack of the callsite.
The funny part is you worry about efficieny of break then return but make a new string every time.
The answer is it's up to the compiler, but it should not matter either way. Avoiding the new string will if you call this all the time.
The switch can often be optimized so that it performs a jump instead of a bunch of if else, but if you look in the assembly source you'll generally be underwhelmed by how little the optimizer does.