enum, classes, namespaces and long names - c++

From what I understand, enums that relates to a class should be declared inside the class, like this:
namespace Sensors {
class MySensor {
public:
enum class SensorStatus {
kSensorActive,
kSensorInactive
}
SensorStatus GetCurrentStatus(void);
};
}
The problem I'm having with this, is that it leads to the following code in another part of the program.
Sensors::MySensor::SensorStatus current_status = mySensor.GetStatus();
switch (current_status):
case Sensors::MySensor::SensorStatus::kSensorActive: // 47 characters!
printf("Sensor is active.");
break;
case Sensors::MySensor::SensorStatus::kSensorInactive: // 49 characters!
printf("Sensor is inactive.");
break;
I appreciate that its very clear what kSensorActive and kSensorInactive refers to, no ambiguity there. But if you try to follow a style guide that specifies 80 characters, we end up with a lot of line breaks, which reduces clarity, IMHO. One example of a long line comes if we have a function that takes two different enumerators; MyFunction(NamespaceA::MyFirstClass::MyFirstEnum::AnEnumerator, NamespaceB::MySecondClass::MySecondEnum::ADifferentEnumerator) - a whopping 127 characters.
Is it common with these long names or am I missing something?

First, you repeat stuff:
The name kSensorActive doesn't have to say Sensor if you already specified that it's a SensorStatus in the name. Or you could remove Sensor from SensorStatus if it's inside MySensor. Maybe both.
The idea behind wrapping things inside classes and namespaces is that you CAN use the same name over and over again, for something that is "the same sort of thing", rather than having completely unique names throughout.
You can also, locally, change the names with using, something like this
using Status = Sensors::MySensor::SensorStatus;
and then us Status::kSensorActive where you previously used the long thing.

To reduce the length without reducing the overall scope clarity you have at least 2 options:
Alias types ie. using Status = Sensors::MySensor::SensorStatus;
A typedef ie. typedef Sensors::MySensor::SensorStatus Status2;
Use these inside the scope of this function so it is local and the ambiguous name doesnt spread throughout the code. Here is a live example.

Related

Select a given namespace at runtime

Say I have these namespaces:
namespace old
{
std::array<std::string,1> characters {"old"};
}
namespace young
{
std::array<std::string,1> characters {"young"};
}
Then I want the user to tell me at the beginning which version is he using. Then call the appropriate namespace throughout the program.
I have tried using namespace depending on input, but it doesn't work because I need to call the correct namespace in functions on other source files. I was thinking maybe can I send the namespace as a function parameter? Or do something clever with templates?
EDIT:
When I refer to "user" I mean somebody that is using my executable, a person playing my game.
What I want to do is to ask him the version he is going to use e.g. US version (things have some names), or UK version (things have other names).
All that changes is the names I use. But I want him to be able to switch between versions every time.
I hope it is clear, please let me know if you need further clarification.
There is no way to pass a namespace as function parameter or template parameter. User may use it as:
using namespace old;
characters[0] = 'O';
or code as:
old::characters[0] = 'O';
UPDATE: After updating original question
Namespaces are relevant during compile-time and do not reflect any behavior in runtime. What you need is more along the lines of:
enum Language
{
ENGLISH_UK, ENGLISH_US
};
std::array<std::string, 2> label = {
"colour", // for British-english
"color" // for US-English
};
And then in the code:
static Language lang = ENGLISH_UK;
std::cout << label[lang] << std::endl;
So, if there is a change in user interface, you do not need to recompile the whole app.
Short answer is no, because what functions are called and what variables are accessed at a particular location in your code when you e.g. write characters is detrmined at compile-time.
The slightly longer answer is that you can create wrapper functions and references in a separate namespace and let them forward to one or the other depending on the user (as long as the types are the same).
E.g.
namespace current {
int namespace_to_use = 1; // can be set by some initialization function in your code
std::array<std::string,1>& get_characters(){
return namespace_to_use == 0 ? old::characters : young::characters;
}
}
I wouldn't call that good application design and there are many more advanced/better versions of this (e.g. based on dynamic polymorphism and the factory pattern or pointers/references). What fits best depends on your needs and your level of expereience.

Is there a way to say the object only once when I have to use it again and again?

