What's the best way if I want to make sure that every parameter that's passed to the setX() method is a positive number?
For example:
a.setX(32); // I don't need to worry about if 32 is less than 0
if(a.getY()-64 > 0)
{
b.setX(a.getY()-64); // But I have to check if a variable will be less than 0
}
Can I make a few changes in the setX() method by adding an if statement there? But modifying a function in a third-party library is not a good idea, is it? Is there a way to achieve this without touching the library?
Of course I can manually make sure that the argument is a positive value every time I call this function. But this sounds even worse. I'll probably call this function very frequently and I can't just do something to check the value every time before I call this function. What's the best way then?
Why don't you simply create your own function and make sure you only call this one and never the original one:
inline void MySetX( TheClass& a, int value )
{
if ( value >= 0 )
{
a.setX( value );
}
else
{
// Do your error handling, throw exception, assert, or whatever
}
}
Then, replace all your a.setX( i ) by MySetX( a, i )
Related
I have a function which processes data that comes as a sequence. Because of this, I need to know the value of certain variables from the last function call during the current function call.
My current approach to doing this is to use static variables. My function goes something like this:
bool processData(Object message){
static int lastVar1 = -1;
int curVar1 = message.var1;
if (curVar1 > lastVar1){
// Do something
}
lastVar1 = curVar1;
}
This is just a small sample of the code; in reality I have 10+ static variables tracking different things. My gut tells me using so many static variables probably isn't a good idea, though I have nothing to back that feeling up.
My question: Is there a better way to do this?
An alternative I've been looking into is using an object whose fields are lastVar1, lastVar2, etc. However, I'm not sure if keeping an object in memory would be more efficient than using static variables.
Your question has a taste of being purely about style and opinions, though there are aspects that are not a matter of opinion: multithreading and testing.
Consider this:
bool foo(int x) {
static last_val = -1;
bool result = (x == last_val);
last_val = x;
return result;
}
You can call this function concurrently from multiple threads but it wont do the expected. Moreover you can only test the function by asserting that it does the right thing:
foo(1);
assert( foo(1) ); // silenty assumes that the last call did the right thing
To setup the preconditions for the test (first line) you already have to assume that foo(1) does the right thing, which somehow defeats the purpose of testing that call in the second line.
If the methods need the current object and the previous object, simply pass both:
bool processData(const Object& message,const Object& previous_message){
if (message.var1 > previous_message.var1){
// Do something
return true;
}
return false;
}
Of course this just shifts the issue of keeping track of the previous message to the caller, though thats straight-forward and requires not messing around with statics:
Object message, old_message;
while ( get_more( message )) {
processData(message, old_message);
old_message = message;
}
I often use -1 as the invalid value type when returning from a function, where the input yields incorrect output. For instance, writing an indexing function where the index is out of bounds, instead of throwing an exception, -1 can be returned. But when writing a function that has negative values as possible return types, this technique does not work. What is the correct way to return an invalid type value in such instances?
The technique I use mostly is to set the return type to be of type *int, and return a Pointer to NULL. But, that requires all return values to be of a pointer type, which seems like an extra overhead to the function. Is there an accepted standard for returning values in such cases?
In newer C++, I'd suggest using std::optional<>; if you don't yet have it, boost::optional<>.
One option would be to let your function take a bool& as an output parameter used to indicate if the returned value is valid.
int myFunc(bool& valid); // sets 'valid' to true if result is usable, false otherwise
Users can then do
bool valid = false;
Int result = myFunc(valid);
if (!valid) {
// Handle error
}
// Use result
Not the most pretty solution, but it does the job.
Apart from the answer I provided above, there's a very clean, continuation-passing solution (given you're non-virtual):
template<typename Success, typename Failed>
void parse( const std::string& str, Success s, Failed f )
{
auto a = start_parse(str);
if( a.problem() )
return f(); // you _might_ have an error code here
s( finish_parse(str, a) );
}
Then you might customize by:
Success:
[&i] (int i_) { i = i_; }
out(i), where out(int& output_) returns the above lambda for output_
actual code doing something useful
function to continue with
Failed:
[&i]{ i = 0; }, `[&i]{ i = nullopt; }, or any other default value
[] { throw MyFavouriteException(); }
retry logic
std::terminate()
[]{} if you don't care (or if you're 100% sure it'll succeed)
It might look a little verbose, but IMHO:
it's trivial to read
any other schematics can be mimicked, even if there's no default c'tor
easy to change as well
'you don't pay for what you don't use', can surely be optimized away
every schematic is visible and apparent from code:
for default value, caller sets it, not callee or global
std::optional<> and default value are handled the same
for exception, caller knows better what to throw
for no action, you don't have to lookup the implementation to know this
for std::terminate(), well, you know what to expect
if you 'speak' CPS, you might actually continue and save an if / catch / etc.
The only issue I see is constructor initializer lists. Any thoughts on this?
I would like to log the return value of a function. The problem is that the function might have many exit points and I don't want to add a log call before every one of them.
I thought about having an inner object that's responsible on making the Log call. But still, I would have to notify it about the return value before each return statement.
I also thought about creating a macro that calls the logger before returning from the function. Something like:
#define RETURN(ret) Logger.log(__FUNCTION__, ret); return ret;
But I want to avoid doing that.
Any other thoughts on how I can achieve that nicely and easily?
Thanks
I don't think you can do that more nicely and easily. In this case I think the solution with least impact on the source is to use the preprocessor, but you shouldn't do it the way you do because it has surprices built in. Fx:
if( done )
RETURN(something);
expands to:
if( done )
Logger.log("function_name", something); return something;
which means that something is sent to the log if done is true, then something is returned anyway.
To make the expansion fit into a single statement it's normally wrapped in a do { ... } while(0) which would make that example log and return only if done is true.
But there's still a surprise since the macro argument is expanded twice, consider the case where you write RETURN(something++); then it will expand to Logger.log(__FUNCTION__, something++); return something++; which means unfortunate side effects. This was a real problem in C, but not in C++. Here templates are handy:
template<typename T>
T const& log_and_return(char const* func, const T& value)
{
Logger.log(func, value);
return value;
}
#define RETURN(value) return log_and_return(__func__, value)
Note that it is called __func__ in the standard (an not __FUNCTION__).
Is there any way to "force" a function parameter to follow some rule in C++ ?
For the sake of example, let say I want to write a function which computes the n'th derivative of a mathematical function. Let suppose the signature of the function is this one :
double computeNthDerivative(double x, unsigned int n);
Now, let say I want to forbid users to input 0 for n. I could just use an assert or test the value and throw an exception if the user input is 0.
But is there any other way of doing this kind of stuff ?
Edit : Conditions would be set at compile time, but the check must be done at the run-time.
You can prevent the use of 0 at compile time, using templates.
template <int N>
double computeNthDerivative(double x)
{
// Disallow its usage for 0 by using static_assert.
static_assert(N != 0, "Using 0 is not allowed");
// Implement the logic for non-zero N
}
To prevent the use of the function for 0 at run time, it's best to throw an exception.
double computeNthDerivative(double x, unsinged int n)
{
if ( n == 0 )
{
throw std::out_of_range("Use of the function for n = 0 is not allowed.");
}
// Implement the logic for non-zero n
}
class Policy {
private:
String myPolicy;
public :
Policy(String regEx) : myPolicy(regEx) {
}
void verify(int n) {
regEx strtok , sprintf, blah, blah n
};
class Asserted {
private:
Policy policy;
public:
Asserted(Policy policy, int n) throw AAAHHHHH {
policy.verify(n);
}
};
Then finally
Asserted assert = new Asserted(Policy("[1-9]", 8))
double computeNthDerivative(2.6, assert);
I think the best way here is to throw an exception. This is what exceptions are for, even the name seems to suggest this.
As to the assert macro, there is one important caveat. If you use the assert macro, the program will abort if the assertion is not met. However, if you ever make a release build where the NDEBUG macro is set, all assertions will be removed during compilation. This means that you cannot check for valid user input with this macro (because you should build a release build).
The only rules are that you give in. If users are the ones that you want to restrict, you have to check what they give in.
Same goes for the functions, however in your case what you showed as an example it is better to check the variable after the cin (or whatever imput you prefer) rather than checking it in the function itself. For this i would just go
if n!=0;
your function
else break;
So if you are looking for a "Policy" based solution you could create a separate class which accepts a defining regular expression (or whatever you define as a policy) and the input, in this case n, which would then be used as the input to your function.
I have a setup that looks like this.
class Checker
{ // member data
Results m_results; // see below
public:
bool Check();
private:
bool Check1();
bool Check2();
// .. so on
};
Checker is a class that performs lengthy check computations for engineering analysis. Each type of check has a resultant double that the checker stores. (see below)
bool Checker::Check()
{ // initilisations etc.
Check1();
Check2();
// ... so on
}
A typical Check function would look like this:
bool Checker::Check1()
{ double result;
// lots of code
m_results.SetCheck1Result(result);
}
And the results class looks something like this:
class Results
{ double m_check1Result;
double m_check2Result;
// ...
public:
void SetCheck1Result(double d);
double GetOverallResult()
{ return max(m_check1Result, m_check2Result, ...); }
};
Note: all code is oversimplified.
The Checker and Result classes were initially written to perform all checks and return an overall double result. There is now a new requirement where I only need to know if any of the results exceeds 1. If it does, subsequent checks need not be carried out(it's an optimisation). To achieve this, I could either:
Modify every CheckN function to keep check for result and return. The parent Check function would keep checking m_results. OR
In the Results::SetCheckNResults(), throw an exception if the value exceeds 1 and catch it at the end of Checker::Check().
The first is tedious, error prone and sub-optimal because every CheckN function further branches out into sub-checks etc.
The second is non-intrusive and quick. One disadvantage is I can think of is that the Checker code may not necessarily be exception-safe(although there is no other exception being thrown anywhere else). Is there anything else that's obvious that I'm overlooking? What about the cost of throwing exceptions and stack unwinding?
Is there a better 3rd option?
I don't think this is a good idea. Exceptions should be limited to, well, exceptional situations. Yours is a question of normal control flow.
It seems you could very well move all the redundant code dealing with the result out of the checks and into the calling function. The resulting code would be cleaner and probably much easier to understand than non-exceptional exceptions.
Change your CheckX() functions to return the double they produce and leave dealing with the result to the caller. The caller can more easily do this in a way that doesn't involve redundancy.
If you want to be really fancy, put those functions into an array of function pointers and iterate over that. Then the code for dealing with the results would all be in a loop. Something like:
bool Checker::Check()
{
for( std::size_t id=0; idx<sizeof(check_tbl)/sizeof(check_tbl[0]); ++idx ) {
double result = check_tbl[idx]();
if( result > 1 )
return false; // or whichever way your logic is (an enum might be better)
}
return true;
}
Edit: I had overlooked that you need to call any of N SetCheckResultX() functions, too, which would be impossible to incorporate into my sample code. So either you can shoehorn this into an array, too, (change them to SetCheckResult(std::size_t idx, double result)) or you would have to have two function pointers in each table entry:
struct check_tbl_entry {
check_fnc_t checker;
set_result_fnc_t setter;
};
check_tbl_entry check_tbl[] = { { &Checker::Check1, &Checker::SetCheck1Result }
, { &Checker::Check2, &Checker::SetCheck2Result }
// ...
};
bool Checker::Check()
{
for( std::size_t id=0; idx<sizeof(check_tbl)/sizeof(check_tbl[0]); ++idx ) {
double result = check_tbl[idx].checker();
check_tbl[idx].setter(result);
if( result > 1 )
return false; // or whichever way your logic is (an enum might be better)
}
return true;
}
(And, no, I'm not going to attempt to write down the correct syntax for a member function pointer's type. I've always had to look this up and still never ot this right the first time... But I know it's doable.)
Exceptions are meant for cases that shouldn't happen during normal operation. They're hardly non-intrusive; their very nature involves unwinding the call stack, calling destructors all over the place, yanking the control to a whole other section of code, etc. That stuff can be expensive, depending on how much of it you end up doing.
Even if it were free, though, using exceptions as a normal flow control mechanism is a bad idea for one other, very big reason: exceptions aren't meant to be used that way, so people don't use them that way, so they'll be looking at your code and scratching their heads trying to figure out why you're throwing what looks to them like an error. Head-scratching usually means you're doing something more "clever" than you should be.