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]);
}
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.
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.
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 4 years ago.
Improve this question
I am using the built in complex number class std::complex from the Standard C++ Library header. I applied a code in a HLS tools. The tool can not access a private member variable of that complex class. Is it possible to make it public or what can i do?
Error: /usrf01/prog/mentor/2015-16/RHELx86/QUESTA-SV-AFV_10.4c-5/questasim/gcc-4.7.4-linux_x86_64/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.7.4/../../../../include/c++/4.7.4/complex(222):
error: 'fpml::fixed_point<int, 16u, 15u> std::complex<fpml::fixed_point<int, 16u, 15u> >::_M_real' is private
The std::complex template is somewhat magic: You have explicit permission to reinterpret a complex number as an array of two scalars. More generally, the following is valid:
std::complex<float> a[10];
float* r = reinterpret_cast<float*>(a);
for (int i = 0; i != 20; ++i) std::cout << r[i] << '\n';
That is, you can treat an array of complex numbers like an array of twice as many real numbers. You can use this approach to access the elements of your complex number individually.
Do beware of the following constraint, though ([complex.numbers]p2):
The effect of instantiating the template complex for any type other than float, double, or long double is
unspecified.
Just to be complete, another way to access the members is using the corresponding getters, for example like this
#include <complex>
int main()
{
std::complex<float> c;
c.real(1);
c.imag(2);
return c.real();
}
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 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
Is the use of templates better than basic data types in terms of memory allocation and management?
Just in short:
templates - a way to write code once in a generic way, and in compilation time the compiler will generate code according to the template, if you used the templatic code.
example:
#include <iostream>
template<typename T>
T MultiplyByFive(T _val)
{
return _val * 5;
}
int main()
{
std::cout << MultiplyByFive(5) << " " << MultiplyByFive(5.5) << std::endl;
return 0;
}
In this example, the compiler will generate two MultiplyByFive functions. One for integer and one for double. The output will therefore be:
25 27.5
That's because these functions have been called. Now we have two function in the code (generated by the compiler)
int MultiplyByFive(int _val)
{
return _val * 5;
}
double MultiplyByFive(double _val)
{
return _val * 5;
}
We didn't code them directly, but the compiler did according to our template.
Memory allocation has little to do with template. Dynamic memory allocation is determined in run time (in c++ by the new operator). Static and local variable are determined in compile time, but it has nothing to do with generating code.
If I didn't understand the question, you're more then welcome to clarify.