Take for example:
int main(void){
numberComparator comparator1;
comparator1.setA(78.321);
comparator1.showA();
comparator1.setB('c');
comparator1.setB("Yes");
comparator1.setB(124.213);
comparator1.showB();
comparator1.setB(12);
return 0;
}
Instead of saying comparator1 over and over again, can I do something shorter?
I understand that this doesn't really change much about how the program works, but it does make it easier to work around with testing a class I make.
I am doing overloading so that for an assortment of inputs into my comparator, my program can handle them without making the results go crazy. In this case, I want the input to be an int, but what if the input isn't?
The answer could be lying around the internet, but as my title may infer, I do not know how to state the question.
You are looking for something like with keyword which is part of, for example, Pascal language.
Unfortunately, C++ doesn't provide similar feature. Using the references, one can shorten the name of the class and somewhat alleviate the pain, i.e.
Comparator comparator1;
...
{
Comparator& cr = comparator1;
cr.a();
cr.b();
cr.c();
}
It depends. If numberComparator has a "fluent" interface, then each member function will return a reference to *this, and you can write:
comparator1
.setA(78.321)
.showA()
.setB('c')
.setB("Yes")
.setB(124.213)
.showB()
.setB(12);
Note that this is a bitch to debug by step-into (you have to step into every function until you get to the one you are interested in).
The alternative of course is "use a shorter name".
int main(void){
numberComparator c1;
c1.setA(78.321);
c1.showA();
c1.setB('c');
c1.setB("Yes");
c1.setB(124.213);
c1.showB();
c1.setB(12);
return 0;
}
There is really no point in having a particularly long name if it is limited in scope to a few lines. For a local variable, if it isn't limited in scope to a few lines, your function is probably too long.

Avoiding non symbolic constants in Qt

One thing that often comes up in code reviews I participate in is 'magic numbers' inline in code as being a bad thing.
The preference is that a symbol be assigned somewhere.
Now what I am working with at the moment is in the QT sdk. The class member QButtonGroup.checkedId() will return -1 as a magic number to signify that there are no radio buttons in the group selected.
And if I write something like
if ( buttongroup->checkedId() == -1 )
{
//yadda yadda
}
it will come up in the code review.
While certainly I can define a const static int symbol to give me that -1, I'd much rather use something in the Qt namespace if it has a relevant constant defined.
Is there such a symbol already defined??
Code reviews are about your code not the code of 3rd party libraries so you can't and shouldn't deal with it. Qt doesn't have any named entity to compare against so you have to compare the resulting code against -1. There is a bright side about it, though: -1 is a broadly understood magic number so there should not be any misunderstanding — it is used in many different languages and libraries. However bad it is it is here and we have to live with it.
No such symbol is predefined; you would have to define it yourself.

Refactoring large case statement, externs, static locals

