When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.
132 messages ยท Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.
how did you declare GetBoardIndices in the header
const sf::Vector2i GetBoardIndices() { return sf::Vector2i(xIndex, yIndex); }
xIndex and yIndex are private member variables
your function is not declared correctly
what do you mean?
your return type is
const sf::Vector2i
which means the returned object is a constant
but this declaration shows that GetBoardIndices is editing fields accessed through the pointer this
How is it editing it? I don't see it.
if you do not explicitly say that a member function of a class is not editing the fields of the class, by writing const after the function parameters, the function is declared as a non-const member function
if this was the C language, you would have:
Ah okay, with fields you mean member vars?
struct MyThing
{
//etc...
};
int getResult(MyThing* this)
{
//do some edits
//return result;
}
int getResult_const(const MyThing* this)
{
//no edits allowed
//return result;
}
yes, member variables of an object, object fields, it's the same
So you cannot call a non-constant method with a constant instance?
yes, C++ has const correctness, unlike other dumb f*cking laguages
so add the const at the end of the declaration
But what throws me off is that this wouldn't cause a problem if I return a variable by value ๐ฆ
it will again refuse to compile because you will again break const correctness
So when should I use only const before the method dec, vs after, vs both front and after?
if a function you wrote does not edit any fields, and does not call non-const member functions, declare it as a const member function
do it
Yeah, but is weird, since a variable returned by value isn't mutable, which never would cause the const instance's variable to be changed by mistake, if you understand what I mean.

