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.
Related
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 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
Here is what i got but when i check type it displays "struct MyVarName"
#include <iostream>
#include <typeinfo>
typedef struct { char text[15];} MyVarName;
int g = 0;
int main(void) {
MyVarName a = { "super" };
std::cout << typeid(a).name() << '\n';
std::cout << typeid(g).name() << '\n';
return 0;
}
Is it possible to define your own variable type and then use it as any other variable?
Print, assign new value.. etc.
The result of std::type_info::name() is implementation-defined and could be anything, including a mangled name, the empty string, or a recipe for lasagna.
For example, GCC gives:
9MyVarName
i
Apparently yours is taking a C-like approach and calling it struct MyVarName, which is what you'd have to write to reference the type in C.
Simply don't rely on it for this kind of thing. C++ does not pretend to have meaningful reflection.
Besides that, there is nothing wrong with your code. You did define a new type. There are ways to introduce new types that don't require the creation of a class type (i.e. with struct or class), but these all involve aliasing existing types with typedef or using, and are thus limited. They won't allow you to create a complex type like std::string.
in C:
typedef char newtype[20];
void foo(void)
{
newtype a;
}
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 6 years ago.
Improve this question
There are plenty ways to make an std::string from one char.
std::string(1, ch)
std::string() + ch
std::string(&ch, 1)
std::string {ch} \\ c++11
I wonder which one I should prefer.
Remember that source code communicates to readers, not primarily to the compiler.
Thus you should strive for clarity, and mostly leave the optimizations to the compiler.
Therefore, as the one expression that doesn't involve extraneous issues, and therefore communicates the intent most clearly, std::string{ ch } is preferable.
"A picture speaks a thousand words", as one saying goes.
The c++ equivalent might be "the interface declaration ought to be a picture".
We can create a very lightweight function, which will almost certainly be inlined wherever it's used, adding no overhead and telling the complete story:
namespace notstd {
using std::to_string;
// interface conveys all the information we need.
inline std::string to_string(char c)
{
// implementation is not actually that important
return { c };
}
}
The use case then becomes self-explanatory code:
auto s = notstd::to_string('c');
and it can be used in template-land:
template<class T>
doSomething(T const& v)
{
using notstd::to_string;
auto s = to_string(v); // will also use ADL when necessary
somethingElse(s);
}
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.