I'm trying to do some refactoring and wish to figure out the best path forward.
I have
myonce{
static int i //for operation 1
switch(commandid) {
case 1: operation 1
i = 1;
...
where myonce is a function that is called in a loop. This is not my code, I'm trying to make it better. Operation 1 (or each case) is a series of commands, and I want to put them in their own translation units (one function per file).
Since myonce runs in a loop, the original author has many static variables that he uses to keep state, some of these state sets are used across multiple operations. Note that these are not static file scope, they are static block scope.
To keep things simple, as a proof of concept, I want to know if the following is possible.
Consider 1 operation with 1 set of static vars.
main.cpp
myonce {
static int i //for op 1
switch(commandid) {
case 1: operation1();
operation1.cpp
extern int i;
void operation1() {
i = 1;
}
In the case of multiple operations using the same sets of state, I would make a header to declare them all extern.
Currently compilation of this file is counted in minutes, and my first goal is to break it up into smaller compilation units so that the author can work more freely. this refactoring will take a long time, but I mention this as an explanation of my motivation of this approach.
I understand that a static file scope variable is not accessible to other translation units (extern in other files), so I wish to distinguish that this is not the case I'm handling. What I don't know at the moment, is where I should declare operation1() to main, should it be
static int i
extern void operation1();
So that int is declared as visible to the function?
I would appreciate any pointers in this regard. Thanks.
Put the state variables into a struct. Pass this struct to each function.
Example.
// foo.h
struct TheState
{
int x;
char *y;
// ...
};
void func1(TheState &);
void func2(TheState &);
// main.cc
#include "foo.h"
void main_loop()
{
TheState the_state; // initialize this however you want
for (;;)
{
if ( blah) func1(the_state);
else func2(the_state);
}
}
// func1.cc
#include "foo.h"
void func1(TheState &the_state)
{
++the_state.x;
}
No, you can't do that. static objects aren't visible in other source files, ever.
How large is your switch anyway? And what is the reason for modifying it?
Perhaps the original programmer had good reasons for the local, static variables? You say it is called in a loop, and some of the static variables are used to keep state from one iteration to the next, shared among branches of the switch. It is certainly a weird way to structure the code. I can think of doing something like this to run some sort of finite automaton, but in that case I'd write the automaton as a string of snippets of code for each state, and transfer among them by straight gotos. I'd make certain somewhere very near there is a description of the automaton in a more readable form.
But I might be totally off-base. Can you share a bit more about what this code does?
First, switches often are avoidable by creating better data structures with their functions (e.g. classes with a virtual member function command whose implementations do the right thing).
On a less ambitious level you could just pass pointers to the statics which are needed in that particular case to the function so that it can read and modify the state of those variables.
Depending on what the functions do, one could also pass state information as value parameters (copies), let the function do their work depending on that state, receive the results and THEN change global state in the main switch according to the result. The state change then is clearly visible (i.e. no side effects in the functions) and the noisy distracting details are banned to another file.
If each case tends to use many of the static variables then you could put them all in a struct; that change should be doable with a text editor (replace variable name x with mystruct.x etc.). Then each function just gets a pointer to that struct. EDIT: As I said in a comment: Perhaps the commands naturally form groups which are concerned with only parts of the state (e.g. there are commands which only read, others which only write data etc.). Then the global state could be split in corresponding groups of data. Each function only gets to see the data group which concerns it, which limits potential side effects.
But generally spoken the function as it is now seems badly designed/grown over time; working on a large set of static variables means having "side effects" in the code all over -- it's not easy to see what any given portion of code does and how it interacts with others. The information flow is not explicit. Analyzing clusters of data which belong together, organizing them in classes and separating them in files would be one task here, even without any virtual member functions.
As to your last question: The "case functions" you create (operation1(); etc.) need only be known in the file which call them. If they are in one or several separate files you should create a header containing the prototypes.

How do I treat string variables as actual code?

That probably wasn't very clear. Say I have a char *a = "reg". Now, I want to write a function that, on reading the value of a, instantiates an object of a particular class and names it reg.
So for example, say I have a class Register, and a separate function create(char *). I want something like this:
void create(char *s) //s == "reg"
{
//what goes here?
Register reg; // <- this should be the result
}
It should be reusable:
void create(char *s) //s == "second"
{
//what goes here?
Register second; // <- this should be the result
}
I hope I've made myself clear. Essentially, I want to treat the value in a variable as a separate variable name. Is this even possible in C/C++? If not, anything similar? My current solution is to hash the string, and the hash table would store the relevant Register object at that location, but I figured that was pretty unnecessary.
Thanks!
Variable names are compile-time artifacts. They don't exist at runtime. It doesn't make sense in C++ to create a dynamically-named variable. How would you refer to it?
Let's say you had this hypothetical create function, and wrote code like:
create("reg");
reg.value = 5;
This wouldn't compile, because the compiler doesn't know what reg refers to in the second line.
C++ doesn't have any way to look up variables at runtime, so creating them at runtime is a nonstarter. A hash table is the right solution for this. Store objects in the hash table and look them up by name.
This isn't possible. C++ does not offer any facilities to process code at runtime. Given the nature of a typical C++ implementation (which compiles to machine code ahead of time, losing all information about source code), this isn't even remotely feasible.
Like I said in my comment:
What's the point? A variable name is something the compiler, but -most importantly- you, the programmer, should care about. Once the application is compiled, the variable name could be whatever... it could be mangled and senseless, it doesn't matter anymore.
You read/write code, including var-names. Once compiled, it's down to the hardware to deal with it.
Neither C nor C++ have eval functions
Simply because: you only compile what you need, eval implies input later-on that may make no sense, or require other dependencies.
C/C++ are compiled ahead of time, eval implies evaluation at runtime. The C process would then imply: pre-process, compile and link the string, in such a way that it still is part of the current process...
Even if it were possible, eval is always said to be evil, that goes double for languages like the C family that are meant to run reliably, and are often used for time-critical operations. The right tool for the job and all that...
A HashTable with objects that have hash, key, Register, collision members is the sensible thing to do. It's not that much overhead anyway...
Still feel like you need this?
Look into the vast number of scripting languages that are out there. Perl, Python... They're all better suited to do this type of stuff
If you need some variable creation and lookup you can either:
Use one of the scripting languages, as suggested by others
Make the lookup explicitly, yourself. The simplest approach is by using a map, which would map a string to your register object. And then you can have:
std::map<const char*, Register*> table;
Register* create(const char* name) {
Register* r = new Register();
table[name] = r;
return r;
}
Register* lookup(const char* name) {
return table[name];
}
void destroy(const char* name) {
delete table[name];
table.erase(name);
}
Obviously, each time you want to access a variable created this way, you have to go through the call to lookup.