const sf::Vector2i GetBoardIndices() { return sf::Vector2i(xIndex, yIndex); }
```
since C++11 there is a way to declare a member function to be available only for lvalues or rvalues too, but that is another topic for a different time
this doesnt compile when called for const objects
If I call this method and edit the returned value, it won't change xIndex and yIndex which are the member vars.
for non-const objects it's fine
the result you return is an object, completely independent from your this pointer
Yeah, I see that now, but just doesn't make sense imo XD If it returned a reference or ptr to the xIndex or yIndex directly, I would see it.
you are not paying attention
it makes sense
yeah exactly
let me demonstrate
Just to clear this up, this method won't modify the xIndex and yIndex variables, correct? const sf::Vector2i GetBoardIndices() { return sf::Vector2i(xIndex, yIndex); } It only reads and copies from them.
#include <iostream>
#include <thread>
#include <xmmintrin.h>
class Demo
{
int x;
public:
Demo() : x(4)
{
}
int func0()
{
return this->x;
}
const int func1()
{
return this->x;
}
int func2() const
{
return this->x;
}
const int func3() const
{
return this->x;
}
};
int main() {
Demo d1;
const Demo d2;
int result = d1.func0();
result = d1.func1();
result = d1.func2();
result = d1.func3();
//result = d2.func0(); //does not compile
//result = d2.func1(); //does not compile
result = d2.func2();
result = d2.func3();
}
main.cpp:20:18: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
const int func1()
^
main.cpp:32:20: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
const int func3() const
^
main.cpp: In function 'int main()':
main.cpp:44:7: warning: variable 'result' set but not used [-Wunused-but-set-variable]
int result = d1.func0();
^
if the constructor of the class sf::Vector2i is taking them by reference, it will edit them, if it is taking them by const reference, or by value, it won't edit them
it takes them as values. So this will mean that it is IMPOSSIBLE for the function to modify the member values, correct? So I still don't understand why it won't allow it. Or is it simply to make syntax and code more precise and easy to read?
like I said 10 times, put the const at the end to tell the compiler that this function does not edit the fields
Yes, I get that. Const objects can only call const methods. I guess the language is just designed that way then. The reason I was getting confused is because I've just thought const objects couldn't be modified using the "=" operator and since this isn't assigning anything to or writing to the actual const object, it would be fine.
So I still don't understand why it won't allow it.
it won't compile because
int main()
{
int value = 20;
const int* ptr2 = &value;
int* ptr1 = ptr2;
*ptr1 = 40;
}
you can't edit things through a const pointer
@fickle spire
So this will mean that it is IMPOSSIBLE for the function to modify the member values, correct?
C++ does not have the ability to guess what is possible and what is not, it can only read what you declared
and from there decide exactly what is possible and what is not
no matter what you think
in your example, from the variable const Tile& _tile, trying to call the function _tile.GetBoardIndices() means that the type of the this pointer is const Tile*
Ah okay. Makes sense.
Oh right. A reference is just a pointer to the address aswell.
so it tries to find a matching function which has the this pointer declared as const Tile*
but you see, that function does nto exist - only Tile* exists
๐ฅณ
Thank you and let us know if you have any more questions!
one way to hack you way out of const correctness (when some idiot you work with in the office wrote some class and forgot to add const to the functions) is to use const_cast, but that is very complicated, very difficult to get it right, and shows that the code is spaghetti
Haha, will look into it thought.
it is one of the available casts which runs when you do explicit cast, or C-style cast
https://en.cppreference.com/w/cpp/language/explicit_cast
skip these for now, they are cancer
Yeah, heard of it when looking into dynamic and static cast
come back in a few years
it's more efficient to use a specified cast instead of c-style cast since c-style does multiple, right?
well, the dicision is made at compile time for you, not at runtime, both have the same performance
only dynamic_cast is decided at runtime when using virtual functions through a pointer
yeah, so I guess it depends on the compiler (except dynamic cast)
static_cast is your typical arithmetic conversion like from double to int or from char to int
const_cast is a hack
reinterpret_cast is "hey, grab that piece of memory and pretend that something else lives there at those bytes"
ah, so if I do for example: int x = reinterpret_cast<int>("h"); that works. Makes sense that c-style cast also does that then when doing: ```
int x = (int)"h";
both of these are not doing what you expect
the first one takes the char array with size 1 byte and treats that memory address as an int variable, and returns it as a copy in x, you are reading outside the bounds of the array, this is undefined behavior
Yeah, ofcourse xd
and the second one, is taking the address where the char array lives, no one knows where, and treats the address as a number, an int
both are cursed
do not use them
yeah. both "h" are only stored in memory while copying and then removed from the stack. but whatever
no reason to do this obviously
actually both of these treat the address as an int, some random address somewhere
there is no out of bounds reading or anything
Hm. I thought it first allocated the char and then casted it to int
that is a C-string literal, not a char
'h'
this is a char literal
Oh, right. This aint C
it is exactly the same in C too
is it? whats the diff between c-string literal and char?
int main()
{
char text[2] = "h"; // the same as char text[2] = {'h', '\0'};
char letter = 'h';
}
works for C and C++ the same way
oh, I get it. " always adds a null-determinant while ' doesnt.
the first variable text is a char array with 2 elements
the variable letter is a char
yeah. just didn't know it added a null determinant and thus actually returns an array
well, the more you know. learned a lot that I've never had to learn/use before ๐
and if you keep practicing you C++ knowledge with writing code, you will learn more
yeah. been programming for a while now, a lot of graphics/d3d11/d3d12 but never bothered to learn these rare cases. but it's cool that there's always more to learn.
you have been using the drivers for Direct X 11 in C ?
in code?
The d3d11 and 12 api:s, yes. currently learning 12 thought, since it's just a more complex version where you have to manage resources, and gpu/cpu synchronization manually. In d3d11 the drivers does that for you.
aha... okay, so let me warn you, you might assume that C++ is just "C with classes" and transfer your C knowledge in C++, but this is a lethal mistake, in C++ the rules are different, for example, everything related to OOP uses features that never existed in C
like references, like deep copying, like virtual functions
I've actually almost only worked with C++. From our convo, it might seem like I have no idea of things, but I've done a lot of programs etc. I've only not bothered learning the actual meaning of l/r-values and constants and similar small stuff, since I know how to use them to build what I want (except with const in this case).
I've actually almost only worked with C++.
๐ ๐ ๐ ๐ ๐
Here's my first ecs i did. Will optimize it in the future thought, since the constant lookup for the component will add a lot of time.
Why you "๐ " reacting tho.
because you are coding C++ in production, but you didn't know the basics about const 5 minutes ago
what guide do you follow when learning C++?
I just didn't know that you couldn't call non-constant methods from constant object even thought the object doesn't get modified when calling the method.
Uni and random websites.
And what do you mean with "in production"?
your code is executed on the machine of the customers which buy the software produced by the company where you work at
And? That's what learning and improving will remove? I'm capable of writing code, but it won't be perfect since I'm still relatively new compared to other people working. Not knowing one case of how to use constant member functions makes me incapable of writing decent code? If it's a problem it will maybe even be removed or changed during the code review before pushing it to the development branch etc.
the colleagues who are reviewing your code, are they experienced C++ developers?
if yes, listen to them
if no, you are on your own to learn
Get that toxic mentality out of here and please avoid helping if you're just gonna thrash at other people
I'm not currently working with c++
that's not a toxic mentality
C++ is a dangerous language just like C
because pointers
Obviously it can be, depending on what type of software you're developing.
But how you use "๐ " and how you're building your sentences are just plain rude, and that's not even a debate.
And please don't help me next time. Would rather have someone who helps and then are nice.
In the header you sent me I found one bug and one dangerous function which can easily cause bugs
first, line 143
/** @brief A pure virtual function that should be implemented for an inheriting subclass. It should operate on the bound Entity objects, but that isn't mandatory.
*/
virtual void Update() = 0;
};
your class does not have a virtual destructor, which means that using runtime polymorphism, depending on the fields of the derived classes, can cause the wrong destructor to be called, meaning memory leaks
and next, line 390
template<typename T>
inline T* BiDirectionalMap<T>::GetObjectByID(int _id)
{
return &objects[idToIndex.at(_id)];
}
if you use the pointer returned by this function without editing the vector's capacity this->objects, the pointer will be valid, but if someone edits the capacity, trying to read from the pointer will be a read after free bug, likely crash
just like this snippet:
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<std::string> elements = {"test1", "test2", "test3"};
std::string* ptr = &elements[0];
for(int i = 0; i < 20; ++i)
{
elements.push_back(std::string(i,'A'));
}
std::cout<<*ptr<<"\n";
}
I do not have context for your use of this function, consider writing something like
template<typename T>
void BiDirectionalMap<T>::SetObjectByID(int _id, const T& value)
{
objects[idToIndex.at(_id)] = value;
}
template<typename T>
T BiDirectionalMap<T>::GetObjectByID(int _id) const
{
return objects[idToIndex.at(_id)];
}