I cant get enum this to work properly on Windows. While compiling on linux it returns expected value, but on windows it returns some random number.
typedef enum wezly {
elektrownie1,
konwencjonalne1,
niekonwencjonalne1,
weglowa1,
jadrowa1,
sloneczna1,
wiatrowa1,
geotermiczna1,
gazowa1,
wodna1,
maremotoryczna1,
maretermiczna1
};
wezly wybor_wezla(string opcja)
{
string bb;
bb = opcja;
if ((bb.compare("[elektrownie]")==0)||(bb.compare("[ELEKTROWNIE]")==0))
return elektrownie1;
else if ((bb.compare("[konwencjonalne]")==0)||(bb.compare("[KONWENCJONALNE]")==0))
return konwencjonalne1;
else if ((bb.compare("[gazowa]")==0)||(bb.compare("[GAZOWA]")==0))
return gazowa1;
else if ((bb.compare("[wodna]")==0)||(bb.compare("[WODNA]")==0))
return wodna1;
// (and so on...)
}
int main()
{
cout << wybor_wezla("[gazowa]");
}
When on linux i get 7, on windows its some random number....
Why can that be ?
It's actually broken here (after looking at the link you gave in the comments):
bb=opcja.substr((opcja.find_first_of("[")),(opcja.find_first_of("]"))-1);
This results in extracting a string like "[whateve" if the input is "... [whatever] ...".
What I think you mean is:
bb=opcja.substr((opcja.find_first_of("[")),(opcja.find_first_of("]"))-opcja.find_first_of("[")+1);
Which results in extracting a string like "[whatever]" from the input.
The original code, given the input "[gazowa]", will compare "[gazow" to various strings, none will match, and the end of the function will be reached without hitting a return statement.
This results in undefined behaviour. Hence your result of 7 on linux, and some other value on windows, when [gazowa] ought to give you 8.
You also need to do something more sensible to handle the case where none of your strings are matched, i.e. if the end of wybor_wezla is reached. What you do in that case is up to you, but as a start I'd at least put a print statement in there so you know when nothing's matched.
Your code is missing a final else clause:
wezly wybor_wezla(string opcja)
{
if(...)
return ...;
else if(...)
return ...;
else if(...)
return ...;
// No final else!
}
When none of the if clauses are true, it falls off the end of the function without returning a value, which is Undefined Behavior. In this case, it's returning a garbage value, but worse stuff could happen.
Your first action should be to add a final else clause. This can return a default value, an error code, throw an exception, abort(), etc., but it cannot do nothing. If you know the value has to be one of a limited set of things, you could change the final else if into just an else and assume that if it's not the first N-1 things, it's the Nth thing.
Once you've done that, you need to figure out why your data isn't falling into one of the expected cases and fix that.
Related
I've been using C/C++ for about three years and I can't believe I've never encountered this issue before!
This following code compiles (I've just tried using gcc):
#include <iostream>
int change_i(int i) {
int j = 8;
return j;
}
int main() {
int i = 10;
change_i(10);
std::cout << "i = " << i << std::endl;
}
And, the program prints i = 10, as you might expect.
My question is -- why does this compile? I would have expected an error, or at least a warning, saying there was a value returned which is unused.
Naively, I would consider this a similar case to when you accidentally forget the return call in a non-void function. I understand it's different and I can see why there's nothing inherently wrong with this code, but it seems dangerous. I've just spotted a similar error in some very old code of mine, representing a bug which goes back a long time. I obviously meant to do:
i = change_i(10);
But forgot, so it was never changed (I know this example is silly, the exact code is much more complicated). Any thoughts would be much appreciated!
It compiles because calling a function and ignoring the return result is very common. In fact, the last line of main does so too.
std::cout << "i = " << i << std::endl;
is actually short for:
(std::cout).operator<<("i =").operator<<(i).operator<<(std::endl);
... and you are not using the value returned from the final operator<<.
Some static checkers have options to warn when function returns are ignored (and then options to annotate a function whose returns are often ignored). Gcc has an option to mark a function as requiring the return value be used (__attribute__((warn_unused_result))) - but it only works if the return type doesn't have a destructor :-(.
Ignoring the return value of a function is perfectly valid. Take this for example:
printf("hello\n");
We're ignoring the return value of printf here, which returns the number of characters printed. In most cases, you don't care how many characters are printed. If compilers warned about this, everyone's code would show tons of warnings.
This actually a specific case of ignoring the value of an expression, where in this case the value of the expression is the return value of a function.
Similarly, if you do this:
i++;
You have an expression whose value is discarded (i.e. the value of i before being incremented), however the ++ operator still increments the variable.
An assignment is also an expression:
i = j = k;
Here, you have two assignment expressions. One is j = k, whose value is the value of k (which was just assigned to j). This value is then used as the right hand side an another assignment to i. The value of the i = (j = k) expression is then discarded.
This is very different from not returning a value from a non-void function. In that case, the value returned by the function is undefined, and attempting to use that value results in undefined behavior.
There is nothing undefined about ignoring the value of an expression.
The short reason it is allowed is because that's what the standard specifies.
The statement
change_i(10);
discards the value returned by change_i().
The longer reason is that most expressions both have an effect and produce a result. So
i = change_i(10);
will set i to be 8, but the assignment expression itself also has a result of 8. This is why (if j is of type int)
j = i = change_i(10);
will cause both j and i to have the value of 8. This sort of logic can continue indefinitely - which is why expressions can be chained, such as k = i = j = 10. So - from a language perspective - it does not make sense to require that a value returned by a function is assigned to a variable.
If you want to explicitly discard the result of a function call, it is possible to do
(void)change_i(10);
and a statement like
j = (void)change_i(10);
will not compile, typically due to a mismatch of types (an int cannot be assigned the value of something of type void).
All that said, several compilers (and static code analysers) can actually be configured to give a warning if the caller does not use a value returned by a function. Such warnings are turned off by default - so it is necessary to compile with appropriate settings (e.g. command line options).
I've been using C/C++ for about three years
I can suppose that during these three years you used standard C function printf. For example
#include <stdio.h>
int main( void )
{
printf( "Hello World!\n" );
}
The function has return type that differs from void. However I am sure that in most cases you did not use the return value of the function.:)
If to require that the compiler would issue an error when the return value of a function is not used then the code similar to the shown above would not compile because the compiler does not have an access to the source code of the function and can not determine whether the function has a side effect.:)
Consider another standard C functions - string functions.
For example function strcpy is declared like
char * strcpy( char *destination, const char *source );
If you have for example the following character arrays
char source[] = "Hello World!";
char destination[sizeof( source )];
then the function usually is called like
strcpy( destination, source );
There is no sense to use its return value when you need just to copy a string. Moreover for the shown example you even may not write
destination = strcpy( destination, source );
The compiler will issue an error.
So as you can see there is sense to ignore sometimes return values of functions.
For your own example the compiler could issue a message that the function does not have a side effect so its call is obsolete. In any case it should issue a message that the function parameter is not used.:)
Take into account that sometimes the compiler does not see a function definition that is present in some other compilation unit or in a library. So the compiler is unable to determine whether a function has a side effect,
In most cases compilers deal with function declarations. Sometimes the function definitions are not available for compilers in C and C++.
I have a bunch of code roughly equivalent to this:
bool test(double e, short a, short b, short c) {
// Things being calculated here...
cout << "debug_3" << endl;
return (1 - abs(cos_th)) < (1 - cos(e));
}
int main() {
// something...
cout << "debug_0" << endl;
if(test(e,1,2,0)) {
cout << "debug_4" << endl;
// Bunch of useful operations...
}
// something...
}
Running the code generates the output:
debug_3
After which the program crashes (displaying "The program has stopped working..." in Windows). I have never encountered crashing at value return and I don't know what causes it or how I could fix it. Any thoughts on the issue?
EDIT: Some more info:
In my builds I also verify that the values of cos_th and e are valid.
People seem to point to the second something as the source of problems but my problem seems resolved (i.e. no crashes) when I get rid of the if-statement with a call to test()...
The only things we can fix without knowing what system is, is to change the type of a b and c to unsigned short since they are just array indexes, and make sure they are within array bounds. You might also need to make sure this is not zero since you divide by the result:
sqrt((Xca*Xca+Yca*Yca+Zca*Zca)*(Xba*Xba+Yba*Yba+Zba*Zba))
Use cerr instead of cout to make sure the output is flushed but you still don't see debug 4.
Put more output inside an else condition or after the if: maybe the function returns false?
If you can't locate the error precisely, use a debugger.
Crash at return usually means that your function overwrites stack (and thus the return address) and your program jumps to nowhere. You can verify this by stepping instruction by instruction at the disassembly level.
this is probably a very noob question but I was what the result of this would be:
int someVariable = 1;
while (callFunction(someVariable));
if (someVariable = 1) {
printf("a1");
} else {
printf("a2");
}
callFunction (int i) {
while (i< 100000000) {
i++;
}
return 0;
}
so when you hit the while loop
while (callFunction(someVariable));
does a thread wait at that loop until it finishes and then to
if(someVariable == 1) {
printf("a1");
} else {
printf("a2");
}
or does it skip and move to the if condition, print "a2" and then after the loop has finished goes through the if condition again?
UPDATE: This isn't ment to be valid c code just psuedo, maybe I didn't word it right, basically what I'm trying to figure out is what the different between a loop like while (callFunction(someVariable)); is vs
while (callFunction(someVariable)){}
i also changed the bolded part in my code i.e ** int someVariable = 1; **, I was doing an endless loop which wasn't my intention.
The code inside a function is executed sequentially, by a single thread. Even if you send an other thread to your function it will execute it sequentually as well.
This is true to 99% of programming languages now days.
UPDATE
basically what I'm trying to figure out is what the different between a loop like while (callFunction(someVariable)); is vs while (callFunction(someVariable)){}
No practical difference. ; delimits an empty statement, { } is a scope without statements. Any compiler can be expected to produce identical code.
Of course, if you want to do something in each iteration of the loop, { } creates a "scope" in which you can create types, typedefs and variables as well as call functions: on reaching the '}' or having an uncaught exception, the local content is cleaned up - with destructors called and any identifiers/symbols use forgotten as the compiler continues....
ORIGINAL ANSWER
This...
callFunction(int i){
while (i< 100000000){
i++;
}
return 1;
}
...just wastes a lot of CPU time, if the compiler's optimiser doesn't remove the loop on the basis that it does no externally-visible work - i.e. that there are no side-effects of the loop on the state of anything other that "i" and that that's irrelevant because the function returns without using i again. If always returns "1", which means the calling code...
while (callFunction(someVariable));
...is equivalent to...
while (1)
;
...which simply loops forever.
Consequently, the rest of the program - after this while loop - is never executed.
It's very hard to guess what you were really trying to do.
To get better at programming yourself - understanding the behaviour of your code - you should probably do one or both of:
insert output statements into your program so you can see how the value of variables is changing as the program executes, and whether it's exiting loops
use a debugger to do the same
Your code contains an endless loop before any output:
while (callFunction(someVariable));
Did you mean for the ; to be there (an empty loop), or did you
mean something else? Not that it matters: callFunction
always returns 1, which is converted into true. (If you
really want the loop to be empty, at least put the ; on
a separate line where it can be seen.)
If you do get beyond the while (because you modify some code
somewhere), the if contains an embedded assignment; it's
basically the same as:
if ( (someVariable = 1) != 0 )
Which is, of course, always true. (Most C++ compilers should
warn about the embedded assignment or the fact that the if
always evaluates to true. Or both.)
If your loop completes (it would be sequentially yes, if you fix it), it will print 'a1', since you're doing an assignment in the if, which will always return 1, which evaluates to 'true' for conditionals.
I have the following code in c++:
int fff ( int a , int b )
{
if (a>b )
return 0;
else a+b ;
}
although I didn't write 'return' after else it does not make error ! < br/>
in main() when I wrote:
cout<<fff(1,2);
it printed 1 ?
How did that happened
can any one Explain that ?
This what is called undefined behavior. Anything can happen.
C++ does not require you to always return a value at the end of a function, because it's possible to write code that never gets there:
int fff ( int a , int b )
{
if (a>b )
return 0;
else return a+b;
// still no return at end of function
// syntactically, just as bad as original example
// semantically, nothing bad can happen
}
However, the compiler cannot determine if you never get to the end of the function, and the most it can do is give a warning. It's up to you to avoid falling off the end without a return.
And if you do, you might get a random value, or you might crash.
$6.6.3/2- "Flowing off the end of a
function is equivalent to a return
with no value; this results in
undefined behavior in a
value-returning function."
A compiler may or may not diagnose such a condition.
Here
else a + b;
is treated as an expression without any side effect.
the "random" return vaule is determined by the CPU register value after the call, since the register is 1 after the call, so the value is 1.
If you change you code, the function will return diffrent value.
A good compiler (e.g. gcc) will issue a warning if you make such a mistake, and have a command line switch to return a non-zero error status if any warnings were encountered. This is undefined behaviour: the result you're seeing is whatever value happened to be in the place that the compiler would normally expect a function returning int to use: for example, the accumulator register or some spot on the stack. Your code doesn't copy a+b into that location, so whatever was last put in there will be seen instead. Still, you're not even guaranteed to get a result - some compiler/architecture might do something that can crash the machine if the function didn't have a return statement: for example - pop() a value from the stack on the assumption that return has pushed one - future uses of the stack (including reading function-return addresses) could then get results from the memory address above or below the intended one.
When do we need to use "assert" for pointers in C++, and when they are used, how are they most commonly implemented?
Generally you would use an assert to check a condition that, if false, would indicate a bug in your application. So if a NULL pointer shouldn't ever be encountered at some point in the application, unless there's a bug, then assert it. If it might be encountered due to some invalid input then you need to do proper error handling.
You don't need to use assert on pointers at all. The idea is to ensure you don't crash when dereferencing your pointers when they're null.
You can do this with assert but it's not a very professional way to handle errors like this since it invariably terminates the program - not a good idea if the user hasn't, for example, saved their last three hours worth of data entry.
What you should do with pointers is to check them for null-ness and fail gracefully. In other words, have your function return an error of some sort or do nothing (not everyone will agree with this approach but it's perfectly acceptable if it's documented).
The assert stuff is meant, in my opinion, for catching problems during development which is why you'll find assert does nothing in release builds under some compilers. It is not a substitute for defensive programming.
As to how to do it:
#include <assert.h>
void doSomethingWithPointer (int *p) {
assert (p != 0);
cout << *p << endl;
}
but this would be better done as:
void doSomethingWithPointer (int *p) {
if (p != 0)
cout << *p << endl;
}
In other words, even if your "contract" (API) states that you're not allowed to receive null pointers, you should still handle them gracefully. An old quote: be conservative in what you give, liberal in what you accept (paraphrased).
ASSERT statements are great as "enforced documentation" - that is, they tell the reader something about the code ("This should never happen") and then enforces it by letting you know if they don't hold true.
If it's something that could happen (invalid input, memory not able to be allocated), that's not a time to use ASSERT. Asserts are only for things that can not possibly happen if everyone is obeying pre-conditions and such.
You can do it thusly:
ASSERT(pMyPointer);
From experience if you assert on null conditions that should never happen under normal conditions you program is in a really bad state. Recovering from such null condition will more likely than not mask the original problem.
Unless you code with exception guarantee in mind (linky) I say let it crash, then you know you have a problem.
I would use an ASSERT where a null pointer wouldn't immediately cause a crash but might lead to somethign wrong later that's hard to spot.
eg:
ASSERT(p);
strcpy(p, "hello");
Is a little unnecessary, it simply replaces a fatal exception with a fatal assert!
But in more complex code, particulalrly things like smart pointers, it might be useful to know check if the pointer is what you thing it is.
Remember ASSERTs only run in debug builds, they dissapear in the release.
In C, there also assert function..
in debug mode, if assert(x), x condition is false, there will pop up an alert...
But remember it works only in debug mode...
in release mode, all assert functions are all skipped
Assertions are used to to define how the program should function. That being said, the most common use of Assert()s when dealing with pointers is going to either be that they are valid (non-NULL and point towards valid memory) or that their internal state is valid if they point to an object/class instance, for example.
Assertions are not for replacing or acting as error condition code, but instead to enforce rules that you are placing on the functioning of your code, such as what conditions should be at given points in time.
For example,
function int f(int x, int * pY)
{
// These are entrance conditions expected in the function. It would be
// a BUG if this happened at all.
Assert(x >= 0);
Assert(pY != nullptr);
Assert(*pY >= 0, "*pY should never be less than zero");
// ...Do a bunch of computations with x and pY and return the result as z...
int z = x * 2 / (x + 1) + pow(*pY, x); // Maybe z should be always positive
// after these calculations:
Assert(x >= 0, "X should always be positive after calculations);
// Maybe *pY should always be non-zero after calculations
Assert(*pY != 0, "y should never be zero after computation");
Assert(z > 0):
return z;
}
Many users of Asserts choose to apply Assertions to internal state validation once they become familiar with them. We call these Invariants() which are methods on a class that assert many things about the internals of the object that should always hold true.
For example:
class A
{
public:
A(wchar_t * wszName)
{
_cch = 0;
_wszName = wszName;
}
// Invariant method to be called at times to verify that the
// internal state is consistent. This means here that the
// internal variable tracking the length of the string is
// matching the actual length of the string.
void Invariant()
{
Assert(pwszName != nullptr);
Assert(_cch == wcslen(pwszName));
}
void ProcessABunchOfThings()
{
...
}
protected:
int _cch;
wchar_t * pwszName;
}
// Call to validate internal state of object is consistent/ok
A a(L"Test Object");
a.Invariant();
a.ProcessABunchOfThings();
a.Invariant();
The important thing to remember is that this is to make sure that when bugs do happen that mean the program is not working as you would expect, then the effect of the bug happens as close to where it happened in the code as possible in order to make debugging easier. I have used Asserts extensively in my own code and while at Microsoft and I swear by them since they have saved me so much time in debugging and even knowing the defect is there.