Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I know that std::variant is easier to use and usually more convenient but which of those is actually faster?
unions are probably faster than std::variant
There's a couple really easy ways to see how this could be. For starters, std::variant is, by design, slightly larger than a union featuring the exact same elements. So any operations that involve copying data, moving data around, etc., are never going to be faster than union outside of very esoteric use conditions.
On top of that, std::variant is type-checked, whereas union is not. So identical code to operate on the element contained in a union is going to be faster than on std::variant.
That having been said, it's possible to screw things up as a programmer. For example, the ideomatic way to do type-checking with unions is to do something like this:
struct my_union {
union {
int i;
double a;
std::string s;
};
size_t index;
//...
};
int main() {
my_union u;
u.i = 15;
u.index = 0;
if(u.index == 0) {
std::cout << u.i;
} else if(u.index == 1) {
std::cout << u.a;
} else if(u.index == 2) {
std::cout << u.s;
}
std::cout << std::endl;
}
Which, at least in terms of size and layout, is not that different to how std::variant is implemented, and may-or-may-not be slower or faster than the std::visit pattern with std::variant, depending on how clever the compiler is.
But as a programmer, your use case might be different, or your constraints might be different, or maybe the code was supposed to be different but later got edited to a different form. Whatever the case, the code used to manually perform type-checking on the union (assuming the programmer even remembers to do that, and doesn't screw up by ignoring it!) may not be so elegant or correct.
So yes, for a lot of reasons, union is probably faster than std::variant. But if you're trying to write safe, maintainable, code, you should prefer std::variant.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Codes bellowing compiles:
namespace x
{
namespace y
{
namespace x
{
struct C
{
C ()
{
std::cout << "x::y::z::C" << std::endl;
}
};
}
}
struct C
{
C ()
{
std::cout << "x::C" << std::endl;
}
};
}
x::C and x::y::x::C are not same, but it's sometimes confusing.
Why is x::y::x allowed in C++? Isn't it more clear to forbid this?
Why is x::y::x allowed in C++? Isn't it more clear to forbid this?
No offense, but I think your premise is seriously flawed.
Maybe you didn't notice but having names being the same on different levels of nesting is something very natural. Consider constructors. The fully qualified name of a constructor of class foo is foo::foo(). Nothing unusual is it?
Now what if I want to put my class inside a namespace called foo. I am not arguing that this is the best naming scheme, but from the top of my head I also see no reason to outright forbid it. The constructor would be foo::foo::foo() then.
Having a rule that would disallow such naming would lead to lots of frustration to anybody that wants to use such (possibly suboptimal, but thats just opinions) naming scheme while having absolutely zero gain for someone that does not want to use such naming. In total there would be no benefit.
It's similar to variables having the same name in different scopes. Technically valid. After all, at the assembly level there are no names, just pointers and sizes.
void foo()
{
int x = 1;
if (true)
{
int x = 2;
x = 3; // Whops
}
}
C++ is not a forgiving language, if you mess up with anything, including variables naming, you are on your own. If you want the language to save you, there are (plenty of) other languages to pick.
That said, MSVC (and probably other compilers) issues a warning when a declared variable hides another variable in an outer scope, so by reading compiler warnings you can be helped.
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.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have many very similar functions like
void someLargeFulction1(args)
{
IDENTICAL CODE
DIFFERENT CODE 1
IDENTICAL CODE
}
//---------------------------//
//---------------------------//
void someLargeFulctionN(args)
{
IDENTICAL CODE
DIFFERENT CODE N
IDENTICAL CODE
}
All these functions differs only in DIFFERENT CODE N part (this is a shot series of floating point operations). Since most of the someLargeFulctionN codes is identical, I wont to avoid code replication because this greatly complicates code maintenance. Reducing reps is my major goal. Unfortunately, I can not organize DIFFERENT CODE as function call and pass this functions as a someLargeFulction argument due to critical performance impact - DIFFERENT CODE performed much faster than a typical function call, excluding the case of call inlining by compiler. I would not like to organize someLargeFulctionN as macro definition (which however is the possible solution).
In the C++ programming language I have very simple and useful solution - template functions. I can do something like:
template <int N>
void someLargeFulction(args)
{
IDENTICAL CODE
differentCode<N>();
IDENTICAL CODE
}
And specialize differentCode() function for all variants. For all tested compilers (g++, MVSC) it works great! The compiler always inlines a differentCode call and I have the necessary number of someLargeFulction variants. The problem is that now I need to port this code to ะก98. For solve the problem directly, I need to create a full number of someLargeFulction copies, this is a bad decision. Using a macro-definition with someLargeFulction implementation acceptable, but not desirable. What other options do you see?
Something like :
#include <stdio.h>
#define doIt(OP,a,b) do##OP(a,b)
#define performTmpl(OP,a,b,c) { for (int i=0; i<10; i++) a[i]=doIt(OP,b[i],c[i]); }
enum { ADD, SUB };
int doADD(int a,int b) { return a+b; }
int doSUB(int a,int b) { return a-b; }
int main() {
printf("%d\n",doIt(ADD,5,4));
printf("%d\n",doIt(SUB,5,4));
int x[10], y[10]={1,2,3,4,5,6,7,8,9,10}, z[10]={1,1,1,1,1,1,1,1,1,1};
performTmpl(ADD,x,y,z);
for (int i=0; i<10; i++) printf("%d\n",x[i]);
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
This may sound strange, but for purposes of obfuscation, I'm wondering if there's a way to create multiple instances of a class throughout my app, but instead of them all reusing the same underlying code, the compiler would create completely separate chunks of code for that class. Sort of an inline for a class.
This would need to work in Xcode and Visual Studio.
The reason for this, and in all fairness, this is an idea that I'm just playing with...I'm looking for another level to slow down a hacker from patching my license code. Typically, no matter how hard you try to prevent code hacking, there ends up being one place where your code returns something like a true/false....Is this license valid? And if a hacker finds that one spot, it's a simple patch. My idea is to try putting the license code, specially the same license class, all throughout my app...many of them...and check any one of them at any time. And if it's done well, the hacker might have to find 10 of them...not knowing that there's really something like 20 of them throughout my app. And all this would depend on writing one class, but it can't be the same piece of reused class code...they'd need to be all separate.
Any ideas?
Here is an attempt/proof of concept. I've drafted a class which has:
some garbage data based on a template argument, so it's harder to reuse data layout.
a method with side effect based on on a template argument, so it's harder to reuse the code
One should be aware that this is all tricky, because compiler is allowed to do any transformation on the code which preserves observable behaviour. Thus, just using a template with a param, would produce two distinct type language wise, but the code generated could be reused for both.
I am not sure whether an experienced hacker would draw any conclusions about the code, or even whether the license check code itself would be duplicated. It's possible. Below code shows that method has two occurences in which one is a loop and the other got unwound, see on godbolt assembly lines 108-113 and 134-142.
That being said, often optimization is a nice obfuscator. Maybe on times even better than hand-mangling.
This a way to start. Generally constexpr and templates are our friends in such cases, because they are processed at compile time, we need to ensure the generate unique things. One could probably try some constexpr hashing, etc.
Code:
#include <string>
#include <iostream>
using std::string;
using std::cout;
template<int N>
struct B {
constexpr B() : arr() {
for (auto i = 0; i != N; ++i)
arr[i] = i;
}
int arr[N];
};
template<int Randomizer = 42>
struct A{
string a{"data_a"}; // probably all member should be templated by Randomizer
B<Randomizer> padding;
string b{"data_b"};
void method() {
cout << a << "\n";
for(int i = 0; i<Randomizer; i++) {
cout << padding.arr[i]; // harmless side effect
}
cout << "\n" << b << "\n";
}
};
int main () {
A<> i1;
A<3> i2;
i1.method();
i2.method();
return 0;
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
Which is faster when assigning a variable via a method, to return a variable, or to point to a variable?
Case 1:
Function Declaration
void foo(int* number)
{
*number = 5;
}
Usage
int main()
{
int number;
function(&number);
cout << "Number: " << number;
}
Case 2:
Function Declaration
int foo()
{
int number = 5;
return number;
}
Usage
int main()
{
int number;
number = function();
cout << "Number: " << number;
}
PS: In case 2, I created a variable and returned it instantly. I know this doesn't make sense, but this is the closest example I can find for the situation I'm dealing with, since I'm initializing an actual object, which requires creating the object first, editing it, then returning it
It depends on the cost of copying the variable. For primitive types, return a value.
For more complex types consider passing in a reference, or take a look at the C++11 move semantics.
One benefit of using output parameters (Case 1) is it gives you the ability to have a function 'return' multiple values:
void foo (int* x, int* y)
{
*x = 5;
*y = 4;
}
But like everyone said in the comments, this doesn't matter in C++ as much as C.
Generally returns are far more readable and make your program's logic well defined and
easy to follow. In C++, stick to returns or references.
Typically, you should choose which to use on your needs rather than on performance.
Do you have multiple outputs? -> Use pointers
Is an input going to be an output -> Might as well use pointers
It's more difficult with these two scenarios to return a variable.
Other than that, performance-wise, it's only nice to use a variable when the variable is super complex, that way, you're only passing in a pointer instead of that super complex object. But any performance gain is negligible other than that.