-
Notifications
You must be signed in to change notification settings - Fork 226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Minor code fixes #377
Minor code fixes #377
Conversation
jarmonik
commented
Jul 24, 2023
- Removed 'register' keyword.
- fixed link warnings.
- Replaced prt() function with '&' macro.
- Set default standard to C++17
…ction with '&' macro, set default to C++17
T* ptr(T&& x) { return &x; } | ||
|
||
|
||
// Required only with c++20 without /permissive flag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not related to C++20. Taking address for a temporary is invalid C++ code. It fails with GCC and Clang even with C++11 standard: https://godbolt.org/z/e1jjobY9G
MSVC simply allowed this code up until C++20. So if you want portability and being able to use other compilers, this should be reverted.
// template<typename T> | ||
// T* ptr(T&& x) { return &x; } | ||
|
||
#define ptr & // use for faster code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not faster. With /O2 flag MSVC produces identical code for both versions:
https://godbolt.org/z/jnqvMq4G3
Except this is a valid C++ code, as long as you use the address within the same expression.
Ok, I change it back. But this is just an other example of language falling apart. Need a hack to solve a very basic issue that's been working fine before. Not my fault. |
@jarmonik I understand how you feel. 😏 The problem is not really the language, but rather Microsoft allowing and promoting non-standard code for many years. People latched on and got used to it. |
Am I the only one that gets VERY scared when one uses this? #define ptr & It was defined as a macro, so its use would be clear (as you "invoke" it like a function call like bool u = false; // some flag with a good name 'u'
bool end = false;; // flag indicating some end-condition
bool foo = uptrend; // store current uptrend value for later use this would give valid code bool u = false; // some flag with a good name 'u'
bool end = false; // flag indicating some end-condition
bool foo = u&end; // !!!! This should never be accepted. By no reason! |
I'll suspend my current work in progress and start restoring that fine function immediately. |
What would be the right way to adress this? void vObject::RenderAxisVector(D3D9Pad *pSkp, const D3DXCOLOR *pColor, /*...*/);
void vObject::RenderAxisLabel(D3D9Pad *pSkp, const D3DXCOLOR *clr, /*...*/); to use const references? void vObject::RenderAxisVector(D3D9Pad *pSkp, const D3DXCOLOR &Color, /*...*/);
void vObject::RenderAxisLabel(D3D9Pad *pSkp, const D3DXCOLOR &clr, /*...*/); Still code like this: FX->SetVector(eColor, ptr(D3DXVECTOR4(0, 0, 0, 0))); needs to be addressed as well :( hmmm |
I have thought about that. But there are a lot of optional parameters and passing a NULL pointer is a common way to indicate (no data available). Which doesn't work with reference. I have googled about that many times. So, using a reference would require more complex solution to a very simple problem. I looked at the ptr() function and didn't quite follow what was it doing exactly. I don't like relaying on a hack solution but I guess there's no other choice. So, I was planning the use the ptr() anyway, a lesser bad. Do you have any info about what's going on with the unions ? I heard that they are obsolete since C++11 |
Yeah, I also think the
As far as I remember the changes will not break any existing code since they only relax current union rules. |
Thanks about the info. Yes, I tried the [-permissive] compile flag and it works on MSVC but GCC won't support it. Since some of us are aiming on multi-platform, we must set coding standards according to the worst compiler on markets. |
There is plenty of union discussion here: #368 |
Regarding @dimitry-ishenko s comment further up, we could introduce some "common-often-used" VECTORS and use them. https://godbolt.org/z/hsarT8588 ...just an idea 😉 |
@jarmonik C++17 introduced std::optional for these situations, so you could do this: #include <iostream>
#include <optional>
struct vector { double x, y, z; };
auto foo(const std::optional<vector>& v)
{
if (v == std::nullopt)
std::cout << "no vector" << std::endl;
else std::cout << v->x << ' ' << v->y << ' ' << v->z << std::endl;
}
int main()
{
foo({ });
foo(vector{5, 6, 7});
return 0;
} Live example: https://godbolt.org/z/3Ma7Yofv8
There are not obsolete per se. It's just that people have been abusing them for years. Many, like you, without even realizing it. 😺 |
Just another idea... struct vector { double x, y, z; };
struct ClassFX { // Some DirectX Class
void MethodFoo(const vector * pV);
void MethodBar(const vector * pV, bool b = true);
void MethodBaz(const vector * pV, float f = 0.0);
};
template <class T>
struct ClassFXwrapper {
T *FX = new T{};
inline void MethodFoo(const vector V) { FX->MethodFoo(&V); }
inline void MethodBar(const vector V, bool b = true) { FX->MethodBar(&V, b); }
inline void MethodBaz(const vector V, float f = 0.0) { FX->MethodBaz(&V, f); }
};
int main()
{
// --- "NEW" code style
auto *FX = new ClassFXwrapper<ClassFX>{};
FX->MethodFoo(vector{});
FX->MethodBar({1.0, 1.0, 1.0}, false);
FX->MethodBaz({0.5, 0.5, 0.5}, 12.34);
// --- "OLD"/"current" code style
// ClassFX *FX = new ClassFX{};
// FX->MethodFoo(&vector{});
// FX->MethodBar(&vector{1.0, 1.0, 1.0}, false);
// FX->MethodBaz(&vector{0.5, 0.5, 0.5}, 12.34);
} |
Maybe a working solution but it looks over complicated due to wrapper class. |
I thought of different solutions, but in the end came up with the |
Fine with me 👍 If the other compilers do like it (when being "pushed to accept it" 😁) |
something like this could work too: But wouldn't make much difference to std::optional<> approach
|
@jarmonik hehe, it doesn't actually... https://godbolt.org/z/Er1Mc17h8 EDIT: Basically, in C++ NaN is never equal to any value, including itself. In other words, So, when you compare See here: https://godbolt.org/z/G9Yjsrjr3 |
Yeah, it looks like it fails to compare them. It works if comparing the bit-fields instead. |
@jarmonik however, we can use your approach if you don't want to use std::optional. But, I would recommend using templates instead of member variables/functions to avoid code duplication. Eg, something like this: |