I have Class which returns std::shared_ptr aka Product_SPTR:
Product_SPTR Mill::Production(sf::Time time)
{
if(m_isProducing)
{
if(elapsedTime.getElapsedTime()>m_manufacturingTime)
{
elapsedTime.restart();
Flour_SPTR a(new Flour(5,1,ProductType::CONSTRUCTION),deleter<Flour>);
return a ;
}
}
}
then i have typedef std::vector<Product_SPTR> VectorProduct_SPTR
and when I'm trying to add new Product_SPTR to vector i have segmentation fault
Here:
products.push_back(a->Production(gameTime.getElapsedTime()));
But when I do something like this:
products.push_back(new Flour(5,1,ProductType::CONSTRUCTION),deleter<Flour>);
problem does not occur....
I have just started to use smart pointers so maybe i don't know how to use it ..
You missed a return statement when the conditions in both ifs evaluate to false. It compiles, probably giving you compiler warnings. You should always work on the highest warning level and eliminate all warnings one by one, unless you understand a warning and its implications.
Additionaly, instead of writing
Flour_SPTR a(new Flour(5, 1, ProductType::CONSTRUCTION),deleter<Flour>);
return a;
You probably should write
return Flour_SPTR(new Flour(5, 1, ProductType::CONSTRUCTION), deleter<Flour>);
Modern compilers shouldn't have any problems with optimizing out the redundant variable, but it's always good to help the compiler do it's job. If you could skip the deleter you could also write:
return std::make_shared<Flour>(5, 1, ProductType::CONSTRUCTION);
Related
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.
I am refactoring some older code that uses NULL in many places. The question is
Is it safe to blindly replace all NULL instances by nullptr?
I am particularly interested in scenario where replacing NULL by nullptr may lead to some run-time errors (compile-time errors would be ok) but I can't think of any. If not, would it be safe to just auto-replace NULL by nullptr (fixing compile time errors if any).
I apologize if question have been asked earlier - I couldn't find it, I will delete it if you point me to the answer!
In practice it should be fairly safe.
But, technically, it is possible that the meaning of your program changes, without causing any compiler errors. Consider the following program:
void foo(int) { std::cout << "int\n"; }
void foo(int*) { std::cout << "int*\n"; }
int main() {
foo(NULL); // prints 'int'
foo(nullptr); // prints 'int*'
return 0;
}
Note that when there's ambiguity between an int and a pointer when passing NULL, the pointer version is what's almost always desired -- which means that most real programs won't have an ambiguity like that in the first place (or will use casts like (int*)NULL to get around it, in which case replacement by nullptr is perfectly fine).
I recently just lost some time figuring out a bug in my code which was caused by a typo:
if (a=b)
instead of:
if (a==b)
I was wondering if there is any particular case you would want to assign a value to a variable in a if statement, or if not, why doesn't the compiler throw a warning or an error?
if (Derived* derived = dynamic_cast<Derived*>(base)) {
// do stuff with `derived`
}
Though this is oft cited as an anti-pattern ("use virtual dispatch!"), sometimes the Derived type has functionality that the Base simply does not (and, consequently, distinct functions), and this is a good way to switch on that semantic difference.
Here is some history on the syntax in question.
In classical C, error handling was frequently done by writing something like:
int error;
...
if(error = foo()) {
printf("An error occurred: %s\nBailing out.\n", strerror(error));
abort();
}
Or, whenever there was a function call that might return a null pointer, the idiom was used the other way round:
Bar* myBar;
... // In old C variables had to be declared at the start of the scope
if(myBar = getBar()) {
// Do something with myBar
}
However, this syntax is dangerously close to
if(myValue == bar()) ...
which is why many people consider the assignment inside a condition bad style, and compilers started to warn about it (at least with -Wall). Some compilers allow avoiding this warning by adding an extra set of parentheses:
if((myBar = getBar())) { // It tells the compiler: Yes, I really want to do that assignment!
However, this is ugly and somewhat of a hack, so it's better avoid writing such code.
Then C99 came around, allowing you to mix definitions and statements, so many developers would frequently write something like
Bar* myBar = getBar();
if(myBar) {
which does feel awkward. This is why the newest standard allows definitions inside conditions, to provide a short, elegant way to do this:
if(Bar* myBar = getBar()) {
There isn't any danger in this statement anymore. You explicitly give the variable a type, obviously wanting it to be initialized. It also avoids the extra line to define the variable, which is nice. But most importantly, the compiler can now easily catch this sort of bug:
if(Bar* myBar = getBar()) {
...
}
foo(myBar->baz); // Compiler error
myBar->foo(); // Compiler error
Without the variable definition inside the if statement, this condition would not be detectable.
To make a long answer short: The syntax in you question is the product of old C's simplicity and power, but it is evil, so compilers can warn about it. Since it is also a very useful way to express a common problem, there is now a very concise, bug robust way to achieve the same behavior. And there are a lot of good, possible uses for it.
The assignment operator returns the value of the assigned value. So, I might use it in a situation like this:
if (x = getMyNumber())
I assign x to be the value returned by getMyNumber and I check if it's not zero.
Avoid doing that. I gave you an example just to help you understand this.
To avoid such bugs up to some extent, one should write the if condition as if(NULL == ptr) instead of if (ptr == NULL). Because when you misspell the equality check operator == as operator =, the compiler will throw an lvalue error with if (NULL = ptr), but if (res = NULL) passed by the compiler (which is not what you mean) and remain a bug in code for runtime.
One should also read Criticism regarding this kind of code.
why doesn't the compiler throw a warning
Some compilers will generate warnings for suspicious assignments in a conditional expression, though you usually have to enable the warning explicitly.
For example, in Visual C++, you have to enable C4706 (or level 4 warnings in general). I generally turn on as many warnings as I can and make the code more explicit in order to avoid false positives. For example, if I really wanted to do this:
if (x = Foo()) { ... }
Then I'd write it as:
if ((x = Foo()) != 0) { ... }
The compiler sees the explicit test and assumes that the assignment was intentional, so you don't get a false positive warning here.
The only drawback with this approach is that you can't use it when the variable is declared in the condition. That is, you cannot rewrite:
if (int x = Foo()) { ... }
as
if ((int x = Foo()) != 0) { ... }
Syntactically, that doesn't work. So you either have to disable the warning, or compromise on how tightly you scope x.
C++17 added the ability to have an init-statement in the condition for an if statement (p0305r1), which solves this problem nicely (for kind of comparison, not just != 0).
if (x = Foo(); x != 0) { ... }
Furthermore, if you want, you can limit the scope of x to just the if statement:
if (int x = Foo(); x != 0) { /* x in scope */ ... }
// x out of scope
In C++17, one can use:
if (<initialize> ; <conditional_expression>) { <body> }
Similar to a for loop iterator initializer.
Here is an example:
if (Employee employee = GetEmployee(); employee.salary > 100) { ... }
It depends on whether you want to write clean code or not. When
C was first being developed, the importance of clean code
wasn't fully recognized, and compilers were very simplistic:
using nested assignment like this could often result in faster
code. Today, I can't think of any case where a good programmer
would do it. It just makes the code less readable and more
difficult to maintain.
Suppose you want to check several conditions in a single if, and if any one of the conditions is true, you'd like to generate an error message. If you want to include in your error message which specific condition caused the error, you could do the following:
std::string e;
if( myMap[e = "ab"].isNotValid() ||
myMap[e = "cd"].isNotValid() ||
myMap[e = "ef"].isNotValid() )
{
// Here, 'e' has the key for which the validation failed
}
So if the second condition is the one that evaluates to true, e will be equal to "cd". This is due to the short-circuit behaviour of || which is mandated by the standard (unless overloaded). See this answer for more details on short-circuiting.
Doing assignment in an if is a fairly common thing, though it's also common that people do it by accident.
The usual pattern is:
if (int x = expensive_function_call())
{
// ...do things with x
}
The anti-pattern is where you're mistakenly assigning to things:
if (x = 1)
{
// Always true
}
else
{
// Never happens
}
You can avoid this to a degree by putting your constants or const values first, so your compiler will throw an error:
if (1 = x)
{
// Compiler error, can't assign to 1
}
= vs. == is something you'll need to develop an eye for. I usually put whitespace around the operator so it's more obvious which operation is being performed, as longname=longername looks a lot like longname==longername at a glance, but = and == on their own are obviously different.
a quite common case.
use
if (0 == exit_value)
instead of
if (exit_value == 0)
this kind of typo will cause compile error
First of all: I know that most optimization bugs are due to programming errors or relying on facts which may change depending on optimization settings (floating point values, multithreading issues, ...).
However I experienced a very hard to find bug and am somewhat unsure if there is any way to prevent these kind of errors from happening without turning the optimization off. Am I missing something? Could this really be an optimizer bug? Here's a simplified example:
struct Data {
int a;
int b;
double c;
};
struct Test {
void optimizeMe();
Data m_data;
};
void Test::optimizeMe() {
Data * pData; // Note that this pointer is not initialized!
bool first = true;
for (int i = 0; i < 3; ++i) {
if (first) {
first = false;
pData = &m_data;
pData->a = i * 10;
pData->b = i * pData->a;
pData->c = pData->b / 2;
} else {
pData->a = ++i;
} // end if
} // end for
};
int main(int argc, char *argv[]) {
Test test;
test.optimizeMe();
return 0;
}
The real program of course has a lot more to do than this. But it all boils down to the fact that instead of accessing m_data directly, a (previously unitialized) pointer is being used. As soon as I add enough statements to the if (first)-part, the optimizer seems to change the code to something along these lines:
if (first) {
first = false;
// pData-assignment has been removed!
m_data.a = i * 10;
m_data.b = i * m_data.a;
m_data.c = m_data.b / m_data.a;
} else {
pData->a = ++i; // This will crash - pData is not set yet.
} // end if
As you can see, it replaces the unnecessary pointer dereference with a direct write to the member struct. However it does not do this in the else-branch. It also removes the pData-assignment. Since the pointer is now still unitialized, the program will crash in the else-branch.
Of course there are various things which could be improved here, so you might blame it on the programmer:
Forget about the pointer and do what the optimizer does - use m_data directly.
Initialize pData to nullptr - that way the optimizer knows that the else-branch will fail if the pointer is never assigned. At least it seems to solve the problem in my test-environment.
Move the pointer assignment in front of the loop (effectively initializing pData with &m_data, which then could also be a reference instead of a pointer (for good measure). This makes sense because pData is needed in all cases so there is no reason to do this inside the loop.
The code is obviously smelly, to say the least, and I'm not trying to "blame" the optimizer for doing this. But I'm asking: What am I doing wrong? The program might be ugly, but it's valid code...
I should add that I'm using VS2012 with C++/CLI and v110_xp-Toolset. Optimization is set to /O2. Please also note that if you really want to reproduce the problem (that's not really the point of this question though) you need to play around with the complexity of the program. This is a very simplified example and the optimizer sometimes doesn't remove the pointer assignment. Hiding &m_data behind a function seems to "help".
EDIT:
Q: How do I know that the compiler is optimizing it to something like the example provided?
A: I'm not very good at reading assembler, I have looked at it however and have made 3 observations which make me believe that it's behaving this way:
As soon as optimization kicks in (adding more assignments usually does the trick) the pointer assignment has no associated assembler statement. It also hasn't been moved up to the declaration, so it's really left uninitialized it seems (at least to me).
In cases where the program crashes, the debugger skips the assignment statement. In cases where the program runs without problems, the debugger stops there.
If I watch the content of pData and the content of m_data while debugging, it clearly shows that all assignments in the if-branch have an effect on m_data and m_data receives the correct values. The pointer itself it still pointing to the same uninitialized value it had from the beginning. Therefore I have to assume that it is in fact not using the pointer to make the assignments at all.
Q: Does it have to do anything with i (Loop unrolling)?
A: No, the actual program actually uses do { ... } while() to loop over a SQL SELECT-resultset so the iteration count is completely runtime-specific and cannot be predetermined by the compiler.
It sure looks like an bug to me. It's fine for the optimizer to eliminate the unnecessary redirection, but it should not eliminate the assignment to pData.
Of course, you can work around the problem by assigning to pData before the loop (at least in this simple example). I gather that the problem in your actual code isn't as easily resolved.
I also vote for an optimizer bug if it is really reproducible in this example. To overrule the optimizer you could try to declare pData as volatile.
Our C++ professor mentioned that using the result of operator-> as input into another operator-> is considered bad style.
So instead of writing:
return edge->terminal->outgoing_edges[0];
He would prefer:
Node* terminal = edge->terminal;
return terminal->outgoing_edges[0];
Why is this considered bad style?
How could I restructure my program to avoid the 'bad style' but also avoid the extra line of code that is created as per the above suggestion?
There's a number of reasons.
The Law of Demeter gives a structural reason (note that your C++ professors code still violates this though!). In your example, edge has to know about terminal and outgoing_edges. That makes it tightly coupled.
As an alternative
class Edge {
private:
Node* terminal;
public:
Edges* outgoing_edges() {
return terminal->outgoing_edges;
}
}
Now you can change the implementation of outgoing_edges in one place without changing everywhere. To be honest, I don't really buy this in the case of a data structure like a graph (it is tightly coupled, edges and nodes can't escape each other). This'd be over-abstraction in my book.
There's the null dereference problem too, in the expression a->b->c, what if b is null?
You should ask your professor as to why he considers it bad style. I don't. I would however consider his omission of the const in the declaration of terminal to be bad style.
For a single snippet like that, it's probably not bad style. However consider this:
void somefunc(Edge *edge)
{
if (edge->terminal->outgoing_edges.size() > 5)
{
edge->terminal->outgoing_edges.rezize(10);
edge->terminal->counter = 5;
}
++edge->terminal->another_value;
}
This is starting to get unwieldy - it is difficult to read, it is difficult to write (I made approximately 10 typos when typing that). And it requires a lot of evaluation of the operator-> on those 2 classes. OK if the operator is trivial, but if the operator does anything exciting, it's going to end up doing a lot of work.
So there's 2 possible answers:
Maintanability
Efficiency
And a single snippet like that, you can't avoid the extra line. In something like the above, it'd have resulted in less typing.
Well, I can't be sure about what your professor did mean, bu I have some thoughts.
First of all, code like this can be "not-so-obvious":
someObjectPointer->foo()->bar()->foobar()
You can't realy say what is the result of foo(), and thus you can't really say on what is the bar() being called. Is that the same object? Or maybe its a temp object that is being created? Or maybe it's something else?
Another thing is if you have to repeat your code. Consider an example like this:
complexObject.somePart.someSubObject.sections[i].doSomething();
complexObject.somePart.someSubObject.sections[i].doSomethingElse();
complexObject.somePart.someSubObject.sections[i].doSomethingAgain();
complexObject.somePart.someSubObject.sections[i].andAgain();
Compare it with such:
section * sectionPtr = complexObject.somePart.someSubObject.sections[i];
sectionPtr->doSomething();
sectionPtr->doSomethingElse();
sectionPtr->doSomethingAgain();
sectionPtr->andAgain();
You can see how the second example is not only shorter, but easier to read.
Sometimes the chain of functions is easier, because you don't need to bother with what they return:
resultClass res = foo()->bar()->foobar()
vs
classA * a = foo();
classB * b = a->bar();
classC * c = b->foobar();
Another thing is debugging. It is very hard to debug long chains of function calls, because you simply can't understand which of them causes the error. In this case, breaking the chain helps a lot, not to mention you can do some extra checks too, like
classA * a = foo();
classB * b;
classC * c;
if(a)
b = a->bar();
if(b)
c = b->foobar();
So, to summarize, you can't say that it is a "bad" or "good" style in general. You have to consider your circumstances first.
The two code snippets you have shown is (of course) semantically identical. When it comes to matters of style, suggest you simply follow what your professor wants.
Slightly better than your second code snippet would be:
Node* terminal = (edge ? edge->terminal : NULL);
return (terminal ? terminal->outgoing_edges[0] : NULL);
I am assuming that outgoing_edges is an array; if not, you have to check for that being NULL or empty as well.
Neither are necessarily better in their current form. However, if you were to add a check for null in your second example, then this would make sense.
if (edge != NULL)
{
Node* terminal = edge->terminal;
if (terminal != NULL) return terminal->outgoing_edges[0];
}
Though even that is still bad because who is to say that outgoing_edges is properly populated or allocated. A better bet would be to call a function called outgoingEdges() that does all that nice error checking for you and never causes you undefined behavior.